app-store-connect-mcp
MCP server for App Store Connect — 22 tools covering apps, TestFlight, customer reviews, sales/finance reports, team users, and a credential healthcheck via the App Store Connect API.
Setup
Set three env vars in your MCP host config:
APP_STORE_CONNECT_KEY_ID— 10-character Key ID (e.g.ABC1234567)APP_STORE_CONNECT_ISSUER_ID— Team Issuer ID (UUID)APP_STORE_CONNECT_PRIVATE_KEY_PATH— absolute path to your downloaded.p8file (or paste PEM intoAPP_STORE_CONNECT_PRIVATE_KEY)
Generate a key at appstoreconnect.apple.com → Users and Access → Integrations → App Store Connect API. Save the .p8 (only downloadable once).
Tools
Apps
list_apps— List apps (filter by bundleId/name)get_app— App details by IDlist_app_store_versions— Releases for an appget_app_infos— Age rating and store-state info
TestFlight
list_builds— Recent builds, newest firstget_build— Single build detailslist_beta_groups— Internal & external beta groupslist_beta_testers— Testers, filter by app/group/emailinvite_beta_tester— Add a new tester (optionally to groups/builds)delete_beta_tester— Remove tester from teamadd_testers_to_beta_group— Bulk add to a groupremove_testers_from_beta_group— Bulk remove from a groupsubmit_build_for_beta_review— Send build for beta review
Customer Reviews
list_customer_reviews— Reviews for an app, filter by rating/territoryget_customer_review— Single review with developer responserespond_to_review— Post or update reply
Sales & Finance
download_sales_report— Daily/weekly/monthly/yearly units & sales TSVdownload_finance_report— Region-scoped finance/proceeds TSV;Total_*trailer lines come back in a separatesummaryobject, not inrows
Team Users
list_users— Team userslist_user_invitations— Pending invitationsinvite_user— Invite new team member with roles; app visibility is explicit:allAppsVisible: trueor a non-emptyvisibleAppIds(there is no all-apps default, andallAppsVisible: falsealone is refused)
Health
asc_healthcheck— Is this connector working? Reports which of the three key settings resolved, whether App Store Connect accepted the signed JWT, and what to fix. Start here when another tool fails: a 401 here means a revoked key, a key/issuer team mismatch, or local clock drift — never a wrong password.
Common workflows
Triage low-rated reviews
list_customer_reviewswithrating: 1(sorted-createdDateby default)- For each,
get_customer_reviewto see if there's already a response respond_to_reviewto reply
Promote a build to external testers
list_buildswithappIdto find the build (look forprocessingState: VALID)submit_build_for_beta_reviewwith that build's ID- After Apple approval,
add_testers_to_beta_groupfor the external group
Onboard a new beta tester
list_beta_groupswithappIdto find the right groupinvite_beta_testerwithemail, optional name, andbetaGroupIds
Daily sales pull
download_sales_reportwith yourvendorNumber(from App Store Connect → Payments and Financial Reports),reportDate: YYYY-MM-DD, defaultfrequency: DAILY- Reports are typically available ~24h after the close of the date
Notes
- App Store Connect uses JSON:API: filters are
filter[name]=value, sorts use-prefix for descending. - Every write (invites, deletions, group membership, review responses, beta review submission) asks the user to confirm first. Where the client can show a prompt, it does (unless the server sets
MCP_CONFIRM_ELICITATION=off). Otherwise the first call sends nothing and returnsstatus: "confirmation-required"with a preview and aconfirmToken: show the preview to the user, and only after they approve call the same tool again with the same arguments plusconfirmToken. Tokens are single-use and expire; if the arguments change you getDRAFT_CHANGEDwith a fresh preview. - All write operations (invites, deletions, review responses, beta review submission) require an API key with sufficient role (App Manager or Admin for most TestFlight/team work).
- Sales reports come back as gzipped TSVs and are auto-parsed into row objects. The tool truncates after
limitrows (default 500) but reports the total row count. - Expect a real
.p8file path (or PEM string). The MCP signs short-lived (20-minute) ES256 JWTs locally — your private key never leaves the machine.
