fix(mcp): force UTF-8 on stdio to fix -32000 on non-ASCII payloads (Windows)#1060
Merged
Conversation
On Windows, Python defaults sys.stdin/sys.stdout to the system codepage
(e.g. cp1251 on Russian locales, cp1252 on Western European), while MCP
JSON-RPC is always UTF-8. Non-ASCII payloads (Cyrillic, CJK, accented
European) get mis-decoded before reaching handlers, causing json.loads
to fail or tool handlers to receive garbled strings. Both surface to
the client as a generic MCP error -32000.
Reproduction:
1. On Windows with a non-Latin locale, call mempalace_add_drawer or
mempalace_kg_add with Cyrillic/CJK in content or KG object.
2. Server returns: MCP error -32000: Internal tool error.
3. Calling the handler directly from Python works fine -- the bug is
purely in the stdio transport.
Fix:
Reconfigure stdin/stdout to UTF-8 at the start of main(), after
_restore_stdout(). Uses errors="replace" defensively so a lone bad
byte cannot take down the server. Guarded by hasattr(reconfigure)
for exotic stream replacements.
This matches the behaviour of PYTHONUTF8=1 / python -X utf8 without
requiring users to set an env var.
4 tasks
This was referenced May 7, 2026
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On Windows, the MCP server misdecodes non-ASCII JSON-RPC payloads because Python defaults
sys.stdin/sys.stdoutto the system codepage (e.g.cp1251on Russian locales,cp1252on Western European) while MCP is always UTF-8. Any tool call with Cyrillic, CJK, or accented European characters in a string field returns a genericMCP error -32000: Internal tool error.Root cause
main()inmempalace/mcp_server.pyreads requests withsys.stdin.readline()and writes responses withsys.stdout.write(...)without forcing the encoding. On Windows those streams are opened with the system ANSI codepage. UTF-8 bytes for non-ASCII characters are mis-decoded beforejson.loadsruns, so the parse fails (or the handler receives garbled strings).Calling handlers like
tool_add_drawer(content='тест кириллица')directly in Python works fine — the bug is purely in the stdio transport.Fix
Reconfigure
stdin/stdoutto UTF-8 at the start ofmain(), right after_restore_stdout().errors="replace"is defensive so a single bad byte cannot take down the server. Guarded byhasattr(stream, "reconfigure")for exotic stream replacements (embedded interpreters, test harnesses).This gives the same behaviour as running under
PYTHONUTF8=1/python -X utf8without requiring users to set an env var.Repro
content→MCP error -32000.PYTHONUTF8=1set, the MCP call succeeds.Test plan
mempalace_add_drawer/mempalace_kg_addwith Cyrillic content via Claude Code → succeedsreconfigure(encoding="utf-8")is a no-op there🤖 Generated with Claude Code