anthropics / anthropics/claude-code
[BUG] Desktop: installing or updating any .mcpb executes every python3 on PATH — x86_64 interpreters launch under Rosetta on Apple Silicon
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 146k
- Forks
- 23.8k
- PR merge metrics
- PR metrics pending
Description
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 Desktop
What's Wrong?
Installing or updating any desktop extension (.mcpb) makes Claude Desktop execute every python3 it can find on PATH, not the one that would actually be used. On Apple Silicon, if any of those is an x86_64-only build (Intel Homebrew's /usr/local/bin/python3 is a common one), the app launches an Intel interpreter, which pulls in Rosetta and produces the macOS Intel-app / Rosetta notification on every extension install or update.
The extension I installed is Node-only and has nothing to do with Python:
"server": { "type": "node", "entry_point": "server/index.mjs",
"mcp_config": { "command": "node", "args": ["${__dirname}/server/index.mjs"] } }
The probe runs anyway. Reproduced twice with the same bundle: a fresh install (v2.0.10) and an update to v2.0.11. Re-opening the same version does not trigger it, so the probe sits on the install/update path.
What Should Happen?
-
Honor the manifest first: probe only the runtime the extension declares (
server.type,compatibility.runtimes). An extension withserver.type: "node"should not touch Python at all. -
Use the manifest's
mcp_config.commandwhen it is present, instead of the hardcoded["python3","python"]list. -
Resolve the way the launcher does. The launch path takes the first match:
let [e] = await a_(t.command, t.args ?? [], r); // [0]The version probe should use that same single resolution instead of iterating over every PATH match. As it stands, the probe executes interpreters the server will never be launched with.
-
Do not read a version by executing PATH binaries that are not going to be used at all. On macOS
/usr/bin/python3is the Xcode Command Line Tools stub, which can raise a system install prompt when CLT is absent (not verified on this machine — worth checking). -
Don't log an
[error]when barepythonis simply absent.
Error Messages/Logs
~/Library/Logs/Claude/main.log (username redacted):
2026-09-19 13:13:04 [info] Handling DXT/MCPB file: 1 path(s) [.mcpb]
2026-09-19 13:13:05 [error] Failed to read version of python binary "python", failed with Error: Failed to spawn python (via disclaimer): /Applications/Claude.app/Contents/Helpers/disclaimer exited with code 127: Failed to spawn process: No such file or directory
at vm (/Applications/Claude.app/Contents/Resources/app.asar/.vite/build/index.chunk-ChZ67Jhw.js:13:131933)
at async Int (/Applications/Claude.app/Contents/Resources/app.asar/.vite/build/index.chunk-ChZ67Jhw.js:13:422316)
2026-09-19 15:14:27 [info] Handling DXT/MCPB file: 1 path(s) [.mcpb]
2026-09-19 15:14:28 [error] Failed to read version of python binary "python", failed with Error: Failed to spawn python (via disclaimer): /Applications/Claude.app/Contents/Helpers/disclaimer exited with code 127: Failed to spawn process: No such file or directory
macOS unified log (log show), ~24 s after the second install — the system noticing an Intel process launch:
2026-09-19 15:14:52 ecosystemd (EcosystemAnalytics) RosettaCoordinator: analyze: processPath: <private>, targetPath: <private>, responsiblePath: <private>
Root Cause
From the shipped bundle, Contents/Resources/app.asar → .vite/build/index.chunk-ChZ67Jhw.js:
async function Int(){
let e = await Mm(), t = [];
for (let n of ["python3","python"])
try {
let r = await a_(n, [], e);
for (let {cmd:e} of r)
try {
let n = (await vm(e, ["--version"])).stdout.match(/Python (\d+\.\d+\.\d+)/);
n && t.push({version:n[1], path:e});
} catch(t) { N.error('Failed to read version of python binary "%s", failed with %o', e, t); }
} catch {}
return t;
}
function Mnt(e,t){
if (e.match(/[\\/]/)) return [e];
let r = t.filter(e => !Xr(e)).map(t => n.default.join(t, e)),
i = await Promise.all(r.map(i_)),
a = r.filter((e,t) => i[t]);
return a.length ? a : [e]; // every PATH directory where the name exists
}
Mnt() returns all PATH directories containing the name — not which's first match — and Int() spawns each candidate through vm() (the disclaimer --pgroup wrapper visible in the stack trace above). Any x86_64-only python3 on PATH therefore gets executed on every extension install/update.
Note the asymmetry with Node: for server.type: "node" the app prefers its built-in runtime and never resolves through PATH (Using built-in Node.js for MCP server: … in the same log), while Python gets a full PATH enumeration.
Steps to Reproduce
- Apple Silicon Mac with an x86_64-only
python3reachable through PATH — for example Intel Homebrew's/usr/local/bin/python3 -> ../Cellar/python@3.14/3.14.7/bin/python3, wherelipo -archsreportsx86_64. Having an arm64python3on PATH as well does not help: the probe does not stop at the first match. - Install or update any desktop extension: double-click a
.mcpb, or Settings → Extensions → Advanced → Install Extension… - The Intel interpreter is executed and macOS surfaces the Rosetta / Intel-app notification.
~/Library/Logs/Claude/main.logshows aHandling DXT/MCPB fileline followed by theFailed to read version of python binaryerror, andlog showshowsRosettaCoordinatoractivity right after.
Claude Model
Not sure / Multiple models — the bug is in the extension install path; no model is involved.
Is this a regression?
I don't know — this is my first desktop-extension install and I have no older build to compare against. The code path above is present in the current release.
Last Working Version
N/A
Claude Code Version
Claude Desktop 2.2553.1 (CFBundleShortVersionString = CFBundleVersion = 2.2553.1). Bundled CLI at Application Support/Claude/claude-code/2.1.275.
Platform
Other (Claude Desktop app, not the API)
Operating System
macOS
Terminal/Shell
Other — N/A (Claude Desktop; PATH inherited from a zsh login shell). lipo -archs on the interpreters: /usr/local/bin/python3 → x86_64; /opt/homebrew/bin/python3 → arm64; /usr/bin/python3 → x86_64 arm64e.
Additional Information
Impact
- On Apple Silicon, any user with an Intel Python installed (Intel Homebrew is still common) gets a Rosetta / Intel-app notification and a translated process on every desktop-extension install or update. A Node-only extension effectively becomes a Rosetta dependency.
- Installing an extension executes every
python3found on PATH, including user-writable locations (~/.local/bin,~/bin, or a project directory that happens to be on PATH). A plantedpython3there runs with the user's privileges while an unrelated extension is installed.
Workaround applied locally (confirms the mechanism)
brew unlink python@3.14 python@3.12 in the Intel Homebrew prefix, which removes the x86_64-only python3 from /usr/local/bin. Afterwards the same probe can only resolve arm64-native interpreters (/opt/homebrew/bin/python3, and the universal /usr/bin/python3), and no Intel process is launched. Nothing else changed.
Related
#92303 is the same class of problem (Claude Desktop + Rosetta on Apple Silicon), but a different component (bundled darwin-x64 node-pty), so I filed this separately.
Environment
Apple M1 Pro; macOS 26.6.2 (build 25G83); Claude Desktop 2.2553.1; reproduced with a locally built MCP bundle (Node-type) on both install and update.
Reporting path
The Desktop docs route Desktop-only problems to the support messenger. Filing here because the defect is deterministic and verifiable from the shipped app bundle, and this tracker already carries an area:desktop label.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at Int() and Mnt() in Contents/Resources/app.asar/.vite/build/index.chunk-ChZ67Jhw.js, then compare their resolution behavior with the launch path using a_(). Reproduce an install or update with a Node-only .mcpb and verify that only the manifest-selected runtime is checked, the first match is used, and absent python does not produce an error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, node.js, python, typescript
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100