Guide
Tiny configs, no curl — `upload.write`
When the agent already has the bytes in hand, skip the pre-signed dance. `upload.write` PUTs inline content up to 1 MiB directly.
5/18/2026 · connect0 · 3 min
When the agent already holds the bytes, upload.write connects them straight into the core — no pre-signed dance.
upload.create_link is the right tool when the user has the file. But sometimes the agent has it — it just generated a Dockerfile, drafted a package.json, tweaked your .eslintrc. Asking the user to copy the agent's output and PUT it via curl is friction. Use upload.write instead.
When to reach for it
- The agent generated content during the conversation.
- The user pasted text into chat and you want to land it on disk.
- A small templated file (config, scaffolding,
README.md).
For anything > 1 MiB or genuine binary the user has, use upload.create_link — bytes don't tunnel efficiently through the MCP wire.
Plain text
upload.write {
"account_slug": "acme",
"project_slug": "demo",
"target_path": "config/eslint.config.mjs",
"content_text": "export default [{ rules: { 'no-console': 'warn' } }];"
}
Returns:
{ "workspace_path": "/workspace/config/eslint.config.mjs", "bytes_written": 48 }
The file is on disk immediately — sh "cat /workspace/config/eslint.config.mjs" will print what you sent.
Binary
For small images, generated PDFs, anything non-textual the agent has produced, base64-encode it:
upload.write {
"account_slug": "acme",
"project_slug": "demo",
"target_path": "assets/logo.png",
"content_base64": "iVBORw0KGgoAAAANSUhEUgAA...",
"content_type": "image/png"
}
Limits
- 1 MiB total after decoding base64. Exceed it and you get
payload_too_largewith a hint to switch toupload.create_link. - Either text or base64, never both — the tool rejects ambiguous payloads.
- Refuses zero-byte writes — there's never a good reason to create an empty file via this path, and silent zero-byte writes hide bugs.
Path rules
Same as everywhere else in the upload surface:
- Relative, no leading
/. - No
..segments. - No hidden segments (anything starting with
.). - Characters in
[A-Za-z0-9._-/]only, ≤ 256 chars.
Audit trail
Every upload.write call creates an upload_link row with source = 'mcp-write', marked claimed immediately (we already saw the bytes land). You can see them in info's recent_uploads and on the dashboard project page.
Next steps
- Hand your agent a CSV — the pre-signed path for files the user has.
- What
recent_uploads.statusmeans — the audit ledger.
Where this fits
This is the Connect everything pillar of connect0 — the core that connects everything your company runs on. upload.write is the shortest path for landing agent-generated files into the core your agents keep running on. Start building → · All guides →