跳到主要内容

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_token first; 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 check prints 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)

  1. doctor — Xcode/CLT versions vs App Store minimums, CLIs, keychain identities (expired, missing private keys, duplicates), Apple intermediates, API key, notary credentials.
  2. detect_project path=~/code/myapp — what it is, bundle IDs, team, current signing config, framework-specific snippets.
  3. Pick a target: mac-developer-id, mac-app-store, testflight-mac, ios-app-store, testflight-ios, ios-ad-hoc, ios-development, mac-development, enterprise.
  4. distribution_checklist path=… target=… — ordered list of what's missing, each with the exact tool call or manual step.
  5. 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 clear is 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