Preflight Checklist
What's Wrong?
Summary
When a Cowork session running in the cloud calls an MCP server running on the
user's machine (proxied through the connected desktop app), string arguments are
double-encoded — UTF-8 bytes arrive decoded as Latin-1.
The same MCP server, called from a local Claude instance, handles the same
strings correctly. Other tools on the same remote bridge (device_bash,
device_list_dir) round-trip UTF-8 perfectly. So this is not the bridge, not the
MCP server, and not the OS locale.
Two distinct failure modes:
- CJK (kana/kanji) — hard error. The mangled string contains surrogates and
the server's tokenizer rejects it.
- Latin-1-representable characters (em-dash, en-dash, curly quotes, accented
letters) — no error. Silently stored/queried wrong.
The silent case is the more damaging one: it has been quietly corrupting written
content for months without any indication.
Environment
- Windows 11
- Claude Desktop (MSIX packaged:
Claude_pzs8sxrjxfjjc)
- Cowork session running in the cloud, connected to the desktop via remote devices
- Proxied local MCP server: MemPalace (Python 3.14, stdio transport)
Reproduction
With a local stdio MCP server proxied to a cloud Cowork session:
1. Send a Latin-1-representable character in a string argument
Call any proxied MCP tool with café naïve résumé.
The server echoes the received query back as:
Classic UTF-8-read-as-Latin-1. No error raised.
2. Send CJK in a string argument
Call the same tool with a kana query. Result:
Search error: TextInputSequence must be str in query.
The write path fails identically:
mempalace_add_drawer(content containing kana)
→ TextInputSequence must be str in add.
3. Control — same bridge, non-MCP tool
device_bash: echo "kana: <kana> kanji: <kanji> café before — after"
Returns everything intact. Hex of the em-dash confirms correct UTF-8:
before — after
6265 666f 7265 20e2 8094 2061 6674 6572
^^^^^^^^^ e2 80 94 = U+2014
4. Control — same MCP server, local instance
A local Claude instance calling the same MemPalace server returns kanji intact,
5 results, no error.
5. Control — no MCP at all
python -m mempalace search "<kana>"
Works perfectly. Five correctly-ranked results.
What this rules out
| path |
result |
| local instance → MCP server |
works |
cloud → bridge → device_bash |
works |
| cloud → bridge → MCP proxy → server |
broken |
| CLI on the machine, no MCP |
works |
Only the path containing the MCP proxy fails. The bridge carries UTF-8 fine.
The MCP server handles UTF-8 fine. The OS and Python handle UTF-8 fine.
Things tried that did NOT help
Both target Python's stdin decoding, on the theory that this was a
locale/stdin issue on the server side:
- Windows user environment variables
PYTHONUTF8=1 and
PYTHONIOENCODING=utf-8, with full app restart and a full sign-out. No
effect on MCP calls. (They do apply to a fresh PowerShell, which is part of
why the CLI test succeeded.)
- Adding
"-X", "utf8" to the server's args and an env block with the same
two variables in claude_desktop_config.json. No effect.
That neither helped is further evidence the corruption happens upstream of the
server process.
Impact
- Any locally-proxied MCP server is affected, not just this one. MemPalace is
simply the only one in this setup, so it's where it surfaced.
- Content written through a cloud session is silently corrupted wherever it
contains an em-dash, curly quote, or accented character. In this case that is
months of accumulated notes.
- CJK users cannot query or write to a local MCP server from a cloud session at
all.
- No warning is surfaced in the silent case, so damage accumulates unnoticed.
Note on a possibly-related upstream issue
MemPalace has an open issue (#363) about Windows sys.stdin defaulting to the
ANSI codepage. That is a real bug but a separate one — it cannot explain
this, because the same MemPalace process serves local instances correctly.
What Should Happen?
Expected behavior
String arguments should reach the MCP server byte-for-byte as sent, and results should come back byte-for-byte as produced, for any valid UTF-8 input — no exceptions for character class.
A cloud Cowork session should behave identically to a local instance calling the same MCP server. device_bash already round-trips UTF-8 correctly over this same bridge; the MCP proxy path should match it.
Error Messages/Logs
Steps to Reproduce
1. Send a Latin-1-representable character in a string argument
Call any proxied MCP tool with café naïve résumé.
The server echoes the received query back as:
Classic UTF-8-read-as-Latin-1. No error raised.
2. Send CJK in a string argument
Call the same tool with a kana query. Result:
Search error: TextInputSequence must be str in query.
The write path fails identically:
mempalace_add_drawer(content containing kana)
→ TextInputSequence must be str in add.
3. Control — same bridge, non-MCP tool
device_bash: echo "kana: <kana> kanji: <kanji> café before — after"
Returns everything intact. Hex of the em-dash confirms correct UTF-8:
before — after
6265 666f 7265 20e2 8094 2061 6674 6572
^^^^^^^^^ e2 80 94 = U+2014
4. Control — same MCP server, local instance
A local Claude instance calling the same MemPalace server returns kanji intact,
5 results, no error.
5. Control — no MCP at all
python -m mempalace search "<kana>"
Works perfectly. Five correctly-ranked results.
Claude Model
Opus
Is this a regression?
No, this never worked
Last Working Version
No response
Claude Code Version
Claude 1.24012.9 (03c61d) 2026-07-24T04:59:17.000Z
Platform
Other
Operating System
Windows
Terminal/Shell
Other
Additional Information
No response
Preflight Checklist
What's Wrong?
Summary
When a Cowork session running in the cloud calls an MCP server running on the
user's machine (proxied through the connected desktop app), string arguments are
double-encoded — UTF-8 bytes arrive decoded as Latin-1.
The same MCP server, called from a local Claude instance, handles the same
strings correctly. Other tools on the same remote bridge (
device_bash,device_list_dir) round-trip UTF-8 perfectly. So this is not the bridge, not theMCP server, and not the OS locale.
Two distinct failure modes:
the server's tokenizer rejects it.
letters) — no error. Silently stored/queried wrong.
The silent case is the more damaging one: it has been quietly corrupting written
content for months without any indication.
Environment
Claude_pzs8sxrjxfjjc)Reproduction
With a local stdio MCP server proxied to a cloud Cowork session:
1. Send a Latin-1-representable character in a string argument
Call any proxied MCP tool with
café naïve résumé.The server echoes the received query back as:
Classic UTF-8-read-as-Latin-1. No error raised.
2. Send CJK in a string argument
Call the same tool with a kana query. Result:
The write path fails identically:
3. Control — same bridge, non-MCP tool
Returns everything intact. Hex of the em-dash confirms correct UTF-8:
4. Control — same MCP server, local instance
A local Claude instance calling the same MemPalace server returns kanji intact,
5 results, no error.
5. Control — no MCP at all
Works perfectly. Five correctly-ranked results.
What this rules out
device_bashOnly the path containing the MCP proxy fails. The bridge carries UTF-8 fine.
The MCP server handles UTF-8 fine. The OS and Python handle UTF-8 fine.
Things tried that did NOT help
Both target Python's stdin decoding, on the theory that this was a
locale/stdin issue on the server side:
PYTHONUTF8=1andPYTHONIOENCODING=utf-8, with full app restart and a full sign-out. Noeffect on MCP calls. (They do apply to a fresh PowerShell, which is part of
why the CLI test succeeded.)
"-X", "utf8"to the server'sargsand anenvblock with the sametwo variables in
claude_desktop_config.json. No effect.That neither helped is further evidence the corruption happens upstream of the
server process.
Impact
simply the only one in this setup, so it's where it surfaced.
contains an em-dash, curly quote, or accented character. In this case that is
months of accumulated notes.
all.
Note on a possibly-related upstream issue
MemPalace has an open issue (#363) about Windows
sys.stdindefaulting to theANSI codepage. That is a real bug but a separate one — it cannot explain
this, because the same MemPalace process serves local instances correctly.
What Should Happen?
Expected behavior
String arguments should reach the MCP server byte-for-byte as sent, and results should come back byte-for-byte as produced, for any valid UTF-8 input — no exceptions for character class.
A cloud Cowork session should behave identically to a local instance calling the same MCP server. device_bash already round-trips UTF-8 correctly over this same bridge; the MCP proxy path should match it.
Error Messages/Logs
Steps to Reproduce
1. Send a Latin-1-representable character in a string argument
Call any proxied MCP tool with
café naïve résumé.The server echoes the received query back as:
Classic UTF-8-read-as-Latin-1. No error raised.
2. Send CJK in a string argument
Call the same tool with a kana query. Result:
The write path fails identically:
3. Control — same bridge, non-MCP tool
Returns everything intact. Hex of the em-dash confirms correct UTF-8:
4. Control — same MCP server, local instance
A local Claude instance calling the same MemPalace server returns kanji intact,
5 results, no error.
5. Control — no MCP at all
Works perfectly. Five correctly-ranked results.
Claude Model
Opus
Is this a regression?
No, this never worked
Last Working Version
No response
Claude Code Version
Claude 1.24012.9 (03c61d) 2026-07-24T04:59:17.000Z
Platform
Other
Operating System
Windows
Terminal/Shell
Other
Additional Information
No response