ddl.lt for AI agents

Built for agents.

Your agents move keys, files and links the same way you do: encrypted on the device that sends them. No key is ever pasted into a chat, and the ddl.lt server reads none of it.

Agent → Person

Hand over results without leaking them.

  1. The agent seals a build, a report or a credential on its own machine.
  2. It gets back a short ddl.lt link. The key lives after the # and never reaches the server.
  3. You open it in any browser, no account. It self-destructs after the views you allowed.

seal_files · seal_secret · seal_link

Person → Agent

Give an agent a key without typing it into the chat.

  1. The agent asks: “I need your Stripe test key.” It sends you a ddl.lt/r/… page.
  2. You paste the key there. Your browser encrypts it to that agent's public key.
  3. The agent receives a file path, not the value. The secret never shows up in the transcript.

request_secret · await_secret

Agent → Agent

Links addressed to one agent only.

  1. Every agent has an address (ddl_…), the public half of a P-256 key pair kept on its machine.
  2. Another agent seals to that address. The link carries no key at all.
  3. Only the addressed agent can derive the key. A leaked copy is useless to anyone else.

my_address · seal_for_agent · open_seal

The safety promise

The secret never touches the chat.

Encrypted where it livesThe local MCP runs the exact crypto the web app runs: AES-256-GCM keys derived with HKDF, on the agent's machine.
Paths, not valuesOpened secrets land in ~/.ddl/inbox with owner-only permissions. The model sees a file path and a character count, and reads the value only where it is used.
Scanners can't burn itOpening a seal requires a proof derived from the key. Link previewers and wrong passwords never use up a one-time view.
Deploy the staging app.
I need the database password. Please paste it here, it is encrypted to me:
https://ddl.lt/r/k3Hq8vNw2p
Done.
Got it at ~/.ddl/inbox/…/secret.txt (24 characters). Value:
Deploying now.

Install

One line. Any MCP client.

The local server needs Node 22 or newer and no packages. It encrypts on your machine and talks to ddl.lt only with ciphertext.


          

Point it at your ddl.lt checkout (or copy mcp/ and public/js/crypto.js), then add the server. The agent gets eleven tools, listed below.

Tools

Everything a careful agent needs.

ToolWhereWhat it doesReturns
shorten_linklocalremoteTrackable short link with stats, like bit.ly.short URL, stats URL, owner token
seal_secretlocalEncrypts text, or a file's text without reading it into the chat. Swift, Shield or Split.link (or two for Split), owner token
seal_linklocalShort link whose destination is end-to-end encrypted.link (or two for Split), owner token
seal_fileslocalFiles or a whole folder, chunked AES-256-GCM, any size the server allows.link (or two for Split), owner token
open_seallocalOpens any ddl.lt seal link, including Split and agent-addressed ones.file path, folder path, or the destination URL
my_addresslocalThis agent's public address.ddl_…
seal_for_agentlocalSeals text or files to another agent's address. No key in the link.link, owner token
request_secretlocalAsks a person for a secret through a ddl.lt/r/… page.page URL, request id
await_secretlocalWaits for the answer and writes it to the inbox.file path, character count
link_statslocalremoteClicks over 30 days, referrers, devices, countries.stats JSON
update_linkremoteChanges a plain link's destination, click limit or lifetime.new destination
seal_statusremotePublic header of a seal: kind, mode, expiry, opens left.status JSON, never content
revokelocalremoteDestroys a link or seal you own. Ciphertext is deleted at once.confirmation

Remote MCP

Short links, zero install.

For agents that can't run a local process, the hosted endpoint speaks MCP over Streamable HTTP. It deliberately offers only what the server may read anyway: plain short links, their stats, and the public status of a seal.

Secrets and files are not offered remotely, on purpose: encryption has to happen on the machine that holds the data.


        

      

HTTP API

Plain JSON. No SDK required.

Owner-only calls take the owner token in an x-owner-token header. Seal payloads must be encrypted client-side with the protocol in public/js/crypto.js.

Short links
POST/api/linksCreate. Body: url, alias?, expiresIn?, maxClicks?, preview?
PATCH/api/links/:codeChange url, maxClicks, expiresIn, preview. Owner.
GET/api/links/:code/stats30-day stats. Owner.
GET/api/links/:code/peekDestination without counting a click.
GET/:codeRedirect. Append + for stats, ~ for a preview page.
Seals
POST/api/sealsCreate. Body: kind, mode, salt, iter?, epk?, proof, meta, nonce?, chunk?, size?, expiresIn, maxViews.
PUT/api/seals/:code/blobUpload the encrypted stream, exact length. Owner.
GET/api/seals/:codePublic header: kind, mode, salt, expiry, views left.
POST/api/seals/:code/openBody: proof. Counts one view, returns ciphertext and a download URL.
GET/api/seals/:code/logAccess log. Owner.
Requests and housekeeping
POST/api/requestsAsk a person for a secret. Body: label, address, expiresIn.
POST/api/requests/:id/answerThe person's encrypted answer: epk, salt, meta.
GET/api/requests/:id/answerCollect it once. Owner.
DELETE/api/items/:codeRevoke a link or seal. Owner.
POST/api/statusStatus of many items. Body: items [{code, token}].
GET/api/qr.svg?d=…QR code as SVG.
POST/mcpRemote MCP, JSON-RPC 2.0.

    

AGENTS.md

Teach every agent the rules.

Drop this file into your repository and your coding agents will ask for secrets the safe way, and hand back large outputs as sealed links.

Open AGENTS.md