AI Agents & MCP

How AI Coding Agents Deliver Files to Developers

By SRIFT maintainers · Published

Reviewed by SRIFT maintainers · last reviewed against the SRIFT 4.3.2 source · third-party facts checked 8 October 2026.

Short answer

An AI coding agent that runs in a remote sandbox, container or cloud IDE writes its output to a disk you cannot reach, and its only channel back to you is the chat. Pasting the file as base64 wastes tokens and corrupts easily; committing or uploading it needs credentials and leaves copies behind. The cleanest general answer is for the agent to hand you a download link: either to object storage it is authorised to write, or a link streamed straight from its own process over an outbound HTTPS connection.

A streamed link needs no inbound port and no cloud account, and can be end-to-end encrypted with the key in the URL fragment. Its limit is that it only works while the agent's process is running.

Main obstacle
The file is on a remote disk; the agent can only send you text
Why not base64 in chat
33% larger, costs tokens, one wrong character corrupts it
Network needed for a streamed link
Outbound HTTPS/WSS on port 443 only
Main trade-off
Streamed links need the agent's process alive; stored copies need cleanup

Key takeaways

  • An agent in a sandbox or remote container can only send you text, so the practical answer is a download link.
  • Base64 in chat is a third larger, costs tokens and corrupts easily; cloud uploads need credentials and leave copies to clean up.
  • A link streamed from the agent's own process needs only outbound HTTPS on port 443 and can carry its decryption key in the URL fragment.
  • Streamed links work only while the agent's process runs; use object storage or a CI artifact when the download comes much later.
  • Links are bearer secrets, and an agent with file tools can share any file it can read: keep tool approval on and prefer single-use or short-lived links.

The delivery options compared in general. Setting up SRIFT's MCP server is on MCP file transfer; agents sending files to other agents is covered in agent-to-agent file transfer.

Why getting a file out of an agent is awkward

When an agent runs on your own laptop, delivery is trivial: it writes ./dist/report.pdf and you open it. Most of the interesting setups are not like that. Cloud coding agents run in short-lived VMs or containers; chat assistants execute code in a hosted interpreter; remote development environments sit in a datacenter; CI-driven agents run in a runner that is destroyed when the job ends. In each case the agent can produce a build, a dataset, a log bundle or a generated report, then tell you a path that means nothing on your machine.

These environments also share a network shape: outbound connections allowed, inbound blocked. You cannot scp into a sandbox that has no SSH server and no public address, and the agent cannot push to your laptop for the same reason in reverse. The one channel that always exists is the conversation, which carries text.

Why pasting the file into chat fails

The obvious workaround is to have the agent print the file, base64-encoded if it is binary. Base64 represents every 3 bytes as 4 characters (RFC 4648), so the text is a third larger than the file, and every character passes through the model as output tokens. A few hundred kilobytes already crowds the context window that the agent needs for actual work. Worse, the model reproduces the string token by token: a single dropped or altered character produces a file that fails to decode or silently differs, and long outputs are often truncated. It is acceptable for a short config snippet, and the wrong tool for anything you would call a file.

The options compared

Five approaches cover nearly every setup. They differ mainly in what credentials the agent needs, whether a copy persists somewhere, and whether the agent's environment must stay alive until you download.

Ways to move a file from an AI agent to a developer. Third-party limits checked 2026-10-08.
ApproachHow it worksFitsCosts and risks
Write to the workspace, then sync or commitAgent saves into a synced folder or pushes a branch; you pull.Source code and small text outputs that belong in the repository.Needs repository write access; binaries and datasets bloat history; some sandboxes have no sync back to you.
Paste content in chatAgent prints the file, base64 for binary.A few kilobytes of text.Token cost, context pressure, truncation, silent corruption.
Object storage + presigned URLAgent uploads to a bucket and signs a time-limited GET URL.Files that must outlive the sandbox, or many downloaders over days.Cloud credentials inside the agent environment; the object persists until deleted or a lifecycle rule removes it; AWS caps CLI/SDK presigned URLs at 7 days.
CI artifact storeThe job uploads an artifact; you download from the CI UI or API.Agents that run inside CI anyway.Requires a CI run and repository access; GitHub keeps artifacts 90 days by default.
Streamed link from the agent's environmentA process in the sandbox keeps an outbound connection to a relay and serves the file when the link is opened.Ad hoc delivery from any sandbox with outbound HTTPS, no account.Works only while that process runs; the link is a bearer secret; the relay operator sees metadata.

Object storage is the right call when the file must survive the sandbox or be fetched repeatedly over days: a stored copy is exactly what you want there. The cost is putting long-lived credentials somewhere an agent, and anything that can steer it through prompt injection, can use them, plus remembering to delete the object. The CI artifact store is the same idea with credentials already managed by the platform; the CI/CD artifact sharing guide compares those options in detail.

Two concrete flows: an MCP tool call and a shell command

From an MCP-capable agent

Agents that speak the Model Context Protocol can call a delivery tool instead of composing a shell command. SRIFT's local MCP server (srift mcp, 15 tools) exposes srift_quick_share; the agent passes an absolute path and gets a URL back to show you:

