Skip to content

[BUG] Cowork cloud sessions double-encode non-ASCII in arguments to locally-proxied MCP servers (local sessions unaffected) #82176

Description

@HaysianSmelt

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

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:

café naïve résumé

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:

  1. 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.)
  2. 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:

café naïve résumé

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions