notarize-mcp
已验证notarize-mcp · v1.2.0 · MIT
Local stdio MCP server + skill for Apple code signing, notarization, certificates, provisioning, entitlements, Gatekeeper debugging, TestFlight and App Store Connect.
安装
dsh plugin add notarize-mcp 用 dsh --profile default --dump-config 确认 layer 已生效 —— 参见安装指南。
源码
标签
作者
说明文档
notarize — Apple signing, notarization & App Store Connect for AI agents
A local stdio MCP server plus a core skill that take any macOS or iOS app — Xcode, SwiftPM, Electron, Tauri, Flutter, React Native/Expo, or just a prebuilt .app / .dmg / .pkg / .ipa — from "I have an app" to a signed, notarized download, a TestFlight build, or an App Store submission, for someone with zero Apple-platform context. It also debugs the hard parts: entitlements, Gatekeeper ("app is damaged"), App Sandbox denials, privacy (TCC) permissions, notarization rejections and ITMS upload errors.
- 35 tools covering code signing, certificates, provisioning, entitlements, notarization, Gatekeeper, the App Store Connect API (bundle IDs, capabilities, certificates, devices, profiles, builds, TestFlight, versions, review), Xcode archive/export, uploads and CI generation.
- Plan + confirm: every tool that changes anything returns a preview with exact commands/API calls and a
confirm_tokenfirst; it only executes when called again with that token and identical arguments. - Long operations never block: notarization, archives, uploads and build processing hand off to background jobs and return a ready-made Monitor command.
- Explains failures: every codesign / notarytool / stapler / spctl / xcodebuild / altool error is matched against a catalog of known problems with plain-language fixes.
- Setup skill (
skills/setup,/notarize:setup) checks or installs the App Store Connect API key with a zero-dependency script (node skills/setup/scripts/setup.mjs checkprints JSON), then confirms a project's bundle ID, team and version and registers them with Apple. - Skill (
skills/apple-distribution) teaches the agent the mental model, the zero-context workflow, golden rules and a debugging playbook, with references per topic and per framework.
Install
Each release ships one npm package carrying three plugin surfaces plus the server itself. All need Node ≥ 20 on your Mac.
| Surface | What it is | For |
|---|---|---|
npm package notarize-mcp |
The MCP server, run with npx -y notarize-mcp |
Any MCP client |
| …the same package as a DeepSeek Harness bundle | Mounts the server through @deepseek-ai/dsh-mcp-client and both skills through a bundled skill root |
DeepSeek Harness |
| …the same repository as a Codex plugin | Declares the server and both skills together, with setup as the onboarding skill |
Codex |
| Claude Code plugin (this repo's marketplace) | The setup and apple-distribution skills, plus the same server pinned to the matching version |
Claude Code |
Claude Code: the plugin (skill + MCP server)
/plugin marketplace add krishchow/notarize
/plugin install notarize@notarize
The plugin starts the server with npx -y notarize-mcp@<plugin version>, so the skill and the server always match.
Codex: the plugin (skill + MCP server)
codex plugin marketplace add krishchow/notarize
codex plugin add notarize@notarize
.codex-plugin/plugin.json points at the skills directory and at codex.mcp.json, which starts the same pinned server over stdio. Because the plugin marks skills/setup as its onboarding skill, Codex offers to run setup straight after installing. See docs/codex.md.
DeepSeek Harness: the bundle (skill + MCP server)
Install the package as a profile bundle — in the sidebar's Plugins page, by asking the agent to call plugin_manager with action: install_bundle and target: notarize-mcp, or from a checkout with the repo's absolute path as target. dsh plugin --profile … add notarize-mcp is not the same thing: it passes straight through to pnpm add, which installs the package as a plain dependency without selecting it as a bundle, so its patch never applies.
Its cordis.patch.yml composes two rows into the profile: the stdio server (so the tools arrive as mcp__notarize__doctor, mcp__notarize__notarize_and_staple, …) and a skill provider that scans the package's own skills/ directory (so apple-distribution and setup join the session catalog). See docs/dsh.md for what the bundle does, how it resolves its paths, and its one credential caveat.
Any MCP client: just the server
Claude Code without the plugin:
claude mcp add notarize -- npx -y notarize-mcp
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json), Cursor (~/.cursor/mcp.json) or any other client:
{
"mcpServers": {
"notarize": {
"command": "npx",
"args": ["-y", "notarize-mcp"]
}
}
}
Add "env": { "ASC_PROFILE": "…" } to pick a credential profile. To use the skills without the plugin, copy skills/setup and skills/apple-distribution into ~/.claude/skills/.
Run it on the Mac that holds your signing identities. On Linux/Windows only the App Store Connect API and file-inspection tools work. The skill's guides are also exposed as MCP resources (notarize://guides/*, notarize://catalog/*) and there are MCP prompts (setup-distribution, debug-gatekeeper, debug-notarization, debug-sandbox).
Quick start (what the agent will do)
doctor— Xcode/CLT versions vs App Store minimums, CLIs, keychain identities (expired, missing private keys, duplicates), Apple intermediates, API key, notary credentials.detect_project path=~/code/myapp— what it is, bundle IDs, team, current signing config, framework-specific snippets.- Pick a target:
mac-developer-id,mac-app-store,testflight-mac,ios-app-store,testflight-ios,ios-ad-hoc,ios-development,mac-development,enterprise. distribution_checklist path=… target=…— ordered list of what's missing, each with the exact tool call or manual step.- Fix → build/sign (
xcode archive/export,sign,resign) →inspect_code_signature→notarize_and_staple/upload_build→gatekeeper simulate_download/testflight/app_store.
Credentials
One App Store Connect Team API key powers portal automation, notarization, Xcode automatic signing and uploads:
App Store Connect → Users and Access → Integrations → App Store Connect API → Team Keys → + (role Admin, or App Manager) → download AuthKey_XXXXXXXXXX.p8 (only once!).
The easiest path is /notarize:setup. It asks for the Key ID, the Issuer ID and the path of the .p8, never the contents. It previews its changes with setup.mjs plan, then setup.mjs apply makes them:
- installs the key as
~/.appstoreconnect/private_keys/AuthKey_<KEYID>.p8(mode 600); - adds an
ASC_*export block to~/.zshrc; - saves a notarize-mcp profile.
Alternatively, let the agent run asc_auth action=configure (validates and saves a profile), or set env vars:
| Variable | Meaning |
|---|---|
ASC_KEY_ID, ASC_ISSUER_ID, ASC_PRIVATE_KEY_PATH (or ASC_PRIVATE_KEY) |
API key |
ASC_PROFILE |
saved profile name |
NOTARY_KEYCHAIN_PROFILE |
notarytool store-credentials profile |
NOTARIZE_MCP_CONFIG_DIR |
config dir (default ~/.config/notarize-mcp) |
NOTARIZE_MCP_LOG_DIR / NOTARIZE_MCP_STATE_DIR |
command transcripts / background job state |
NOTARIZE_MCP_AUTO_CONFIRM |
unattended runs: safe/1 auto-runs non-destructive actions, a list like sign,package,notary:submit auto-runs only those, all everything — see docs/agent-integration.md |
NOTARIZE_MCP_CODESIGN_PROMPT_TIMEOUT |
seconds the first codesign may wait on a keychain dialog before failing fast (default 45) |
Only the path to the .p8 is stored (in a 0600 file). Private keys generated by keychain create_csr live in ~/.config/notarize-mcp/keys (0600). Passwords are passed via environment variable names (password_env), never through the conversation, and are redacted from logs.
Things only a human can do (the tools tell you exactly how): enrolling in the Apple Developer Program, accepting agreements, creating the API key, creating the App Store Connect app record, and (usually) creating Developer ID certificates as the Account Holder.
Long-running work (notarization, builds)
Notarization usually takes minutes but can take hours; App Store processing 5–30 minutes. Tools wait ~90 s, then return:
{ "status": "running", "job_id": "job_1a2b3c4d", "submission_id": "…",
"monitor": { "command": "node …/notarize-mcp.js watch-job job_1a2b3c4d --state-dir …",
"fallback_command": "node …/notarize-mcp.js watch-notarization <submission-id>",
"timeout_ms": 1800000 } }
In Claude Code the skill starts a Monitor with that command: one notification per status change, a final SUCCEEDED / FAILED / LOST line, then jobs action=status for the full result. The CLI works standalone too:
notarize-mcp watch-job <job-id> # exits 0 ok, 1 failed, 3 lost, 4 max time
notarize-mcp watch-notarization <submission-id> # polls Apple directly; survives server restarts
Tools
| Area | Tools |
|---|---|
| Discovery & diagnostics | doctor, detect_project, distribution_checklist, signing_identities, inspect_code_signature, inspect_binary, entitlements, provisioning_profiles, gatekeeper, quarantine, system_logs, crash_reports, privacy, devices, jobs |
| Signing & notarization | keychain, sign, resign, package, notary, staple, notarize_and_staple |
| App Store Connect / portal | asc_auth, asc_bundle_ids, asc_certificates, asc_devices, asc_profiles, asc_apps, asc_builds, asc_api (raw escape hatch) |
| Build, upload, release, CI | xcode, upload_build, testflight, app_store, ci_config |
notarize-mcp --list-tools prints them; each tool's description documents its actions.
Development
pnpm install
pnpm run check # biome lint + tsc + build + vitest (runs on Linux; macOS CLIs are faked with recorded outputs)
pnpm run build # tsup → dist/notarize-mcp.js (build output, not committed)
claude mcp add notarize -- node "$PWD/dist/notarize-mcp.js" # run your local build in Claude Code
bash scripts/record-fixtures.sh && pnpm run test:recorded # parsers vs real output from your Mac
pnpm run test:live # opt-in, real Apple account (docs/testing.md)
bash scripts/smoke-macos.sh # real end-to-end on a Mac: builds a tiny app, signs, inspects, assesses, packages
pnpm dlx @modelcontextprotocol/inspector node dist/notarize-mcp.js
UPDATE_DOCS=1 pnpm exec vitest run test/docs.test.ts regenerates skills/apple-distribution/references/error-catalog.md from the catalog.
Layout: src/core (argv-only command runner, confirm tokens, jobs, config, redaction, plist), src/knowledge (targets, certificate types, entitlements, privacy keys, error catalog, SDK minimums), src/parsers, src/asc (JWT + JSON:API client), src/tools, src/cli (watchers), skills/apple-distribution, skills/setup (setup skill + scripts/setup.mjs).
Safety notes
- Commands are spawned with argument arrays (no shell), so paths can't inject commands.
- Destructive actions (revoking certificates, deleting profiles/bundle IDs, uploads, review submission, release) are flagged in previews; revoking a Developer ID certificate is called out as breaking shipped apps.
quarantine clearis labelled as a local workaround, never a distribution fix.- Only re-sign software you own or are licensed to distribute.
Documentation
- docs/agent-integration.md: confirm and auto-confirm contract, jobs and Monitor, restarts, permissions, network allowlist.
- docs/codex.md: the Codex plugin — install, what it declares, the environment allowlist and timeouts.
- docs/dsh.md: the DeepSeek Harness bundle — install paths, the rows it composes, and its credential caveat.
- docs/tools.md: every tool, action and argument (generated).
- docs/testing.md: unit tests, recorded macOS output, smoke test, live Apple tests.
- CLAUDE.md: architecture and invariants for contributors and coding agents.
License
MIT