create_or_update_file cannot represent true binary content — no encoding parameter, JSON string requires valid UTF-8

未关闭
#3,312 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
55/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
go
领域
api, backend

调研方向

Start by tracing the create_or_update_file and push_files entry points and their per-file content handling; the issue does not name specific files or tests. Check how JSON parameters are validated and how content is written, then add a documented binary-safe encoding path that decodes base64 once while preserving current UTF-8 behavior, with coverage for the PNG reproduction and both tools.

由索引模型根据 Issue 内容生成。

描述

Describe the bug

create_or_update_file has no way to write a genuine binary file (e.g. a PNG) without corruption, even when the caller follows the tool's own current description exactly.

The content parameter description says:

"Content of the file, exactly as it should appear once written. Do not base64-encode it; this server does that before calling the REST API."

This reads as a fix for #2981 (models pre-encoding out of confusion with the REST API docs). But it doesn't address the deeper problem: content is a JSON string, and JSON strings must be valid UTF-8. Raw binary bytes (arbitrary byte sequences, e.g. PNG magic bytes 89 50 4E 47 ...) are frequently not valid UTF-8, so there is no way to place them into this parameter at all — encoded or not:

  • Pass the raw bytes as-is → most MCP/JSON transports will reject the call outright (invalid UTF-8 in a string field), or the bytes get mangled by whatever text encoding recovery the client/transport applies.
  • Pre-encode as base64 yourself (the "obvious" workaround, and what #2981's own reproduction did) → per the current server behavior, the base64 text is stored literally as the file's bytes. The tool reports success; the resulting file is corrupt (its content is the ASCII base64 string, not the decoded image).
Minimal reproduction

Created a 77-byte, 10×10 solid-color PNG, base64-encoded it (104 chars), and called create_or_update_file with that base64 string as content:

content: "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAAFElEQVR4nGP8n2XJgBsw4ZEbwdIABR4Btgm0KTcAAAAASUVORK5CYII="

Result: commit succeeds, content.size in the response is 104 (the length of the base64 text), not 77 (the actual PNG size). Fetching the file back with get_file_contents returns the literal base64 string as the file's text content — not a decodable/valid PNG.

There is no parameter on this tool to say "this content is base64" or otherwise indicate a binary-safe encoding, unlike what a content_base64 / encoding field would provide. Every path leads to a corrupted binary file for any client that can only pass JSON string parameters (which is all MCP clients).

Impact

Any MCP client — including AI agents — that needs to commit a binary asset (image, font, icon, PDF, zip, etc.) via create_or_update_file (or the equivalent multi-file push_files, which has the identical content: string shape per-file) cannot do so reliably. The only safe workaround currently is bypassing this tool entirely (e.g. driving the GitHub web upload UI in a browser, or using a real git client locally), which defeats the purpose of having this tool.

Suggested fix

Add an explicit binary-safe path, e.g.:

  • An optional encoding (or content_encoding) parameter on create_or_update_file and each file entry in push_files, with values like "utf-8" (default, current behavior) and "base64" — when "base64", the server decodes the given base64 string once and writes the resulting raw bytes, instead of writing the base64 text (or double-encoding it).
  • Document clearly in the parameter description which mode is used, since this is exactly the ambiguity #2981 tried (and, per this report, failed) to close.
Related
  • #2981 — addressed the ambiguity around double-encoding of text-ish content, but this report shows the description fix alone does not make binary uploads possible; there is still no valid way to submit non-UTF-8 bytes.
  • #3097 — the mirror-image bug on the read path (get_file_contents double-base64-encoding binaries), already fixed.
  • #372 — requested a non-base64 read option; this report is the write-side binary-safe request.
Environment

Reproduced via the hosted GitHub MCP Server connector, 2026-09-19, through an Anthropic Claude MCP connector session. Not version-specific — the tool's content parameter has always been a plain JSON string with no encoding flag.

主要语言
Go
星标
33.1k
派生
5k
平均合并
2 天 15 小时
30 天内合并 PR
27

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

github/github-mcp-server 的其他 Issue

查看 github/github-mcp-server 的全部 Issue

相似的 Issue

更多 Go Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。