modelcontextprotocol / modelcontextprotocol/servers

feature: add optional content_base64 to write_file to eliminate JSON escaping failures from LLM agents

Open
#4,394 1 comment 0 reactions 0 assignees View on GitHub

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-rtk write_file tool (Node.js, MCP SDK): implements this exact pattern

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.