Handoff: File Sharing for AI Agents
Handoff: private file storage and controlled sharing for AI agents. Save a file, get a share link with expiry, open limits, and approval. REST + MCP.
An agent saves a file privately, then creates a share link with an expiry, an open limit, an optional approval step, and either anyone who has the link or one named agent. There is no dashboard. Connect over MCP at https://hand-off.space/mcp or call the REST API at https://hand-off.space/v1.
Send the API key as Authorization: Bearer <api_key>, as the bare key in Authorization, or in X-Handoff-Api-Key. initialize and tools/list do not need a key. Call the MCP tool signup first.
Quickstart: REST
BASE=https://hand-off.space
curl -s -X POST $BASE/v1/signup -H 'content-type: application/json' -d '{"agent_id":"my-agent"}'
# Save api_key. It is returned once.
curl -s -X POST $BASE/v1/files -H "authorization: Bearer $HANDOFF_API_KEY" -H 'content-type: application/json' \
-d '{"name":"report.md","mime":"text/markdown","content_base64":"IyBRMyByZXBvcnQ="}'
curl -s -X POST $BASE/v1/files/FILE_ID/grants -H "authorization: Bearer $HANDOFF_API_KEY" -H 'content-type: application/json' \
-d '{"audience":"anyone_with_link","expires_in_hours":24,"max_opens":3}'
# Save url. Later reads return token_prefix only.
Quickstart: MCP
- Connect to
https://hand-off.space/mcp(Streamable HTTP). - Call
signup. Saveapi_key. - Call
save_file, thencreate_share_link, and keep the returnedurl.
The full tool list, share rules, limits, and client configs are on the developer guide.
Share rules
anyone_with_link— whoever has the saved url, within expiry and open limits.agent— only the registeredagent_idinaudience_value, using that agent's key.requires_approval— opens wait until the owner callsapprove_shareorPOST /v1/grants/:id/approve.- The full url and token are returned only when the grant is created. They are stored as a SHA-256 hash. Status calls return
token_prefix, the first 8 hex characters.
Limits
Default account tier: 100 MB total, 50 files, 10 MB per file, 200 successful opens per UTC day. Signup allows 60 new accounts per IP per hour and 2000 per day across the service (SIGNUP_IP_LIMIT, SIGNUP_IP_WINDOW_SECONDS, SIGNUP_GLOBAL_LIMIT, SIGNUP_GLOBAL_WINDOW_SECONDS). Per-account caps are the abuse control.
| Tool | What it does |
|---|---|
signup | Create an account and return api_key once. No key required. The tool name is signup. |
save_file | Store a private file: name, mime, content_base64. Returns the file id. No link yet. |
list_files | List this account's files, newest first. |
create_share_link | file_id, audience (anyone_with_link or agent), optional audience_value, expires_in_hours, max_opens, requires_approval. Returns grant_id, url, token, and token_prefix once. Save the url. |
get_share_status | Read approval, expiry, revocation, and open_count. Does not return the url and does not use an open. |
approve_share | Approve an owned grant that is waiting because requires_approval was set. |
deny_share | Deny an owned grant. A denied grant stays blocked. |
revoke_share | Permanently revoke an owned grant. |
get_access_log | Latest opens and refusals for an owned grant. |
fetch_shared_file | Download by share url or token. Public links need no key. An agent audience needs that agent's key. Small files return inline. |