File Input in MCP Tools
Learn how to pass files to MCP tools in ajan. When an MCP tool declares a file input field, ajan resolves file references into structured FileData objects automatically.
When an MCP tool declares an input field with format: "file", ajan automatically intercepts the LLM's file reference and resolves it into a structured FileData object before the MCP server ever receives the call.
How It Works
When a user attaches a file in chat and the LLM references it (as a filename like report.pdf, a storage path like attachment//, or /mnt/data/), ajan's engine intercepts that reference and resolves it into a full FileData object before passing it to your MCP tool.
The FileData Shape
Your MCP tool receives the following object:
{
fileName: string; // original filename, e.g. "report.pdf"
mimeType: string; // e.g. "image/jpeg", "application/pdf"
base64: string; // full file content, base64-encoded
size: number; // byte length
lastModified: Date;
}The .meta({ format: "file" }) Marker
The key signal to ajan is adding .meta({ format: "file" }) to your Zod schema field. When you save the MCP integration, ajan detects format: "file" in the JSON schema and stores the field as a FILE type. At execution time, ajan resolves the file reference into a full FileData object and passes it to your MCP server.
Implementing File Input in Your MCP Server
Declare the input field as a Zod object matching the FileData shape. Do not use z.string() — the MCP SDK validates inputs before calling the handler, so the schema must match what it actually receives:
server.registerTool(
"process-file",
{
inputSchema: {
file: z
.object({
fileName: z.string(),
mimeType: z.string(),
base64: z.string(),
size: z.number().optional(),
})
.describe("File to process")
.meta({ format: "file" }), // tells ajan to resolve the reference
},
},
async ({ file }) => {
const buffer = Buffer.from(file.base64, "base64");
// use buffer, file.fileName, file.mimeType, etc.
return {
content: [{ type: "text", text: `Processed: ${file.fileName} (${file.size} bytes)` }],
};
},
);Example Tool Input and Output
When ajan calls your tool, it sends a fully resolved FileData object:
{
"file": {
"fileName": "example.txt",
"mimeType": "text/plain",
"base64": "SGVsbG8gd29ybGQ=",
"size": 11
}
}Your tool can then return metadata or processed results:
{
"success": true,
"filename": "example.txt",
"mimeType": "text/plain",
"sizeBytes": 11
}Example Project
The ajan\_mcp\_file\_upload repository is a minimal working MCP server that demonstrates the full file input flow — from schema declaration to handling the resolved FileData in the tool handler.
Related Documentation
- ajan Cookbook - Runnable MCP recipes, including file uploads
- MCP File Outputs - Return files from MCP servers to ajan
- Model Context Protocol (MCP) - Overview of MCP in ajan
- ajan Agent MCP Server - Expose your ajan agents as MCP tools
FAQ
Use file input when the external MCP tool needs to inspect or process a file that the user references in ajan. This is useful for tools that parse, transform, validate, or upload files to another system.
Check that the MCP tool declares a file input field, the user referenced an available file, the file type is supported by the tool, and the tool handles the file data format ajan sends.