{
  "markdown": "# appstore-release-mcp\n\nAn MCP server that drives the **full App Store release cycle** for iOS and macOS apps: version bump → archive + TestFlight upload → metadata → review submission → status.\n\n**What makes it different:** existing App Store Connect MCP servers wrap the REST API — metadata, TestFlight management, analytics. None of them can do the one step the REST API doesn't support: **getting a binary onto Apple's servers**. This server is a *release pilot*, not an API browser, and gives you two ways to do that:\n\n- **Direct ASC REST API** (ES256 JWT, zero-dependency signing via `node:crypto`) for status, builds, metadata, and review submission\n- **`asc_upload_build`** — your existing fastlane lane archives, signs, and uploads, run as an **async job** with log polling (a real archive takes 5–15 minutes — no MCP timeout can hold that)\n- **`asc_upload_ipa`** — already have a signed `.ipa`? (from `eas build`, a CI pipeline, a manual Xcode archive) Upload it directly via `xcrun altool` — no fastlane, no local archive step, nothing to configure beyond the ASC API key you already have\n- **Local version bumping** across `project.pbxproj` (and `project.yml` for xcodegen projects)\n\n## Requirements\n\n- macOS with Xcode command line tools (`xcrun altool` — used by `asc_upload_ipa`)\n- [fastlane](https://fastlane.tools) with a lane that builds and uploads (e.g. `beta`) — only needed for `asc_upload_build`; skip it entirely if you're only using `asc_upload_ipa`\n- An App Store Connect API key (`.p8`)\n\n## Setup\n\n1. **Generate an ASC API key** (once): App Store Connect → Users and Access → Integrations → App Store Connect API → Team Keys → Generate (role: **App Manager**). Download the `.p8` — Apple lets you download it exactly once. Keep it in `~/.appstoreconnect/private_keys/`.\n\n2. **Register with Claude Code:**\n\n```bash\nclaude mcp add appstore \\\n  -e APPLE_KEY_ID=XXXXXXXXXX \\\n  -e APPLE_ISSUER_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \\\n  -e ASC_KEY_PATH=$HOME/.appstoreconnect/private_keys/AuthKey_XXXXXXXXXX.p8 \\\n  -e APPLE_TEAM_ID=XXXXXXXXXX \\\n  -e ASC_BUNDLE_ID=com.example.myapp \\\n  -e ASC_PROJECT_DIR=/path/to/your/xcode/project \\\n  -- npx appstore-release-mcp\n```\n\nFor a macOS app whose Fastfile uses `platform :mac`, add `-e ASC_PLATFORM=MAC_OS -e ASC_FASTLANE_PLATFORM=mac`.\n\n3. **Verify:** ask the agent to run `asc_doctor`. All checks should be ✓.\n\n## Tools\n\n| Tool | What it does |\n|---|---|\n| `asc_doctor` | Verify config, creds, fastlane/xcodebuild/altool, app record — run first |\n| `asc_app_status` | Versions + review states + recent builds in one call |\n| `asc_list_builds` | Build processing states (wait for `VALID` after upload) |\n| `asc_bump_version` | Bump build number / set marketing version in local project files |\n| `asc_upload_build` | Run your fastlane upload lane as an async job — returns job ID immediately |\n| `asc_upload_ipa` | Upload an already-built `.ipa` via `xcrun altool` — async job, no fastlane needed |\n| `asc_job_status` | Poll a job started by `asc_upload_build` or `asc_upload_ipa`; status + log tail |\n| `asc_update_metadata` | Description / keywords / what's-new / promo text via REST |\n| `asc_submit_review` | Attach build + create review submission + submit |\n\n## Release walkthrough\n\nBuilding locally with fastlane:\n\n```\nasc_doctor                                   # toolchain healthy?\nasc_bump_version {marketing_version: \"1.1.0\"}\nasc_upload_build                             # → job id\nasc_job_status {job_id}                      # poll until succeeded\nasc_list_builds                              # wait for processingState VALID\nasc_update_metadata {whats_new: \"...\", create_version: \"1.1.0\"}\nasc_submit_review {build_id}                 # point of no return\nasc_app_status                               # WAITING_FOR_REVIEW\n```\n\nAlready have a signed `.ipa` (EAS Build, CI, manual archive) — no fastlane needed:\n\n```\nasc_doctor\nasc_upload_ipa {ipa_path: \"./build/app.ipa\"} # → job id\nasc_job_status {job_id}                      # poll until succeeded\nasc_list_builds                              # wait for processingState VALID\nasc_update_metadata {whats_new: \"...\", create_version: \"1.1.0\"}\nasc_submit_review {build_id}\nasc_app_status\n```\n\n## Environment variables\n\nCredential names deliberately match fastlane's `app_store_connect_api_key`, so one credential set serves both.\n\n| Var | Required | Notes |\n|---|---|---|\n| `APPLE_KEY_ID` | yes | ASC API key ID |\n| `APPLE_ISSUER_ID` | yes | ASC issuer ID |\n| `APPLE_KEY_CONTENT` / `ASC_KEY_PATH` | one of | base64-encoded `.p8` / path to `.p8` file |\n| `APPLE_TEAM_ID` | for `asc_upload_build` | Apple Developer team ID (not needed for `asc_upload_ipa`) |\n| `ASC_BUNDLE_ID` | yes | your app's bundle identifier |\n| `ASC_PROJECT_DIR` | recommended | Xcode project root where fastlane runs (default: cwd) |\n| `ASC_PLATFORM` | no | `IOS` (default), `MAC_OS`, `TV_OS`, `VISION_OS` |\n| `ASC_FASTLANE_LANE` | no | upload lane name (default: `beta`) |\n| `ASC_FASTLANE_PLATFORM` | no | fastlane platform prefix, e.g. `mac` or `ios` |\n| `ASC_UPLOAD_CMD` | no | full override, e.g. `bundle exec fastlane ios beta` |\n\n## Notes\n\n- Build jobs are children of the server process; if the MCP client disconnects mid-build the job dies. Logs persist in `~/.appstore-mcp/jobs/` either way.\n- `asc_submit_review` is the point of no return for a release — the tool description tells agents to confirm with a human first.\n\n## License\n\nMIT\n",
  "bytes": 5449,
  "sha": "2018784aa5d2820e1f6e343382dfe486bd9b81252bfca2cbc73c215bcf64e824",
  "repo_slug": "rabdulsal/appstore-release-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_rabdulsal_appstore_release_mcp_45aa9a88/readme"
}