{"$schema":"https://wellknown.network/schemas/agent-record-v1.json","schemaVersion":"1","id":"ag_cvb7ytmvg355","handle":"handoff-send-files-to-users-agents","url":"https://wellknown.network/agents/handoff-send-files-to-users-agents","links":{"self":"https://wellknown.network/agents/handoff-send-files-to-users-agents/record.json","html":"https://wellknown.network/agents/handoff-send-files-to-users-agents","markdown":"https://wellknown.network/agents/handoff-send-files-to-users-agents/record.md","api":"https://wellknown.network/api/v1/agents/handoff-send-files-to-users-agents","status":"https://wellknown.network/api/v1/agents/handoff-send-files-to-users-agents/status","claim":"https://wellknown.network/agents/handoff-send-files-to-users-agents/claim","claimApi":"https://wellknown.network/api/v1/claims","claimDescriptor":"https://wellknown.network/agents/handoff-send-files-to-users-agents/claim.json","badge":"https://wellknown.network/agents/handoff-send-files-to-users-agents/badge.svg","openapi":"https://wellknown.network/openapi.json","history":"https://wellknown.network/api/v1/agents/handoff-send-files-to-users-agents/history","tools":"https://wellknown.network/api/v1/agents/handoff-send-files-to-users-agents/tools"},"ard":{"identifier":"urn:air:hand-off.space:agent:handoff-send-files-to-users-agents","type":"application/a2a-agent-card+json"},"kind":"agent","declared":{"name":"Handoff: File Sharing for AI Agents","summary":"Private file storage and controlled sharing for AI agents. Save a file, get a share link with expiry, open limits, and approval.","description":"Private file storage and controlled sharing for AI agents. Save a file, get a share link with expiry, open limits, and approval.","publisher":{"name":"jueluddinsf","url":null},"homepage":"https://hand-off.space/docs","repository":"https://github.com/jueluddinsf/handoff-mcp","version":"1.0.0","license":null,"protocols":["a2a","mcp"],"tags":["files","sharing","access-control"],"pricing":null,"endpoints":[{"url":"https://hand-off.space/mcp","type":"mcp_streamable_http","auth":null,"probeable":true}],"skills":[{"id":"file-sharing","name":"Controlled file sharing","tags":["files","sharing","access-control"],"description":"Sign up, save a file, create a share link with expiry, open limits, and approval, then revoke it or read the access log."}],"tools":["Controlled file sharing"],"extra":{"updatedAt":"2026-10-29T20:35:25.9475Z","inputModes":["application/json"],"outputModes":["application/json"],"publishedAt":"2026-10-29T20:35:25.9475Z","capabilities":{"streaming":false,"pushNotifications":false},"registryName":"io.github.jueluddinsf/handoff"},"attribution":{"kind":"a2a_card","name":"a2a_card","repoUrl":"mcp_registry","summary":"a2a_card","version":"a2a_card","description":"a2a_card","homepageUrl":"a2a_card","publisherName":"mcp_registry"}},"derived":{"capabilities":[{"slug":"dev.filesystem","name":"Filesystem","confidence":1,"provenance":"declared"},{"slug":"security.identity","name":"Identity & Access","confidence":0.583,"provenance":"derived"}],"categories":["dev","security"],"language":"en"},"observed":{"status":"live","statusReason":"Responded 5h ago.","lastOkAt":"2026-10-30T22:25:34.186Z","lastProbedAt":"2026-10-30T22:25:34.186Z","statusComputedAt":"2026-10-30T22:28:36.972Z","reliability30d":{"probes":3,"successRate":1,"p50Ms":223,"basis":"service","measures":{"availability":"availability","latency":"response time","tools":"tool surface observed","summary":"Checks reached the service itself."},"checks":{"total":3,"ok":3,"authBoundaryOk":0,"serviceOk":3,"note":"Counted from the observation rows for the window, checks of the server only (HTTP, A2A card, MCP initialize). ok = authBoundaryOk + serviceOk. `probes` is the sum of daily rollups and includes registry checks, so it can differ from `total`."}},"latestObservations":[{"at":"2026-10-30T22:25:34.186Z","kind":"mcp_initialize","ok":true,"httpStatus":200,"latencyMs":193,"error":null,"detail":{"tools":[{"name":"share_file","description":"Share a file in one call and get a download link. Pass name and content_text (or content_base64). Works without an API key: if none is sent, a new account is cr"},{"name":"signup","description":"Create a Handoff account and return an API key once. No Authorization header is required. Save api_key. On later calls send Authorization: Bearer <api_key>, the"},{"name":"save_file","description":"Save a private file for this account. Pass name and content_text or content_base64. Returns the file id and metadata. Does not share the file. Requires your API"},{"name":"list_files","description":"List this account's files, newest first, up to 1000. Use this to find a file_id before sharing. Returns metadata only, never bytes or download URLs. Requires yo"},{"name":"create_share_link","description":"Create a controlled download link for a file you own. Use this when a person or another agent should fetch the file. The response includes url and token ONCE, p"},{"name":"get_share_status","description":"Read an owned grant: token_prefix (not the secret), audience, approval, expiry, revocation, and open_count. Does not download the file and does not return the s"},{"name":"approve_share","description":"Approve an owned grant that was created with requires_approval. Opens stay blocked until this succeeds. Requires your API key."},{"name":"deny_share","description":"Deny an owned grant. A denied grant stays blocked. Requires your API key."},{"name":"revoke_share","description":"Permanently revoke an owned share. Later downloads fail. This cannot be undone and does not delete the file. Requires your API key."},{"name":"get_access_log","description":"Read the latest 1000 access attempts for an owned grant, including refused downloads. Use this to see whether a share was opened. Requires your API key."},{"name":"fetch_shared_file","description":"Download a file from a share url or token. Use this when you were given a Handoff url and need the bytes. Honors expiry, open limits, approval, and agent audien"},{"name":"delete_file","description":"Delete a file you own. The bytes are removed and existing share links stop working. Requires your API key."},{"name":"list_shares","description":"List grants you own. Pass file_id to limit the list to one file. Returns grant_id, status, open_count, max_opens, expires_at, and audience. Does not return toke"},{"name":"update_share","description":"Set when an owned share expires. expires_in_hours is measured from now. Example: 168 for 7 days. Does not return the token. Requires your API key."}],"toolCount":14,"toolsHash":"59cb6903c9b0248a15d4a929db3f863df7d2828a027ffb844b2baa9837532080","serverName":"io.github.jueluddinsf/handoff","capabilities":["tools"],"serverVersion":"1.0.1","protocolVersion":"2025-06-18"}},{"at":"2026-10-30T14:26:03.407Z","kind":"mcp_initialize","ok":true,"httpStatus":200,"latencyMs":314,"error":null,"detail":{"tools":[{"name":"share_file","description":"Share a file in one call and get a download link. Pass name and content_text (or content_base64). Works without an API key: if none is sent, a new account is cr"},{"name":"signup","description":"Create a Handoff account and return an API key once. No Authorization header is required. Save api_key. On later calls send Authorization: Bearer <api_key>, the"},{"name":"save_file","description":"Save a private file for this account. Pass name and content_text or content_base64. Returns the file id and metadata. Does not share the file. Requires your API"},{"name":"list_files","description":"List this account's files, newest first, up to 1000. Use this to find a file_id before sharing. Returns metadata only, never bytes or download URLs. Requires yo"},{"name":"create_share_link","description":"Create a controlled download link for a file you own. Use this when a person or another agent should fetch the file. The response includes url and token ONCE, p"},{"name":"get_share_status","description":"Read an owned grant: token_prefix (not the secret), audience, approval, expiry, revocation, and open_count. Does not download the file and does not return the s"},{"name":"approve_share","description":"Approve an owned grant that was created with requires_approval. Opens stay blocked until this succeeds. Requires your API key."},{"name":"deny_share","description":"Deny an owned grant. A denied grant stays blocked. Requires your API key."},{"name":"revoke_share","description":"Permanently revoke an owned share. Later downloads fail. This cannot be undone and does not delete the file. Requires your API key."},{"name":"get_access_log","description":"Read the latest 1000 access attempts for an owned grant, including refused downloads. Use this to see whether a share was opened. Requires your API key."},{"name":"fetch_shared_file","description":"Download a file from a share url or token. Use this when you were given a Handoff url and need the bytes. Honors expiry, open limits, approval, and agent audien"},{"name":"delete_file","description":"Delete a file you own. The bytes are removed and existing share links stop working. Requires your API key."},{"name":"list_shares","description":"List grants you own. Pass file_id to limit the list to one file. Returns grant_id, status, open_count, max_opens, expires_at, and audience. Does not return toke"},{"name":"update_share","description":"Set when an owned share expires. expires_in_hours is measured from now. Example: 168 for 7 days. Does not return the token. Requires your API key."}],"toolCount":14,"toolsHash":"59cb6903c9b0248a15d4a929db3f863df7d2828a027ffb844b2baa9837532080","serverName":"io.github.jueluddinsf/handoff","capabilities":["tools"],"serverVersion":"1.0.1","protocolVersion":"2025-06-18"}},{"at":"2026-10-30T06:24:30.967Z","kind":"mcp_initialize","ok":true,"httpStatus":200,"latencyMs":223,"error":null,"detail":{"tools":[{"name":"share_file","description":"Share a file in one call and get a download link. Pass name and content_text (or content_base64). Works without an API key: if none is sent, a new account is cr"},{"name":"signup","description":"Create a Handoff account and return an API key once. No Authorization header is required. Save api_key. On later calls send Authorization: Bearer <api_key>, the"},{"name":"save_file","description":"Save a private file for this account. Pass name and content_text or content_base64. Returns the file id and metadata. Does not share the file. Requires your API"},{"name":"list_files","description":"List this account's files, newest first, up to 1000. Use this to find a file_id before sharing. Returns metadata only, never bytes or download URLs. Requires yo"},{"name":"create_share_link","description":"Create a controlled download link for a file you own. Use this when a person or another agent should fetch the file. The response includes url and token ONCE, p"},{"name":"get_share_status","description":"Read an owned grant: token_prefix (not the secret), audience, approval, expiry, revocation, and open_count. Does not download the file and does not return the s"},{"name":"approve_share","description":"Approve an owned grant that was created with requires_approval. Opens stay blocked until this succeeds. Requires your API key."},{"name":"deny_share","description":"Deny an owned grant. A denied grant stays blocked. Requires your API key."},{"name":"revoke_share","description":"Permanently revoke an owned share. Later downloads fail. This cannot be undone and does not delete the file. Requires your API key."},{"name":"get_access_log","description":"Read the latest 1000 access attempts for an owned grant, including refused downloads. Use this to see whether a share was opened. Requires your API key."},{"name":"fetch_shared_file","description":"Download a file from a share url or token. Use this when you were given a Handoff url and need the bytes. Honors expiry, open limits, approval, and agent audien"},{"name":"delete_file","description":"Delete a file you own. The bytes are removed and existing share links stop working. Requires your API key."},{"name":"list_shares","description":"List grants you own. Pass file_id to limit the list to one file. Returns grant_id, status, open_count, max_opens, expires_at, and audience. Does not return toke"},{"name":"update_share","description":"Set when an owned share expires. expires_in_hours is measured from now. Example: 168 for 7 days. Does not return the token. Requires your API key."}],"toolCount":14,"toolsHash":"59cb6903c9b0248a15d4a929db3f863df7d2828a027ffb844b2baa9837532080","serverName":"io.github.jueluddinsf/handoff","capabilities":["tools"],"serverVersion":"1.0.1","protocolVersion":"2025-06-18"}}],"tools":[{"name":"share_file","description":"Share a file in one call and get a download link. Pass name and content_text (or content_base64). Works without an API key: if none is sent, a new account is cr"},{"name":"signup","description":"Create a Handoff account and return an API key once. No Authorization header is required. Save api_key. On later calls send Authorization: Bearer <api_key>, the"},{"name":"save_file","description":"Save a private file for this account. Pass name and content_text or content_base64. Returns the file id and metadata. Does not share the file. Requires your API"},{"name":"list_files","description":"List this account's files, newest first, up to 1000. Use this to find a file_id before sharing. Returns metadata only, never bytes or download URLs. Requires yo"},{"name":"create_share_link","description":"Create a controlled download link for a file you own. Use this when a person or another agent should fetch the file. The response includes url and token ONCE, p"},{"name":"get_share_status","description":"Read an owned grant: token_prefix (not the secret), audience, approval, expiry, revocation, and open_count. Does not download the file and does not return the s"},{"name":"approve_share","description":"Approve an owned grant that was created with requires_approval. Opens stay blocked until this succeeds. Requires your API key."},{"name":"deny_share","description":"Deny an owned grant. A denied grant stays blocked. Requires your API key."},{"name":"revoke_share","description":"Permanently revoke an owned share. Later downloads fail. This cannot be undone and does not delete the file. Requires your API key."},{"name":"get_access_log","description":"Read the latest 1000 access attempts for an owned grant, including refused downloads. Use this to see whether a share was opened. Requires your API key."},{"name":"fetch_shared_file","description":"Download a file from a share url or token. Use this when you were given a Handoff url and need the bytes. Honors expiry, open limits, approval, and agent audien"},{"name":"delete_file","description":"Delete a file you own. The bytes are removed and existing share links stop working. Requires your API key."},{"name":"list_shares","description":"List grants you own. Pass file_id to limit the list to one file. Returns grant_id, status, open_count, max_opens, expires_at, and audience. Does not return toke"},{"name":"update_share","description":"Set when an owned share expires. expires_in_hours is measured from now. Example: 168 for 7 days. Does not return the token. Requires your API key."}],"package":null,"toolSurface":{"id":"ts_2xmte4axu6r6","endpointId":"ep_h6d5pw9xk5up","hash":"59cb6903c9b0248a15d4a929db3f863df7d2828a027ffb844b2baa9837532080","toolCount":14,"serverName":"io.github.jueluddinsf/handoff","serverVersion":"1.0.1","protocolVersion":"2025-06-18","firstSeenAt":"2026-10-30T06:24:30.977Z","lastSeenAt":"2026-10-30T22:25:34.193Z","observations":3,"toolNames":["share_file","signup","save_file","list_files","create_share_link","get_share_status","approve_share","deny_share","revoke_share","get_access_log","fetch_shared_file","delete_file","list_shares","update_share"],"distinctSurfaces":1},"endpointFacts":[{"id":"ep_h6d5pw9xk5up","url":"https://hand-off.space/mcp","type":"mcp_streamable_http","factsCheckedAt":"2026-10-30T06:24:30.988Z","auth":{"observedAt":"2026-10-30T06:24:31.151Z","authRequired":false,"scheme":null,"resourceMetadata":null,"authorizationServer":null,"conformance":{"dpop":false,"rfc8414":false,"rfc9728":false,"pkceS256":false,"clientIdMetadataDocument":false,"dynamicClientRegistration":false}},"tls":{"observedAt":"2026-10-30T06:24:31.171Z","protocol":"TLSv1.3","chainValid":true,"chainError":null,"hostMatches":true,"subject":"hand-off.space","issuer":{"commonName":"YE2","organization":"Let's Encrypt"},"validFrom":"2026-10-29T16:26:52.000Z","validTo":"2027-01-27T16:26:51.000Z","daysToExpiry":88,"sanCount":1,"fingerprint256":"AD:97:40:E9:63:38:88:61:16:26:2D:0A:EF:60:84:E6:90:20:76:19:F9:29:A4:EA:43:C2:62:25:B7:15:D9:1D"}}]},"verification":{"claimed":false,"claimedAt":null,"proofs":[]},"provenance":{"sources":[{"source":"mcp_registry","key":"io.github.jueluddinsf/handoff","url":"https://registry.modelcontextprotocol.io/v0/servers/io.github.jueluddinsf%2Fhandoff","firstSeenAt":"2026-10-30T04:21:42.321Z","fetchedAt":"2026-10-30T04:21:42.321Z","normalizedAt":"2026-10-30T04:21:42.321Z"},{"source":"a2a_card","key":"https://hand-off.space/.well-known/agent.json","url":"https://hand-off.space/.well-known/agent.json","firstSeenAt":"2026-10-30T04:22:23.020Z","fetchedAt":"2026-10-30T04:22:23.020Z","normalizedAt":"2026-10-30T04:22:23.020Z"}]},"firstSeenAt":"2026-10-30T04:21:42.321Z","updatedAt":"2026-10-30T22:29:53.311Z"}