modelcontextprotocol / modelcontextprotocol/servers
feature: add optional content_base64 to write_file to eliminate JSON escaping failures from LLM agents
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 90.5k
- Forks
- 11.7k
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 5
Description
Summary
Add an optional content_base64 parameter to write_file so LLM agents can bypass JSON string escaping failures when content contains quotes, backticks, or special characters.
Problem
write_file accepts content as z.string(). When an LLM generates the tool call JSON, content with ", `, or ${} often results in malformed JSON → parse error → retry loop.
Token Cost (10KB doc)
| Retries | Calls | Tokens | vs base64 |
|---|---|---|---|
| 0 | 1 | 3,770 | +52% |
| 1 | 2 | 7,590 | -24% |
| 2 | 3 | 11,410 | -50% |
| 4 | 5 | 19,050 | -70% (3.3×) |
Breakeven is sub-1 retry. Content with quotes/backticks almost always triggers the problem.
Full analysis: https://github.com/Ev3lynx727/server-commands-rtk/blob/develop/docs/references/000_user_experiences.md
Proposed Fix
WriteFileArgsSchema = z.object({
path: z.string(),
content: z.string().optional(),
content_base64: z.string().optional(),
}).refine(
args => args.content !== undefined || args.content_base64 !== undefined,
"Must provide either content or content_base64"
);
When content_base64 is provided, decode server-side:
const content = args.content_base64
? Buffer.from(args.content_base64, 'base64').toString('utf-8')
: args.content;
await writeFileContent(validPath, content);
Base64 charset (A-Za-z0-9+/=) is fully JSON-safe. The server already uses base64 for read_media_file (readFileAsBase64Stream), so zero new dependencies.
Bonus: Binary writes
content: string makes binary writes impossible. content_base64 enables them:
const buffer = Buffer.from(args.content_base64, 'base64');
await fs.writeFile(validPath, buffer);
Scope
| Tool | Current | Proposed |
|---|---|---|
write_file |
content: string |
Add content_base64?: string |
edit_file |
newText: string |
Add newText_base64?: string |
Prior art
server-commands-rtkwrite_filetool (Node.js, MCP SDK): implements this exact pattern
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the TypeScript schemas and handlers for the write_file and edit_file tool entry points; compare their content handling with read_media_file and readFileAsBase64Stream. Done means optional base64 inputs are validated, decoded server-side, and preserve existing text behavior, with coverage for JSON-safe content and the proposed binary-write path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100