appstore-connect-mcp
App Store Connect MCP server provides a local-only, stdio-based interface for programmatic management of App Store Connect, using .p8 private key JWT signing. It enables automation from uploading builds to submitting an app for review, with dry-run previews and destructive action safeguards.
Key capabilities:
App & Build Management: List apps and details; list, get, check status, upload builds (.ipa/.pkg) with chunked upload and polling; find latest build number; enforce strict Major.Minor.Patch.
TestFlight: Manage beta groups, add builds, get/update 'What to Test' notes, check beta build status.
App Store Versions & Metadata: Create/update/ensure versions and attach builds; manage localized version metadata (description, keywords, promo text, what's new, URLs) and app-level info localizations (name, subtitle, privacy policy); add locales.
Screenshots: List screenshot sets, upload (auto-creating sets), delete (destructive).
Review & Submission: Get/update reviewer info (password write-only not returned); run preflight checks; submit for App Review with mandatory native macOS confirmation and auto re-run preflight; cancel open review submission; check submission status.
Age Rating, Availability, Pricing & Content Rights: Get/update age rating declarations; manage territory availability; set app to free (price equalization); manage content rights.
IAPs & Subscriptions: List/get/create IAPs and subscriptions; manage groups, localizations, pricing per territory, and review screenshots.
SSOT Sync & Orchestration: Sync
.appstore/YAML config files with global defaults and diff-based updates; preflight validation across build, metadata, screenshots, review, age rating, pricing, availability, content rights, and submission.Safety & Dry Run: All write tools support
dryRunto preview diffs; tools tagged [Read]/[Write]/[Destructive/Release]; no generic API escape hatch; no delete apps or IAPs.
Limitations: Cannot automate App Privacy Nutrition Labels, set paid price points (only free), export compliance settings, attaching not-yet-reviewed IAPs/subscriptions, Apple Developer agreement acceptance, or initial app record creation.
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 "Deploy 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-mcp Submit 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 |
| Read | List / get in-app purchases (consumable, non-consumable, non-renewing) |
| Write | Create an in-app purchase |
| Read | List an in-app purchase's per-locale name/description |
| Write | Add / update an in-app purchase locale |
| Read | List Apple's fixed price tiers for an in-app purchase in one territory |
| Read | Get an in-app purchase's pricing status |
| Write | Set an in-app purchase's price (auto-equalized across territories) |
| Read | Get an in-app purchase's App Review-only screenshot |
| Write | Upload/replace an in-app purchase's App Review-only screenshot |
| Read | List / get auto-renewable subscription groups |
| Write | Create a subscription group |
| Read | List / get subscriptions within a group |
| Write | Create an auto-renewable subscription in a group |
| Read | List a subscription group's per-locale display name |
| Write | Add a subscription group locale |
| Read | List a subscription's per-locale name/description |
| Write | Add / update a subscription locale |
| Read | List Apple's fixed price tiers for a subscription in one territory |
| Write | Set a subscription's price in one territory (not auto-equalized — call once per territory) |
| Read | Get a subscription's App Review-only screenshot |
| Write | Upload/replace a subscription's App Review-only screenshot |
| 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 |
| Write | Withdraw the app's currently open review submission |
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.Attaching a new (not-yet-reviewed) in-app purchase or subscription to a review submission has no public API — neither
ReviewSubmissionItemnorAppStoreVersionexposes a relationship to in-app purchases/subscriptions (verified against the API's schema). Select it manually in App Store Connect on the version's page ("In-App Purchases and Subscriptions") before callingasc_submit_for_review— otherwise Apple rejects the submission itself, typically with an HTTP 409 whoseerrorsarray names the unreviewed item (seeAppStoreConnectError.errors, which surfaces Apple's entire errors array, not just the first entry).Apple Developer Program agreement acceptance (including the Paid Apps Agreement, required before
asc_pricing_set_free/paid IAP or subscription pricing will work), tax/banking info, and creating the app record for the very first time all still require the App Store Connect web UI — there is no public API to check agreement status, so a 409/422 on a pricing/availability write that persists after retrying is worth checking there first.
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).
Global defaults (~/.config/appstore-connect-mcp/defaults.yml)
Values that are the same across every app you ship — copyright, support/privacy/marketing URL,
review contact, default release type — don't need to be repeated in every app's
.appstore/appstore.yml. Put them once in an optional, non-repo, user-level file (same directory
convention as the .p8 key; override the path with ASC_GLOBAL_DEFAULTS_PATH):
metadata:
copyright: "2026 Tomokichi"
supportUrl: "https://tmkch.io/support"
privacyPolicyUrl: "https://tmkch.io/privacy"
review:
contactFirstName: "Tomoki"
contactEmail: "support@tmkch.io"
release:
type: "AFTER_APPROVAL"asc_release_sync layers this under each app's own .appstore/appstore.yml — an app-specific
value always wins, an unset one falls back to the global default. App-specific-only fields (App
Privacy, IAP, screenshots, age rating, pricing type, etc.) are never defaulted globally; see
CLAUDE.md's "Global と App固有設定を分離する" for why. Missing the file entirely is fine — this
layer is opt-in.
Version format
Marketing/App Store versions must be strict Major.Minor.Patch (1.0.0, not 1.0, v1.0.0, or
1.0.0-beta) — enforced by src/utils/version.ts. asc_version_create, asc_version_update
(when changing versionString), and asc_version_ensure reject anything else outright; invalid
versions are never auto-corrected, since silently rewriting one hides a real mismatch between the
project, the build, and App Store Connect. asc_release_preflight additionally checks
versionFormat and versionConsistency (the selected build's marketing version must match the
App Store Connect version) before allowing submission.
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/
│ ├── iap/ subscriptions/
│ ├── 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)
│ ├── globalDefaultsSchema.ts # zod schema for ~/.config/appstore-connect-mcp/defaults.yml
│ ├── globalDefaultsLoader.ts # loads the optional user-level defaults file
│ └── mergeDefaults.ts # layers app SSOT config over global defaults (app always wins)
├── ci/buildProvider.ts # BuildProvider interface only — no implementation (see CLAUDE.md)
├── 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
├── version.ts # strict Major.Minor.Patch validation + incrementVersion
└── projectPath.ts # path-traversal guard for SSOT file access
tests/ # node:test unit tests, no live API callsAvailable Tools
44 toolsasc_age_rating_get[Read] Get age rating declarationA
Read-only. Gets the current App Store age rating questionnaire answers for an app (content descriptors, Kids Age Band, age rating overrides).
Inputs: appId (required).
asc_age_rating_update[Write] Update age rating declarationA
Write. Partially updates the age rating questionnaire for an app using Apple's current field set and enum values (content descriptors are NONE/INFREQUENT/FREQUENT). Supports dryRun to preview the change as an old → new diff without applying it.
Inputs: appId (required), dryRun, lootBox, contests, +26 more.
asc_app_get[Read] Get an App Store Connect appA
Read-only. Gets details for a single app. Identify it by bundle id (e.g. io.tmkch.colorvia), app name (e.g. Colorvia), or numeric App Store Connect app id — you never need to know the numeric id yourself.
Inputs: appId (required).
asc_app_info_localization_create[Write] Add a new App Info localeA
Write. Creates app-level localized fields (name, subtitle, privacy policy) for a new locale, e.g. adding "ja". Fails if the locale already exists — use asc_app_info_localization_update for existing locales. Supports dryRun.
Inputs: appId (required), locale (required), name, dryRun, +4 more.
asc_app_info_localization_get[Read] Get one App Info localizationA
Read-only. Gets app-level localized fields for a single locale.
Inputs: appId (required), locale (required).
asc_app_info_localizations_list[Read] List App Info localizationsA
Read-only. Lists app-level localized fields (name, subtitle, privacy policy URL/text, privacy choices URL) for every locale. Distinct from asc_metadata_get, which covers per-version fields like description/keywords.
Inputs: appId (required).
asc_app_info_localization_update[Write] Update an App Info localizationA
Write. Partially updates app-level localized fields (name, subtitle, privacy policy URL/text, privacy choices URL) for an existing locale. Supports dryRun to preview the change as an old → new diff without applying it.
Inputs: appId (required), locale (required), name, dryRun, +4 more.
asc_apps_list[Read] List App Store Connect appsA
Read-only. Lists all apps visible to this App Store Connect account: name, bundle id, SKU, primary locale, and App Store Connect app id. Use this to discover which apps exist before calling other tools.
Inputs: no named parameters.
asc_availability_get[Read] Get App Store availabilityA
Read-only. Gets which App Store territories an app is currently available in.
Inputs: appId (required).
asc_availability_update[Write] Update App Store availabilityA
Write. Replaces the full set of territories an app is available in. Use 3-letter territory codes (e.g. "JPN", "USA", "GBR", "CAN") or the literal "ALL" to expand to every currently active App Store territory (fetched live from Apple). Unknown codes are rejected before any change is made. Supports dryRun to preview enable/disable changes per territory.
Inputs: appId (required), territories (required), dryRun, availableInNewTerritories.
asc_beta_build_localization_get[Read] Get TestFlight "What to Test" notesA
Read-only. Gets the per-locale TestFlight "What to Test" notes for a build. Returns all locales unless a specific one is given.
Inputs: appId (required), buildId (required), locale.
asc_beta_build_localization_update[Write] Update TestFlight "What to Test" notesA
Write. Updates the "What to Test" notes shown to testers for a build/locale. The localization must already exist for that locale (Apple creates these automatically after processing) — use asc_beta_build_localization_get to check first.
Inputs: appId (required), locale (required), buildId (required), whatsNew (required).
asc_beta_build_status[Read] Get TestFlight build statusA
Read-only. Gets a build's processing state plus its internal/external TestFlight beta review state, for checking whether a build is ready to distribute to testers.
Inputs: appId (required), buildId (required).
asc_beta_group_add_build[Write] Add a build to a TestFlight groupA
Write. Adds an already-uploaded build to a TestFlight beta group, making it available to that group's testers. The build must already exist in App Store Connect (see asc_builds_list) — this tool does not upload builds.
Inputs: appId (required), group (required), buildId (required).
asc_beta_groups_list[Read] List TestFlight beta groupsA
Read-only. Lists TestFlight beta tester groups for an app (e.g. "Internal Testers"), including whether each is the internal group and whether public link sharing is enabled.
Inputs: appId (required).
asc_build_get[Read] Get a buildA
Read-only. Gets a single build by its App Store Connect build id or version/build number.
Inputs: appId (required), buildId (required).
asc_build_latest[Read] Get the latest build numberA
Read-only. Finds the highest build number (CFBundleVersion) already uploaded for an app — optionally scoped to a marketing version and/or platform — and suggests the next one. Use this before an Xcode MCP build/archive step to decide what build number to set, since this server never writes to the Xcode project itself.
Inputs: appId (required), version, platform.
asc_builds_list[Read] List buildsA
Read-only. Lists uploaded builds for an app (build id, version/build number, upload date, processing state, whether it has expired), most recent first.
Inputs: appId (required), limit.
asc_build_status[Read] Get build processing statusA
Read-only. Gets just the processing state (e.g. PROCESSING, VALID, INVALID, FAILED) and expiration flag for a build — use this to poll after an upload.
Inputs: appId (required), buildId (required).
asc_build_upload[Write] Upload a build to App Store ConnectA
Write. Uploads a build binary (.ipa for iOS/tvOS/visionOS, .pkg for macOS) to App Store Connect: creates the upload, sends the file in Apple's required chunks, and commits it with an MD5 checksum. Processing then continues on Apple's servers — poll asc_build_upload_status, then asc_builds_list, to see it finish and become a usable build.
Inputs: appId (required), filePath (required), cfBundleVersion (required), cfBundleShortVersionString (required), +1 more.
asc_build_upload_status[Read] Get build upload statusA
Read-only. Gets the state (AWAITING_UPLOAD, PROCESSING, FAILED, COMPLETE) of a build upload started with asc_build_upload, plus any validation errors/warnings Apple reported.
Inputs: buildUploadId (required).
asc_build_wait[Read] Wait for a build or build upload to finish processingA
Read-only (polls, doesn't change anything). Waits for a build (processingState) or a build upload (BuildUpload state) to reach a terminal state — VALID/COMPLETE (success) or FAILED/INVALID (failure) — polling on an interval up to a timeout. Give exactly one of buildId or buildUploadId. Returns SUCCESS, FAILED, TIMEOUT, or CANCELLED, plus Apple's last-seen state, any errors, and when it was last checked.
Inputs: buildId, buildUploadId, timeoutSeconds, pollIntervalSeconds.
asc_content_rights_get[Read] Get content rights declarationA
Read-only. Gets whether the app declares it uses third-party content requiring rights (contentRightsDeclaration).
Inputs: appId (required).
asc_content_rights_update[Write] Update content rights declarationB
Write. Sets whether the app uses third-party content requiring rights. Supports dryRun to preview the change.
Inputs: appId (required), contentRightsDeclaration (required), dryRun.
asc_metadata_create_locale[Write] Add a new App Store metadata localeA
Write. Creates a new localization for a version, e.g. adding Japanese ("ja") to a version that only has en-US. Fails if the locale already exists — use asc_metadata_update for existing locales. Fields are optional and can be filled in now or later with asc_metadata_update. Supports dryRun.
Inputs: appId (required), locale (required), version (required), dryRun, +6 more.
asc_metadata_get[Read] Get App Store version metadataA
Read-only. Gets localized App Store metadata (description, keywords, promotional text, what's new, support URL, marketing URL) for a version. Locale must be explicit — returns all locales unless one is given.
Inputs: appId (required), version (required), locale.
asc_metadata_update[Write] Update App Store version metadataA
Write. Partially updates localized App Store metadata for a version/locale (description, keywords, promotionalText, whatsNew, supportUrl, marketingUrl). Locale is required and must be explicit (e.g. en-US, ja). Supports dryRun to preview the change as an old → new diff without applying it.
Inputs: appId (required), locale (required), version (required), dryRun, +6 more.
asc_pricing_get[Read] Get app pricingA
Read-only. Gets whether an app's price schedule is configured, its base territory, and whether it's currently free (isFree is null if no schedule is configured yet).
Inputs: appId (required).
asc_pricing_set_free[Write] Set the app to freeA
Write. Sets the app's price to free by scheduling the $0 price point in the base territory (Apple equalizes $0 across all other territories/currencies automatically). Paid price points are not supported by this tool. Supports dryRun.
Inputs: appId (required), dryRun, baseTerritory.
asc_release_preflight[Read] Check App Review readinessA
Read-only. Runs a comprehensive readiness check before submitting a version for App Review: app/version/build existence, build processing/selection, app name/subtitle/description/keywords/support URL/privacy policy URL, screenshots, review contact/demo account, age rating, pricing, availability, content rights, export compliance (if detectable), the App Privacy questionnaire (always manual_required — no public API), and current submission state. Each check reports pass/fail/warning/manual_required; ready is true only if every check passes.
Inputs: appId (required), version (required), locale.
asc_release_sync[Write] Sync .appstore/ SSOT config to App Store ConnectA
Write. Reads /.appstore/appstore.yml + locale files and syncs App Info, version metadata, availability, age rating, review info, pricing, and content rights to App Store Connect — diffing local vs remote first, so unchanged fields are never re-written. One category failing doesn't stop the others. Screenshots and App Privacy are always reported separately (skipped / manual_required) since they aren't covered by this sync. Supports dryRun to preview every change without applying anything.
Inputs: version (required), projectRoot (required), dryRun.
asc_review_get[Read] Get App Review informationA
Read-only. Gets the reviewer-only info for a version: contact name/phone/email, demo account requirement/name, and review notes. Never returns the demo account password — only whether one is configured (demoAccountConfigured).
Inputs: appId (required), version (required).
asc_review_update[Write] Update App Review informationA
Write. Partially updates reviewer-only info: contact name/phone/email, demoAccountRequired, demoAccountName, demoAccountPassword, notes. Password is accepted as write-only input — it is never echoed back in this tool's result, in dryRun output, or in logs. Supports dryRun.
Inputs: appId (required), version (required), notes, dryRun, +7 more.
asc_screenshot_delete[Destructive/Release] Delete a screenshotA
DESTRUCTIVE. Permanently removes a single screenshot from App Store Connect. Get the screenshot id from asc_screenshot_sets_list results (each set's screenshots) before calling this.
Inputs: screenshotId (required).
asc_screenshot_sets_list[Read] List screenshot setsA
Read-only. Lists the App Store screenshot sets (one per device display type, e.g. APP_IPHONE_67) for a version/locale.
Inputs: appId (required), locale (required), version (required).
asc_screenshot_upload[Write] Upload a screenshotA
Write. Uploads a local screenshot image file to App Store Connect for a version/locale/display type, creating the screenshot set first if one doesn't already exist for that display type.
Inputs: appId (required), locale (required), version (required), filePath (required), +1 more.
asc_submission_status[Read] Get App Review submission statusA
Read-only. Gets the App Store review state for a version (e.g. PREPARE_FOR_SUBMISSION, WAITING_FOR_REVIEW, IN_REVIEW, REJECTED, READY_FOR_SALE) and whether it has been submitted.
Inputs: appId (required), version (required).
asc_submit_for_review[Destructive/Release] Submit an App Store version for reviewA
DESTRUCTIVE / RELEASE-CLASS. Submits a version for App Review via the current ReviewSubmission API — this changes real, public-facing App Store state and cannot be trivially undone. Always runs asc_release_preflight first and refuses to proceed if any check fails. Always shows a native macOS confirmation dialog (with the preflight summary) to the human user and never submits silently just because it was called; it only proceeds if the human explicitly clicks Submit.
Inputs: appId (required), version (required).
asc_version_create[Write] Create a new App Store versionA
Write. Creates a new App Store Version for an app, e.g. "prepare 1.1 for review". Optionally sets copyright, releaseType (MANUAL/AFTER_APPROVAL/SCHEDULED), and earliestReleaseDate. This does not submit anything for review. Supports dryRun to preview without creating.
Inputs: appId (required), versionString (required), dryRun, platform, +3 more.
asc_version_ensure[Write] Ensure an App Store version existsA
Write. Returns the App Store version if it already exists, or creates it if not — saving the agent from a manual get/exists-check/create/conflict sequence. Returns { version, created }. Supports dryRun.
Inputs: appId (required), versionString (required), dryRun, platform, +3 more.
asc_version_get[Read] Get an App Store versionA
Read-only. Gets a single App Store version by its version string.
Inputs: appId (required), version (required).
asc_version_select_build[Write] Attach a build to an App Store versionA
Write. Sets which uploaded build an App Store version will ship. Supports dryRun to preview without applying.
Inputs: appId (required), buildId (required), version (required), dryRun.
asc_versions_list[Read] List App Store versionsA
Read-only. Lists all App Store versions for an app (version string, platform, App Store review state, created date, copyright, releaseType, earliestReleaseDate).
Inputs: appId (required).
asc_version_update[Write] Update an App Store versionA
Write. Partially updates an existing App Store version: versionString, copyright, releaseType (MANUAL/AFTER_APPROVAL/SCHEDULED), earliestReleaseDate. Supports dryRun to preview the change as an old → new diff without applying it.
Inputs: appId (required), version (required), dryRun, copyright, +3 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 44 tools
Each tool targets a distinct resource and action, with clear descriptions that separate similar-sounding tools (e.g., build status vs upload status vs wait). A few pairs like app-info localization vs metadata could be confused without close reading, but overall the boundaries are well-defined.
Every tool follows the consistent pattern asc_<resource>_<action> (e.g., asc_builds_list, asc_version_update, asc_screenshot_upload), using snake_case throughout with no camelCase or irregular verbs. This makes the naming highly predictable and scannable even at scale.
At 44 tools, the server significantly exceeds the 25-tool threshold where coherence typically degrades. While the App Store Connect domain is broad, the granularity here is high and could overwhelm agents; some operations could likely be consolidated.
The tool set covers core release workflows comprehensively: app management, builds, versions, metadata, localization, beta groups, pricing, availability, review, screenshots, submission, and preflight. Minor gaps exist—no version deletion, no beta group creation/update, and no privacy management—but they are non-critical for most release automation.
Maintenance
Related MCP Connectors
MCP server for Appcircle mobile CI/CD platform.
Create App Store screenshots, icons, ASO copy, localization, and revisions via hosted MCP.
Run App Store Connect from your IDE: pricing, listings, screenshots, releases, AI visibility.
App Store Connect operator for AI agents: icons, TestFlight builds, listings, IAP, rejection fixes.
Related MCP Servers
- AlicenseBqualityBmaintenanceMCP server for managing Xcode Cloud workflows, builds, and test artifacts via the App Store Connect API.1730 npm1MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for shipping iOS apps, enabling screenshots of simulators, managing App Store Connect metadata, and submitting apps for review.19 npmMIT
- AlicenseAqualityDmaintenanceAn 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.843 npmMIT
- AlicenseNot gradedqualityCmaintenanceApp Store Connect MCP Server (Swift) that manages apps, builds, TestFlight, metadata, reviews natively on macOSMIT