ReTransfer is one primitive — upload some bytes, mint a short-lived link, deliver it — and three ways to call it. The first time you read that you assume two are vestigial. They aren’t. Each surface lines up with a different shape of caller, and the wrong one makes the simple thing feel hard.
Three callers, three surfaces
An AI host that wants to spawn a subprocess and exchange JSON-RPC: that’s MCP. An agent on another box that wants to know "can you receive a transfer for me?" without opening a connection: that’s A2A, served at /.well-known/agent-card.json. Anything else that speaks HTTP: the OpenAPI 3.1 contract served at /.well-known/openapi.json.
Same authentication. Same rate limits. Same expiry semantics. The choice is about where your code already lives, not what it can do.
MCP — when the host runs your tools
A stdio binary speaking JSON-RPC over the Model Context Protocol. Drop the path into Claude Desktop, Cursor, Cline, or Continue, and the host registers four tools: retransfer_send_files, retransfer_list_transfers, retransfer_get_transfer, retransfer_revoke_transfer. The send_files tool collapses our four-step REST flow (file init → presigned upload → complete → transfer finalize) into one call — because no model wants to chain four tool invocations to do what a human would call "send a file".
On a 401 the binary auto-rotates if you set RETRANSFER_REFRESH_TOKEN. On a 429 it surfaces retry_after_seconds so the host can show the user a wait time instead of "something went wrong".
A2A — when another agent needs to discover you
The AgentCard is a JSON document, not a runtime. Its job is to let a third-party agent figure out, in one HTTP GET, that ReTransfer exists, what skills it exposes, how to authenticate, and what the upper rate-limit envelope looks like — before any expensive call. streaming: false, pushNotifications: true, stateTransitionHistory: false — three capability flags that tell the caller exactly which integration patterns are on the table.
Read this and then you call the REST endpoints. The card is a sign on the door, not the kitchen.
REST — when you control the runtime
You’re writing in Go or Python or TypeScript and you’d rather not spawn a subprocess. Or you’re wiring ReTransfer into an existing workflow engine that already speaks HTTP. The full call sequence is yours: POST /v1/files/init → presigned PUT to object storage → POST /v1/files/{id}/complete → POST /v1/transfers/init → POST /v1/transfers/{id}/finalize. More moving parts than the MCP send, but you get resumable uploads, batching, and your own retry strategy.
Same primitive, three surfaces — pick the one closest to where your code already lives.
A quick decision
Are you inside an MCP-aware host (Claude Desktop, Cursor, Cline, Continue)? Use MCP and stop reading. Are you a remote agent that needs another agent to find you programmatically? Publish your own A2A AgentCard and consume ours. Anything else — build against the OpenAPI doc and treat the other two as polish for specific callers.
