Skip to content

Repository files navigation

appstore-connect-mcp

An MCP server that gives Claude real access to the App Store Connect API: read your listings, audit every localization, upload screenshots for a dozen languages in one call, submit for review, manage pricing and answer customer reviews — without leaving the conversation.

222 tools — complete coverage of every App Store Connect API operation that matters for shipping an app: listings and localizations, screenshots and previews, review submission and review details, phased release, customer reviews, pricing, in-app purchases and subscriptions (availability, introductory and promotional offers, offer codes, App Review screenshots), app metadata (categories, age rating, EULA, export compliance), TestFlight and Beta App Review, sandbox testers, product page optimization (A/B tests), custom product pages, in-app events, promoted purchases, pre-orders, App Clips, team members, territories and code signing.

Game Center, Xcode Cloud/CI, alternative distribution and analytics report requests are deliberately out of scope — past roughly 200 tools a model's tool selection starts to degrade, and those families do not serve app releases.

Why this exists

Doing App Store release work by hand means clicking through the same forms once per language, per device size, per app. The API can do all of it, but its resource model is unfriendly — prices hide behind opaque appPricePoint ids, screenshots need a three-step reserve/upload/commit dance, and half the useful filters are undocumented.

This server hides that. You give it a price in euros and a country code; it finds the price tier. You give it a directory of PNGs; it validates the dimensions, creates the sets and uploads them in the right order.

Install

git clone https://github.com/abdouldotdev/appstore-connect-mcp.git
cd appstore-connect-mcp
npm install && npm run build

Create a .env next to the server (see .env.example):

APPLE_KEY_ID=ABC123DEFG
APPLE_ISSUER_ID=00000000-0000-0000-0000-000000000000
APPLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
...contents of your AuthKey_XXXXXX.p8...
-----END PRIVATE KEY-----"
APPLE_BUNDLE_ID=com.example.app

Generate the key at App Store Connect → Users and Access → Integrations → App Store Connect API. The .p8 file downloads only once. An App Manager + Sales and Reports key covers everything except the code signing tools, which need Admin or Developer.

Register the server (the cd matters — credentials are read from the working directory):

claude mcp add appstore-connect -s user -- \
  sh -c 'cd /absolute/path/to/appstore-connect-mcp && exec node dist/index.js'

What you can do

Area Highlights
Diagnostics get_app_release_status answers "where do I stand?" — version, state, attached build, in-flight submission, phased release, and the next action to take
Localizations List every locale with its id, read any listing with per-field character counts against Apple's limits, diagnose which locales block submission
Screenshots Batch upload from <dir>/<locale>/<DISPLAY_TYPE>/*.png, with local dimension validation before anything is sent, and cleanup of the reservation if an upload fails
Submission Modern reviewSubmissions API, one-shot submit, phased release control, manual release
Reviews Filter unanswered reviews, rating distribution and trend, publish or bulk-publish responses
Pricing Give a price in currency, the server resolves Apple's price tier; schedule promotions; add or remove territories without re-listing all 175
Code signing Certificates, bundle ids, capabilities, devices, profiles, plus a health check for what expires soon

Safety

This server can take actions that are public and irreversible. Three things guard that:

  • confirm: true is required on every destructive, public or irreversible tool — submitting to review, releasing, changing prices, delisting territories, replying to reviews, revoking certificates. Without it the tool refuses and explains what it would have done. bulk_respond_to_reviews returns a full dry run.
  • stdio by default. No network port is opened. The optional HTTP transport (TRANSPORT=http) refuses to bind a non-loopback interface unless OAuth or MCP_HTTP_TOKEN is configured.
  • Nothing about your key is logged. All diagnostics go to stderr, redacted.

Known Apple API limitations

Apple's published specification and its live service disagree in places. These were found by running against production, and each one costs a debugging round if you meet it cold. They are not bugs in this server, and no retry fixes them.

Documented but not served — the tools say so instead of returning a bare 404:

Endpoint Reality
/v1/promotedPurchaseImages Collection, resource and the promotionImages relationship all 404. A promotion image can only be set in App Store Connect by hand — and Apple then refuses to delete a promoted purchase that has one, so a promotion created through the API can become removable only from the console.
/v1/appPriceTiers Retired. Use price points (list_app_price_points, set_app_price).
/v1/builds/{id}/buildBundles No such relationship; bundles come only as an include on the build.

Required despite being marked optional:

  • Introductory offers require territory. There is no worldwide introductory offer — a worldwide free trial is one offer per territory, which is why subscription_introductory_offer_create accepts territory: "ALL" and fans out.
  • Custom product pages require the version and its first localization inline in the same POST.
  • Beta App Clip invocations require a localization inline in the same POST.

Attributes that moved:

  • Age rating: seventeenPlus is gone, replaced by ageRatingOverrideV2. The API returns a dozen descriptors the specification omits (advertising, lootBox, messagingAndChat, userGeneratedContent, …).
  • In-app event assets are the only media family that rejects sourceFileChecksum on commit; they take uploaded alone.

Server-side behaviour to expect:

  • GET /v1/buildBetaDetails?filter[build]= answers HTTP 500 for some builds. /v1/builds/{id}/buildBetaDetail works and is what this server uses.
  • /v1/actors requires filter[id] — actors can be resolved, never enumerated.
  • limit is rejected on custom product page localizations and on v2 experiment treatments.
  • Experiment treatment locales are seeded asynchronously; POSTing one that has just been seeded answers 500, not 409.
  • In-app event resources answer a transient 403 The API key in use does not allow this request for a few seconds after a write, on paths the same key serves fine otherwise. Retrying clears it.
  • App Review screenshots always come back with fileName: "SOURCE".

Out of scope by choice: Game Center, Xcode Cloud / CI, SCM, alternative distribution, marketplaces, background assets, analytics report requests and diagnostic signatures. Every other operation in the specification that serves an app release is covered.

Not possible at all: Apple does not accept binary uploads over the REST API. That needs xcodebuild -exportArchive -destination upload or Transporter, then polling GET /v1/builds. It is a capability gap, not a coverage gap.

Adding a tool

Tools live in src/tools/, one module per domain, collected in a registry that fails loudly on duplicate names. Adding one means creating a file and adding a line. See CONTRIBUTING.md.

Apple publishes an OpenAPI specification for this API, vendored here as 3.2.json. It is the fastest way to settle a question about a payload shape — but see the limitations below before trusting it: on this API the specification and the live service disagree often enough that the server has to be the authority.

(.gitignore still lists 3.2.json from an earlier decision not to vendor it. The file was committed first, so the rule never applied — the spec ships with the repo.)

Status

Verified against a live account with 19 apps. Read paths are exercised across it; the write paths are exercised too, in create → verify → delete round trips that restore the starting state — subscriptions, offers, localizations, screenshots and other media uploads, review details and attachments, custom product pages, in-app events, product page experiments, promoted purchases and TestFlight metadata.

Not exercised against production, and flagged as such in their descriptions: anything that is public and irreversible (submitting to review, releasing a version, ending a pre-order, removing a user) and anything requiring an account state this one does not have. Every one of those is guarded by confirm.

Credits

Built on the foundation of ryaker/appstore-connect-mcp, itself derived from earlier work by Joshua Riley. The JWT authentication approach comes from that lineage; the transport, the tool registry and the large majority of the tools are new.

MIT licensed — see LICENSE for the full copyright chain.

About

MCP server for the App Store Connect API — 222 hand-written tools for shipping iOS apps: listings, screenshots, subscriptions and offers, TestFlight, App Review, pricing, A/B tests. Documents 14 places where Apple OpenAPI spec disagrees with the live API.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages