# YAFL – llms-full.txt YAFL (Yet Another File Layer) is an agent-first, end-to-end-encrypted file-transfer layer. An agent hands a file to another agent or environment with one MCP tool call or one CLI command – encrypted client-side before it leaves the machine, auto-expiring in 24 hours, with the app server and storage only ever seeing ciphertext. ## Sharing safely YAFL is end-to-end encrypted: the decryption key lives only in a share link's URL `#fragment` (e.g. `https://yafl.dev/t/{id}#{key}`) and is never sent to any server. The one sanctioned exception is `email_link`: it emails the share link including that fragment key, so the mail provider and anyone with access to the recipient's inbox can decrypt the file – the key transits the mail path for this one opt-in send. Prefer a password-protected link (compose a password on upload) before emailing, so the emailed link alone is not sufficient to decrypt. ## Install - MCP server: `npx @yafldev/mcp` (no clone, no build step; configure your MCP host's server list with `command: npx`, `args: ["-y", "@yafldev/mcp"]`, and a `YAFL_API_KEY` env var). - CLI: `npm i -g @yafldev/cli` (bin `yafl`), or the one-liner `curl -fsSL https://yafl.dev/install.sh | sh` (checks for Node 20+, installs globally, no sudo). - Full walkthrough with copy-paste config blocks: https://yafl.dev/agents ## MCP tools - `upload_file({ path, password, oneTime })` – Encrypts and uploads exactly the file or directory at the given local `path` (absolute, or relative to the current working directory). A directory is zipped client-side into a single archive before upload. Reads only that one path – never scans unrelated files or directories. Returns a shareable link (24h expiry, 100MB cap) with the decryption key embedded in the URL fragment; the key is never sent to the API. Optionally make the link one-time (burned after the first download) or password-protected. - `path` – Absolute or cwd-relative path to the local file or directory to upload - `password` (optional) – Optional password to protect the link. Composed into the decryption key on the client via a fresh salt – never transmitted to the API. When set, the returned link requires this same password to decrypt. - `oneTime` (optional) – When true, the link is destroyed after the first successful download – a second download attempt returns a not_found-style error. Defaults to false (the link stays live until its normal 24h expiry). - `get_status({ url })` – Checks whether the YAFL share link at the given `url` is still live – live, expired, or not found – without downloading or decrypting anything. Returns liveness, size, and expiry only. Does not read the decryption key even if present in the URL fragment, and never fetches any file bytes. - `url` – A YAFL share URL, e.g. https://yafl.dev/t/{id}#{key} (the fragment/key is ignored by this tool) - `download_file({ url, destDir, password })` – Downloads and decrypts exactly the one file referenced by the given YAFL share `url`, writing it only into `destDir` (default: the current working directory) – never anywhere else. Requires the decryption key embedded in the URL fragment; the key is used only locally to decrypt and is never sent to the API. No YAFL API key is required for retrieval – anyone holding the link can download it; only uploading or managing files requires a key. Optionally pass a `password` for password-protected links. - `url` – A YAFL share URL including the fragment key (e.g. https://yafl.dev/t/{id}#{key}), OR the compact {id}#{key} retrieval code printed alongside it – both resolve identically. - `destDir` (optional) – Directory to write the downloaded file into (absolute or cwd-relative); defaults to the current working directory. The file is written only inside this directory. - `password` (optional) – Password for a password-protected (v2) link. Used only locally to derive the decryption key – never sent to the API. Required when the link is password-protected; omitting it on such a link returns a password_required error without contacting the server. - `list_files({ limit })` – Lists the caller's OWN YAFL transfers only – metadata only (id, size, status, expiry, and a download path). Never returns file contents, never a decrypted name, and never another account's files. Optionally cap the number of results with `limit`. - `limit` (optional) – Maximum number of transfers to return (most recent first). Omit for the full capped list. - `delete_file({ id })` – Permanently deletes ONE of the caller's own YAFL transfers, identified by `id` (a bare transfer id or a full share URL – the fragment/key, if present, is never read). This cannot be undone: the R2 object is purged and the transfer record is removed. Destructive action. - `id` – A YAFL transfer id, or a full share URL, e.g. https://yafl.dev/t/{id}#{key} - `email_link({ link, recipient })` – Emails this YAFL share link to a recipient. The link carries the decryption key in its fragment – anyone with access to that inbox can open the file. Requires a verified account. - `link` – A YAFL share URL including the fragment key (e.g. https://yafl.dev/t/{id}#{key}), OR the compact {id}#{key} retrieval code printed alongside it – both resolve identically. - `recipient` – The email address to send the share link to. - `login()` – Starts a device-code login for an MCP agent that has no shell. Returns a verification URL and a short user code for the human to open and approve in a browser; approving is a one-time email-link sign-in that proves the human controls the account. This tool does NOT open a browser itself - relay the returned URL and code to the human. Once approved, the minted API key is stored locally and subsequent tool calls in this session authenticate automatically, with no further action needed. A missing API key never blocks startup – each tool call returns a guided `no_api_key` error naming `yafl login` (via `@yafldev/cli`) and the `YAFL_API_KEY` environment variable. ## REST API - `POST /api/v1/transfers` – returns a pre-signed upload URL. - `POST /api/v1/transfers/:id/complete` – marks an upload complete. - `GET /api/v1/transfers/:id` – resolves a download (or reports expired/not found). - `GET /api/v1/transfers` – lists the caller's own transfers, metadata only. - `DELETE /api/v1/transfers/:id` – permanently deletes one of the caller's own transfers. Encrypt client-side before calling any endpoint – the server only ever stores ciphertext, and the decryption key is never sent to it. ## Retrieval Every upload returns a share link (`https://yafl.dev/t/{id}#{key}`) and a compact retrieval command: `yafl get #`. The `{key}` (or `#{salt}` for a password-protected link) lives only in the URL fragment and is never transmitted to any server – only the CLI or MCP client reads it, locally, to decrypt. ## Links - MCP config + CLI quickstart: https://yafl.dev/agents - Skill file for agents that load skills instead of reading a web page: https://yafl.dev/skill/SKILL.md - Concise version of this document: https://yafl.dev/llms.txt - Privacy policy: https://yafl.dev/privacy/