appstore-connect-mcp
Provides tools for managing App Store Connect apps, builds, TestFlight beta groups, App Store versions, metadata, screenshots, review information, age rating, availability, pricing, content rights, and submitting for review.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@appstore-connect-mcpSubmit the latest build for App Store review"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
appstore-connect-mcp
A local-only Model Context Protocol server that gives Claude Code (or any MCP-capable coding agent) safe access to App Store Connect only: apps, builds, TestFlight, App Store versions, metadata, App Info, screenshots, review information, age rating, availability, pricing, content rights, and review submission — enough to take a build from "already uploaded" to "submitted for review" with a single human confirmation at the end.
This project deliberately does not touch Xcode. Xcode operations (build, test, archive, source editing, SwiftUI previews) are handled by Apple's own official Xcode MCP. Claude Code orchestrates both servers together. See CLAUDE.md for the full architecture and security rules.
Claude Code
├── xcode → Apple's official Xcode MCP (xcrun mcpbridge)
└── appstore-connect-mcp → this project (stdio)macOS only
stdio transport only — no HTTP server, no open ports, no external deploy target
No database
Your
.p8private key is never written into this repo or committed. It lives outside the repo (e.g.~/.config/appstore-connect-mcp/) and is read from disk only when signing a JWT.
Requirements
macOS
Xcode 26.3+ (for the Xcode MCP side of the workflow)
Node.js (managed via mise)
pnpm (managed via mise)
Claude Code
An App Store Connect Team API Key (Key ID + Issuer ID + downloaded
.p8)
Related MCP server: ShipKit
Setup
1. Xcode MCP (Apple's official server — not part of this repo)
claude mcp add --transport stdio xcode -- xcrun mcpbridgeIn Xcode: Settings → Intelligence → Model Context Protocol → Allow external agents to use Xcode tools.
Verify:
claude mcp list2. appstore-connect-mcp
mise install
mise run install # pnpm install3. Credentials
Create an App Store Connect Team API Key at Users and Access → Integrations → Team Keys, note
its Key ID and Issuer ID, and download the .p8 file once (Apple only allows downloading
it once).
Store the .p8 outside this repository:
mkdir -p ~/.config/appstore-connect-mcp
chmod 700 ~/.config/appstore-connect-mcp
mv ~/Downloads/AuthKey_XXXXXXXXXX.p8 ~/.config/appstore-connect-mcp/
chmod 600 ~/.config/appstore-connect-mcp/AuthKey_XXXXXXXXXX.p8(The key's own contents are never printed anywhere by this project — including here.)
Then set three environment variables, either by copying .env.example to .env in this repo
and filling it in, or by exporting them in your shell / setting them directly in your MCP client
config (see below):
ASC_KEY_ID=<your Key ID>
ASC_ISSUER_ID=<your Issuer ID>
ASC_PRIVATE_KEY_PATH=~/.config/appstore-connect-mcp/AuthKey_XXXXXXXXXX.p8.env, .p8, and anything matching credentials.*/secrets.* are gitignored — see
.gitignore.
4. Verify
mise run test # unit tests — no credentials needed
mise run typecheck
mise run buildTo confirm your credentials actually authenticate, start the server (mise run dev) with the
env vars set and call asc_apps_list from Claude Code — a successful response confirms the JWT
and credentials are valid end-to-end.
Registering with Claude Code
Add appstore-connect-mcp as its own MCP server, alongside xcode:
claude mcp add appstore-connect-mcp -- mise run dev --cwd /absolute/path/to/appstore-connect-mcpReplace /absolute/path/to/appstore-connect-mcp with wherever you cloned this repo — that path is
environment-specific and shouldn't be assumed.
If your Claude Code client doesn't support claude mcp add (e.g. a desktop app without the CLI),
add an entry to its MCP config JSON instead:
{
"mcpServers": {
"appstore-connect-mcp": {
"command": "mise",
"args": ["-C", "/absolute/path/to/appstore-connect-mcp", "run", "dev"],
"env": {
"ASC_KEY_ID": "...",
"ASC_ISSUER_ID": "...",
"ASC_PRIVATE_KEY_PATH": "/Users/you/.config/appstore-connect-mcp/AuthKey_XXXXXXXXXX.p8"
}
}
}
}Use mise -C <dir> run dev (rather than a bare cwd field) if your client doesn't apply cwd
to the spawned process — -C is mise's own "change directory before running" flag and doesn't
depend on the client supporting a cwd key.
After registering, confirm both servers are visible:
claude mcp listYou should see both xcode and appstore-connect-mcp.
Tools
App identification never requires the numeric Apple app id — pass a bundle id
(io.tmkch.colorvia) or app name (Colorvia) and it's resolved for you.
Tool titles are tagged [Read], [Write], or [Destructive/Release] so risk level is visible
at a glance (see CLAUDE.md for the philosophy behind this).
Tool | Class | Description |
| Read | List all apps on the account |
| Read | Get one app's details |
| Read | List an app's uploaded builds |
| Read | Get a single build |
| Read | Get a build's processing state |
| Write | Upload a build ( |
| Read | Get the state of an in-progress build upload |
| Read | List TestFlight beta groups |
| Write | Add a build to a TestFlight group |
| Read | Get "What to Test" notes |
| Write | Update "What to Test" notes |
| Read | Get TestFlight-specific build status |
| Read | List an app's App Store versions |
| Read | Get a single App Store version |
| Write | Create a new App Store version (supports |
| Write | Update a version's fields (supports |
| Write | Attach a build to a version (supports |
| Read | Get localized App Store metadata for a version |
| Write | Update localized metadata (supports |
| Write | Add a new metadata locale to a version (supports |
| Write | Return the version if it exists, else create it — race-safe (supports |
| Read | Find the highest uploaded build number and suggest the next one |
| Read | Poll a build/build-upload until it's terminal (SUCCESS/FAILED/TIMEOUT/CANCELLED) |
| Read | List screenshot sets (and their screenshots) for a version/locale |
| Write | Upload a screenshot, creating its set if needed |
| Destructive/Release | Permanently delete a screenshot |
| Read | Get review contact/demo-account/notes — never returns the password |
| Write | Update review contact/demo-account/notes (password write-only, supports |
| Read | Get the age rating declaration |
| Write | Update the age rating declaration (supports |
| Read | List app-level localizations (name, subtitle, privacy policy) |
| Read | Get one app-level localization |
| Write | Add a new App Info locale (supports |
| Write | Update an App Info locale (supports |
| Read | Get which territories the app is available in |
| Write | Replace the full territory list, or |
| Read | Get whether pricing is configured and whether it's free |
| Write | Set the app to free (supports |
| Read | Get the content rights declaration |
| Write | Update the content rights declaration (supports |
| Write | Sync |
| Read | Comprehensive App Review readiness check |
| Read | Get App Review status for a version |
| Destructive/Release | Submit a version for App Review — runs preflight first, always shows a native macOS confirmation dialog |
There is intentionally no generic "call any App Store Connect endpoint" tool, and no tool that deletes apps or in-app purchases.
Not automatable through the public API
App Privacy Nutrition Labels (data collection / tracking responses) have no documented public App Store Connect API endpoint.
asc_release_preflightalways reports this check asmanual_required— set it manually in App Store Connect under App Privacy.Paid price points —
asc_pricing_set_freereliably handles free apps; setting a specific paid price is not exposed as a tool (Apple's price-schedule API has had several documented behavior changes on their developer forums, and a half-correct paid-pricing tool is worse than none — seesrc/tools/pricing/service.ts).Export compliance (
ITSAppUsesNonExemptEncryption) is an Xcode/Info.plist-side setting;asc_release_preflightreports it when detectable on the uploaded build, but doesn't set it.Apple Developer Program agreement acceptance, tax/banking info, and creating the app record for the very first time all still require the App Store Connect web UI.
asc_build_upload / asc_screenshot_upload implementation notes
Both are implemented against Apple's actual published App Store Connect API schema — not guessed:
Builds use the
BuildUpload/BuildUploadFileresources (App Store Connect API 4.1+): create the upload, create the file record, upload the file in the chunks specified by itsuploadOperations, then commit with an MD5sourceFileChecksums.filechecksum. Processing then continues on Apple's servers — pollasc_build_upload_status, thenasc_builds_list.Screenshots use the older
AppScreenshotSet/AppScreenshotresources (API 1.2+), which use the same chunked-upload pattern but commit with a plainsourceFileChecksumMD5 string instead of a nested checksum object.asc_screenshot_uploadcreates the screenshot set automatically if one doesn't already exist for the given locale/display type.
Both were verified field-by-field against developer.apple.com/documentation/appstoreconnectapi
before implementation (see the header comments in src/tools/uploads/service.ts and
src/tools/screenshots/service.ts for the exact resources referenced).
SSOT config (.appstore/)
Instead of calling metadata/App-Info/availability/age-rating/review/pricing/content-rights tools
one at a time, an app repo can define a single source of truth that asc_release_sync reads and
reconciles against App Store Connect (diff-based — only fields that actually differ get written):
.appstore/
├── appstore.yml
├── en-US/
│ ├── name.txt
│ ├── subtitle.txt
│ ├── description.txt
│ ├── keywords.txt
│ ├── promotional_text.txt
│ └── whats_new.txt
└── ja/
└── ... (same files)app:
bundleId: io.tmkch.example
release:
type: MANUAL
pricing:
type: FREE
availability:
territories: [JPN, USA, CAN, GBR]
review:
signInRequired: false
usernameEnv: APP_REVIEW_USERNAME
passwordEnv: APP_REVIEW_PASSWORD
ageRating:
userGeneratedContent: false
unrestrictedWebAccess: false
gambling: falseSecrets are referenced by environment variable name only — review.usernameEnv /
review.passwordEnv, resolved from the environment at sync time. A literal review.password (or
username) key in the YAML is rejected by the schema outright. All file access is confined to
<projectRoot>/.appstore/ (see src/utils/projectPath.ts) — directory traversal via .. or an
unsafe locale/filename is rejected before any read happens.
Screenshots are not part of this format yet — upload them with asc_screenshot_upload directly.
App Privacy is always reported as manual_required (no public API — see above).
Release flow
Xcode MCP: Build → Test
↓
asc_build_latest → next build number
↓
Xcode MCP: set version/build number → Archive → Export
↓
asc_build_upload → asc_build_wait (poll until VALID)
↓
asc_version_ensure
↓
asc_release_sync (or individual metadata/appInfo/availability/ageRating/pricing/contentRights tools)
↓
asc_version_select_build
↓
asc_release_preflight → must be ready: true
↓
asc_submit_for_review → preflight re-checked → macOS confirmation dialog → human clicks SubmitSee CLAUDE.md for the full orchestration rules (what never to skip, e.g. never submitting with failing tests or a still-processing build).
dryRun
Write tools that support it accept dryRun: true and return the change as a before/after diff
instead of applying it:
{ "appId": "Colorvia", "version": "1.1", "locale": "en-US", "description": "...", "dryRun": true }{ "dryRun": true, "action": "asc_metadata_update", "changes": [
{ "field": "description", "old": "...", "new": "..." }
] }Development
mise run dev # run the MCP server from source (stdio)
mise run build # compile to dist/
mise run typecheck
mise run test # unit tests — no App Store Connect credentials requiredUnit tests never hit the real App Store Connect API — HTTP is stubbed at the fetch boundary,
and JWT tests sign against a throwaway EC key generated in the test itself.
Project layout
src/
├── index.ts # MCP entrypoint (stdio)
├── server/mcp.ts # registers every tool group
├── auth/
│ ├── config.ts # env var loading + .p8 file reading
│ └── jwt.ts # ES256 Team API Key JWT signing/caching
├── asc/
│ ├── client.ts # asc.get/post/patch/delete — not exposed as an MCP tool
│ ├── errors.ts # AppStoreConnectError (HTTP/Reason/Suggestion), AscNetworkError
│ └── types.ts # shared Apple JSON:API + summary types
├── tools/
│ ├── apps/ builds/ uploads/ testflight/ versions/ metadata/ screenshots/ submissions/
│ ├── review/ ageRating/ appInfo/ availability/ pricing/ contentRights/ buildWait/
│ ├── releaseSync/ releasePreflight/
│ └── each: service.ts (App Store Connect logic) + index.ts (MCP tool registration)
├── config/
│ ├── ssotSchema.ts # zod schema for .appstore/appstore.yml
│ └── ssotLoader.ts # reads/validates SSOT + locale files (path-confined)
├── security/confirm.ts # osascript confirmation dialog (submit-for-review)
└── utils/
├── resolveApp.ts, resolveVersion.ts, resolveAppInfo.ts # id resolution + caching
├── mcpResult.ts # toolJson/toolError helpers
├── dryRun.ts # shared dryRun diff builder
├── fileUpload.ts # chunked uploadOperations PUT + MD5 checksum
└── projectPath.ts # path-traversal guard for SSOT file access
tests/ # node:test unit tests, no live API callsMaintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityAmaintenanceMCP server for managing Xcode Cloud workflows, builds, and test artifacts via the App Store Connect API.1591MIT
- Alicense-qualityDmaintenanceMCP server for shipping iOS apps, enabling screenshots of simulators, managing App Store Connect metadata, and submitting apps for review.19MIT
- AlicenseAqualityBmaintenanceAn MCP server that drives the full App Store release cycle for iOS and macOS apps: version bump, archive + TestFlight upload, metadata, review submission, and status.835MIT
- Alicense-qualityAmaintenanceApp Store Connect MCP Server (Swift) that manages apps, builds, TestFlight, metadata, reviews natively on macOSMIT
Related MCP Connectors
MCP server for Appcircle mobile CI/CD platform.
Create App Store screenshots, icons, ASO copy, localization, and revisions via hosted MCP.
MCP server for interacting with the Supabase platform
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/tomoki013/appstore-connect-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server