Summary
Please distribute macOS-MCP as a Developer ID code-signed and notarized build — ideally a small bundled helper .app with a proper Info.plist (CFBundleIdentifier / CFBundleName / CFBundleDisplayName) and an icon — with a stable signing identity across releases.
As shipped today (run via ad-hoc-signed Homebrew uv → python3 → the Shell tool spawning node/git), the server's privacy grants show up in System Settings → Privacy & Security as multiple bare, icon-less rows named uv, python3, node, git, spread across Reminders, Calendars, Contacts, Photos, Accessibility, etc. It's confusing for users and looks untrustworthy for something requesting Accessibility and Automation access.
Current behaviour
- Claude Desktop launches the server with
uv --directory <ext> run macos-mcp serve.
uv (/opt/homebrew/bin/uv) is ad-hoc, linker-signed, TeamIdentifier=not set. The venv python3 symlinks to Homebrew's [email protected] (also unsigned/ad-hoc). The Shell tool then posix_spawns further bare binaries (node, git, …).
- Because none of these carry a Developer ID, the TCC responsible-process chain breaks at each hop, so every binary is attributed to itself instead of rolling up under one signed parent. Result: several nameless, icon-less rows instead of a single "macOS-MCP" entry.
- Since the binaries are ad-hoc signed, each
brew upgrade re-signs them with a new cdhash, which invalidates existing TCC grants — users get re-prompted and accumulate stale/duplicate entries after every update.
Impact
- Poor UX and eroded trust: users can't tell what
node/uv/python3 are or which one to trust with Accessibility/Automation.
- Grants don't persist across updates (ad-hoc cdhash churn).
- No way for users to fix this themselves —
tccutil only accepts real bundle IDs, the panes have no per-row delete, and editing TCC.db is SIP-protected. The only remedy today is a full-category tccutil reset, which also wipes unrelated apps.
Requested change
Ship a signed + notarized artifact so macOS has a single, stable, named identity to attribute permissions to:
- Developer ID Application signing on the shipped executable(s), hardened runtime, and notarization (stapled).
- A stable code-signing identifier / Team ID that does not change across releases, so TCC grants survive updates.
- Preferably a bundled helper
.app (or a signed launcher binary with an embedded Info.plist + icon) that hosts the interpreter, so all Accessibility/Automation/data access is attributed to one entry that displays a real **name an
Summary
Please distribute macOS-MCP as a Developer ID code-signed and notarized build — ideally a small bundled helper
.appwith a properInfo.plist(CFBundleIdentifier / CFBundleName / CFBundleDisplayName) and an icon — with a stable signing identity across releases.As shipped today (run via ad-hoc-signed Homebrew
uv→python3→ theShelltool spawningnode/git), the server's privacy grants show up in System Settings → Privacy & Security as multiple bare, icon-less rows nameduv,python3,node,git, spread across Reminders, Calendars, Contacts, Photos, Accessibility, etc. It's confusing for users and looks untrustworthy for something requesting Accessibility and Automation access.Current behaviour
uv --directory <ext> run macos-mcp serve.uv(/opt/homebrew/bin/uv) is ad-hoc, linker-signed,TeamIdentifier=not set. The venvpython3symlinks to Homebrew's[email protected](also unsigned/ad-hoc). TheShelltool thenposix_spawns further bare binaries (node,git, …).brew upgradere-signs them with a new cdhash, which invalidates existing TCC grants — users get re-prompted and accumulate stale/duplicate entries after every update.Impact
node/uv/python3are or which one to trust with Accessibility/Automation.tccutilonly accepts real bundle IDs, the panes have no per-row delete, and editingTCC.dbis SIP-protected. The only remedy today is a full-categorytccutil reset, which also wipes unrelated apps.Requested change
Ship a signed + notarized artifact so macOS has a single, stable, named identity to attribute permissions to:
.app(or a signed launcher binary with an embeddedInfo.plist+ icon) that hosts the interpreter, so all Accessibility/Automation/data access is attributed to one entry that displays a real **name an