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

Open
#95,551 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area:desktop area:mcp bug has repro platform:macos
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 with server.type: "node" should not touch Python at all.

  • Use the manifest's mcp_config.command when 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/python3 is 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 bare python is 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
  1. Apple Silicon Mac with an x86_64-only python3 reachable through PATH — for example Intel Homebrew's /usr/local/bin/python3 -> ../Cellar/python@3.14/3.14.7/bin/python3, where lipo -archs reports x86_64. Having an arm64 python3 on PATH as well does not help: the probe does not stop at the first match.
  2. Install or update any desktop extension: double-click a .mcpb, or Settings → Extensions → Advanced → Install Extension…
  3. The Intel interpreter is executed and macOS surfaces the Rosetta / Intel-app notification. ~/Library/Logs/Claude/main.log shows a Handling DXT/MCPB file line followed by the Failed to read version of python binary error, and log show shows RosettaCoordinator activity 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/python3x86_64; /opt/homebrew/bin/python3arm64; /usr/bin/python3x86_64 arm64e.

Additional Information

Impact

  1. 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.
  2. Installing an extension executes every python3 found on PATH, including user-writable locations (~/.local/bin, ~/bin, or a project directory that happens to be on PATH). A planted python3 there 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.