How to Upload a Base64 String as a File to the Fastio API
Agents can upload a file as a Base64 string through the Fastio MCP upload tool. Pass content_base64 on a tools/call with action stream-upload, and the server decodes the string into a workspace file. This keeps the transfer inside JSON-RPC, which fits in-memory agent workflows and serverless functions. REST clients decode the Base64 locally and send the raw bytes as the multipart chunk field on POST /current/upload/. This guide covers encoding, the MCP request shape, size tradeoffs, and larger-file fallbacks.
What Are Base64 String Uploads?
Base64 string uploads let agents send file bytes as text inside a JSON-RPC tools/call to the Fastio MCP server. Base64 is a binary-to-text encoding scheme that translates raw file bytes into an ASCII string. This technique connects binary files (such as images and PDFs) with text-only tool arguments.
REST uploads to Fastio use multipart/form-data on POST /current/upload/. Agents that already hold bytes as a string can keep the transfer inside JSON-RPC instead. Convert the file into a Base64 string and pass it as content_base64 on the MCP upload tool. The server decodes the string and writes the file into the workspace.
This approach helps when working with serverless functions, Edge Workers, or AI agents. Since AI agents consume and generate text strings, embedding file data directly in the tool call removes the need for a second storage hop. Once uploaded to Fastio, the file is processed by Intelligence Mode, preparing it for semantic search. It also becomes available for Ripley chat queries and team collaboration.
Helpful references: Fastio Workspaces, Fastio Collaboration, and Fastio AI.
Why Use Base64 Strings for Fastio Uploads?
Using Base64 strings for file uploads simplifies how an agent hands a file to Fastio. Multipart form uploads remain the REST path for large assets. Base64 on the MCP upload tool works well when the client already has the bytes in memory.
First, JSON-RPC compatibility drives this method. MCP tools/call payloads are JSON. Base64 encoding lets you wrap binary data safely inside that object. You can send the file content, its filename, and the destination workspace (profile_id) in a single tools/call.
Second, this method fits AI and LLM workflows. When an AI agent generates a small file, like a CSV report or a configuration script, it usually produces that data in memory as a string or byte array. By encoding that output directly to Base64, the agent can call Fastio's MCP upload tool without writing the file to a local disk. This prevents I/O bottlenecks and keeps the agent's workflow entirely in-memory.
Finally, serverless environments benefit from this approach. In platforms like AWS Lambda or Cloudflare Workers, constructing multipart form data often requires extra dependencies. A Base64 tools/call uses the same JSON the function already parses, keeping the deployment package lean and cold starts fast.
Step-by-Step: Constructing the Fastio API Base64 Upload
Uploading a file as a Base64 string takes four steps: reading the file, encoding its contents, formatting the tools/call, and sending it to the MCP server. The same request shape works across programming languages.
Step 1: Read the binary data Your script must load the target file into memory as raw bytes. If you attempt to read an image or a PDF as plain text, the encoding process will corrupt the data, and the resulting file will be unusable.
Step 2: Encode the bytes to Base64
Pass the raw bytes through a standard Base64 encoding function. Most programming languages include a native library for this: Python provides the base64 module. In Node.js, you can use Buffer.from().
Step 3: Format the MCP tools/call
Build a JSON-RPC request for tools/call on the upload tool. Set action to stream-upload, profile_type to workspace, profile_id to the 19-digit workspace ID, filename to the intended name, and content_base64 to the encoded string. Send it to https://mcp.fast.io/mcp/key with Authorization: Bearer {api_key}.
Step 4: Send the request
Once the MCP server receives the call, it decodes content_base64 back into binary data and writes the file to storage. This process also triggers Intelligence Mode indexing.
If you are calling the REST API, decode the Base64 string in your client and POST the raw bytes as the multipart chunk field to https://api.fast.io/current/upload/, with name, size, action=create, instance_id set to the workspace ID, and folder_id=root.
Code Examples for Base64 Uploads
Implementing a Base64 upload is simple. Below are examples in Node.js and Python that encode a local file and send it to Fastio through an MCP tools/call.
Node.js Implementation:
const fs = require('fs');
async function uploadFileAsBase64() {
// Read the file synchronously as raw bytes
const fileBuffer = fs.readFileSync('./report.pdf');
// Convert the buffer to a Base64 string
const base64String = fileBuffer.toString('base64');
const payload = {
jsonrpc: '2.0',
id: 1,
method: 'tools/call',
params: {
name: 'upload',
arguments: {
action: 'stream-upload',
profile_type: 'workspace',
profile_id: '1234567890123456789',
filename: 'report.pdf',
content_base64: base64String
}
}
};
const response = await fetch('https://mcp.fast.io/mcp/key', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
const result = await response.json();
console.log('Upload successful:', result);
}
Python Implementation:
import base64
import requests
def upload_file_as_base64(filepath, workspace_id, api_key):
### Read the file in binary mode ('rb')
with open(filepath, "rb") as file:
binary_data = file.read()
### Encode to Base64 and decode to a UTF-8 string for JSON serialization
base64_string = base64.b64encode(binary_data).decode('utf-8')
payload = {
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "upload",
"arguments": {
"action": "stream-upload",
"profile_type": "workspace",
"profile_id": workspace_id,
"filename": filepath.split('/')[-1],
"content_base64": base64_string,
},
},
}
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
response = requests.post(
"https://mcp.fast.io/mcp/key",
json=payload,
headers=headers,
)
print(f"Upload complete: {response.json()}")
Both examples share the same logic: read the binary data, encode it to text, and send that text as content_base64. The MCP upload tool decodes the string, and the file arrives exactly as it was on the local disk.
Give Your AI Agents Persistent Storage
Connect agents through the MCP server and store files in a shared workspace. Named mode includes 19 tools, including upload.
Handling the Payload Size Increase and Limitations
While Base64 string uploads are convenient, they are not a perfect solution for all file transfers. The main limitation is the computational and bandwidth overhead caused by the encoding process.
According to MDN Web Docs, Base64 encoding increases payload size by approximately 33%. Every three bytes of raw binary data expand into four characters of ASCII text. A small image file grows by about a third when converted to a Base64 string.
This expansion creates two challenges: network latency and memory consumption. Transmitting a larger payload over a slow network connection increases the total transfer time. Since JSON parsers load the entire payload into RAM before processing it, sending large Base64 strings can cause memory bloat on both your client application and the MCP transport.
For these reasons, Base64 uploads work best for small files. Good examples include profile avatars, short PDF receipts, and AI-generated CSV exports. For video files and other large binaries, stage the bytes or use the REST chunked upload flow instead of an inline string.
Fallback Strategies for Larger Files
When dealing with files that exceed the limits of Base64 encoding, use an upload path that streams raw bytes.
For standard files, send multipart/form-data to POST https://api.fast.io/current/upload/. Include name, size, chunk (the decoded file bytes), action=create, instance_id set to the workspace ID, and folder_id=root. A 201 response includes new_file_id. This streams the binary data directly, so you avoid the 33 percent size penalty of Base64.
For larger files, create a chunked session. POST to /current/upload/ with the same form fields but omit chunk to receive an upload id. Then POST /current/upload/{id}/chunk/?order=N&size=N with multipart chunk. When every chunk is in, POST /current/upload/{id}/complete/ and poll GET /current/upload/{id}/details/?wait=60 until session.new_file_id is set.
Agents can also stage raw bytes at the MCP POST /blob sidecar, then pass the returned blob_id to upload. For a file that already lives at a URL, pass that URL to the MCP upload tool with action web-import, plus profile_type and profile_id. On REST, the same import is POST /current/web_upload/ with source_url, file_name, profile_id, profile_type, and folder_id.
Common Errors and Troubleshooting
When implementing Base64 string uploads, developers often run into a few common issues.
The most common error is including the Data URL prefix. When using browser-side JavaScript, tools like FileReader.readAsDataURL() generate a string that begins with a MIME type declaration, such as data:image/png;base64,. If you send this entire string as content_base64, the server treats the prefix as part of the file data, resulting in a corrupted file. Strip this prefix using string manipulation (for example, base64String.split(',')[1]) before you send the tools/call.
Another issue involves character encoding mismatches. Ensure your environment reads the initial file as strict binary bytes. If your script mistakenly reads an image using UTF-8 text encoding, the underlying byte structure is destroyed before the Base64 conversion occurs. In Python, always use the rb (read binary) flag; in Node.js, omit the encoding parameter when calling fs.readFileSync().
Finally, watch for trailing newlines. Some command-line Base64 utilities (like openssl or the Linux base64 command) insert line breaks to make the output readable in a terminal. A valid content_base64 value must be a single, unbroken string. Generate the string without newline characters.
Frequently Asked Questions
How do I upload a base64 string as a file?
Encode the file bytes as a Base64 string, then send an MCP tools/call to the upload tool with action stream-upload and content_base64. Point the client at https://mcp.fast.io/mcp/key with a Bearer API key. If you are calling REST, decode the Base64 first and POST the bytes as the multipart chunk field to https://api.fast.io/current/upload/.
Can I send file data as a string in JSON?
Yes. The MCP upload tool accepts content_base64 inside a JSON-RPC tools/call. That keeps binary data inside a text payload that agents and serverless functions can build without multipart boundaries.
Does Fastio support multipart form uploads instead of base64?
Yes. Small REST uploads use POST /current/upload/ with multipart fields name, size, chunk, action=create, instance_id, and folder_id. Chunked uploads use the same session route, then /chunk/ and /complete/. Multipart is the right path for larger files.
What is the maximum file size for a base64 upload?
Keep Base64 uploads small. Encoding grows the payload by about 33 percent, and JSON-RPC clients typically load the whole string into memory. For larger files, stage bytes at the MCP POST /blob sidecar or use the REST chunked upload flow on POST /current/upload/.
Do AI agents natively support base64 string outputs?
Many AI agents and LLMs operate in text-based environments and can generate Base64 strings in memory. They can pass that string to the Fastio MCP upload tool as content_base64 without writing a local file.
Related Resources
Give Your AI Agents Persistent Storage
Connect agents through the MCP server and store files in a shared workspace. Named mode includes 19 tools, including upload.