Tool call arguments and result (abridged)
srift_quick_share {
  "filePath": "/workspace/dist/app.zip",
  "encrypt": true,
  "maxDownloads": 1,
  "ttlMs": 3600000
}
-> {
  "downloadUrl": "https://srift.app/d/<token>#k=<key>",
  "fileName": "app.zip",
  "encrypted": true,
  "expiresAt": 1791460800000,
  "maxDownloads": 1
}

Setup differs per client; the guides for sending files from Claude Desktop and Claude Code and for Cursor agents show the configuration. One caveat: the hosted endpoint at https://srift.app/mcp has no filesystem access and offers only the 9 session and control tools, so a chat assistant that can only attach remote MCP servers cannot deliver files through it. Delivery needs the local server running where the file is.

From any agent with a shell

Inside the sandbox
srift quick-share ./dist/app.zip --encrypt --once --ttl 2h --wait
# prints https://srift.app/d/<token>#k=<key> and blocks until downloaded

# no install, e.g. in a throwaway container:
npx -y srift-transfer quick-share ./dist/app.zip --encrypt --wait
On the developer's machine
srift get "https://srift.app/d/<token>#k=<key>"
# or open the link in a browser; unencrypted links also work with
# curl -fLOJ "<url>"  or  wget --content-disposition "<url>"

Quote the URL in shells: # starts a comment in many of them, which would drop the key. If the sandbox blocks something unexpected, srift doctor probes DNS, HTTPS, WebSocket, local ports and process spawning and reports whether links will be served from a background daemon, embedded, or not at all.

The reverse direction: getting a file to the agent

The same constraints apply when you need to give the agent something: a database dump to analyse, a design file, a log from production. You cannot upload into the sandbox, but the sandbox can open a room on a relay and invite you into it.

Agent side (CLI)
srift session start --name "inbox"
# Access Link: https://srift.app/join-session?id=ABC1234
srift session status          # lists pending join requests
srift approve <temp-user-id>  # let the developer in
srift list                    # the developer's file offer appears with its file ID
srift receive <file-id> --save-dir ./incoming

The developer opens the access link in a browser, presses Request to Join, and once approved drags the file in. Over MCP the steps map to srift_start_session (returns the join URL), srift_session_status, srift_approve_join, srift_list_transfers and srift_accept_transfer with a saveDir. Joining always requires the host's approval, so a leaked session code alone does not let a stranger push files. Unlike quick-share, the CLI session commands need the background daemon, so they do not work in sandboxes that forbid detached processes.

Chunks that pass through the relay are sealed with AES-256-GCM under a per-transfer key the two sides agree with ECDH. Those public keys are exchanged through the SRIFT server without a verification step, so this protects against passive observers and an honest server, not against an operator who actively substitutes keys. Between two CLI or agent peers, --room-secret mixes a secret the server never sees into the keys.

Security notes before you let an agent share files

  • Links are bearer secrets. Anyone who has the full URL can download, and with --encrypt the URL also contains the key. Chat transcripts are stored and sometimes shared, so pair links with --once or a short --ttl.
  • Without --encrypt, it is TLS only. The relay handles the real file name and the plaintext bytes in transit. The CLI warns about this; prefer encryption for anything you would not post publicly.
  • Metadata remains. Even for encrypted links the relay sees IP addresses, timing and the ciphertext size.

When a streamed link is the wrong choice

A streamed link depends on the sandbox staying up. If the platform kills the environment the moment the agent replies, and you will not download for an hour, the link will be dead when you click it; that is the case for object storage or a CI artifact. The same goes for files many people will fetch over weeks, for audit requirements that need a retained copy, and for outputs that belong in version control, where a commit is the honest answer. Streamed links are for the common middle case: one person, now, from an environment that can only dial out.

Frequently asked questions

What happens if the sandbox stops before I download the file?

A streamed link stops working because nothing was stored on the relay; SRIFT returns an error instead of the file. Have the agent run the share command with --wait so it blocks until the download completes, or use object storage when the environment cannot be kept alive.

Does the person downloading need SRIFT installed?

No. A browser opens both plain and encrypted links; encrypted ones are decrypted inside the page. For the command line, srift get decrypts encrypted links, and plain links also work with curl or wget.

Can I tell the agent to always deliver files this way?

Yes. Most coding agents read a project instruction file such as CLAUDE.md, AGENTS.md or .cursorrules. A rule like 'deliver files with srift quick-share --encrypt and return the link' is followed in the same way as build instructions. srift bootstrap writes SRIFT's own .cursorrules and AGENTS.md into a directory, but it replaces existing files with those names, so merge by hand in a project that already has them.

References

  1. RFC 4648: The Base16, Base32, and Base64 Data Encodings (IETF)
  2. RFC 3986: Uniform Resource Identifier (URI): Generic Syntax (IETF)
  3. Model Context Protocol specification (Model Context Protocol)
  4. Sharing objects with presigned URLs (Amazon Web Services)
  5. Removing workflow artifacts (GitHub Docs)

Give your agent a file-transfer tool

Local MCP over stdio (15 tools) or hosted at https://srift.app/mcp (9 session tools, no file access).

{ "mcpServers": { "srift": { "command": "npx", "args": ["-y", "srift-transfer", "mcp"] } } }