AppStore MCP Server

by forgeopslabs

Not rated
GitHub

About

MCP server (Rust, rmcp) exposing the Apple App Store Connect API — apps, in-app purchases, subscriptions, pricing, versions/metadata, TestFlight, provisioning, and asset uploads, plus generic JSON:API tools.

Details

Author
forgeopslabs
Categories
Developer Tools, API, Other

Setup

Install AppStore MCP Server in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/forgeopslabs/appstore-mcp

Follow the installation instructions in the repository README, then restart your MCP client.

AnMCPserver, written in Rust, that exposes theApple App Store Connect APIto AI agents. It covers the full product lifecycle — apps & metadata, in-app purchases, subscriptions and their offers, pricing & availability, App Store versions, App Review submission, TestFlight, provisioning & signing, asset uploads, promoted purchases, customer reviews, phased release, users & access, in-app events, Xcode Cloud, and analytics reports — across114 tools, and can reachanyother App Store Connect endpoint through two generic JSON:API tools.

Built on the officialrmcpSDK over stdio.

📖Full tool reference → docs/TOOLS.md— every tool's purpose and parameters.

Every tool is labelled with MCP annotations, so a client can telllist_appsfromremove_user. You can serve only the domains you need (ASC_TOOLS) or only the tools that cannot write (ASC_READ_ONLY) — seeChoosing which tools to serve.

The App Store Connect API has hundreds of endpoints but is uniformlyJSON:API. Rather than a tool per endpoint, this server ishybrid:

- Curated tools(112) for the common, multi-step, or error-prone workflows — apps & metadata, IAPs, subscriptions & offers, versions, pricing, availability, App Review submission, TestFlight, provisioning, asset uploads, promoted purchases, customer reviews, phased release, users, in-app events, Xcode Cloud, analytics reports, and custom product pages.
- Two generic escape-hatch toolsappstore_requestandappstore_list— that can callanyendpoint with raw JSON:API documents.

Seedocs/TOOLS.mdfor each tool's description and parameters. Custom product page images are uploaded with the existingupload_app_screenshot/upload_app_previewtools.

Prebuilt binaries formacOS (universal), Linux (x86-64), and Windows (x86-64)are attached to everyGitHub Release. Pick the channel for your client; all of them need credentials (seeCredentials).

Downloadappstore-mcp.mcpbfrom the latest release and open it with Claude Desktop (Settings → Extensions → Install Extension…, or drag the file onto the window). It prompts for yourIssuer ID,Key ID, and.p8 key file. The bundle ships all three platforms' binaries and selects the right one automatically.

/plugin marketplace add forgeopslabs/appstore-mcp /plugin install appstore-mcp@forgeopslabs

The plugin launches theappstore-mcpbinary from yourPATH, so install it first — download the binary for your OS from thelatest releaseand put it on yourPATH, orcargo install --git https://github.com/forgeopslabs/appstore-mcp. SetASC_ISSUER_ID,ASC_KEY_ID, andASC_PRIVATE_KEY_PATHin the environment you start Claude Code from.

Codex configures MCP servers directly (no marketplace). Withappstore-mcpon yourPATH:

codex mcp add appstore \ --env ASC_ISSUER_ID=... --env ASC_KEY_ID=... \ --env ASC_PRIVATE_KEY_PATH=/path/AuthKey_XXXXXX.p8 \ -- appstore-mcp
[mcp_servers.appstore] command = "appstore-mcp" args = [] env = { ASC_ISSUER_ID = "...", ASC_KEY_ID = "...", ASC_PRIVATE_KEY_PATH = "/path/AuthKey_XXXXXX.p8" }

Published asio.github.forgeopslabs/appstore-mcp(metadata inserver.json) so any MCP-aware client can discover it.

cargo build --release # -> target/release/appstore-mcp

Generate aTeam Keyin App Store Connect →Users and Access → Integrations → App Store Connect API, and download the.p8file. Then set:

See.env.example. The server authenticates each request with a short-livedES256 JWTsigned by your key (cached and refreshed automatically).

The server starts even without credentials so a client can list its tools; tool calls then return an actionable configuration error until creds are set.

A hundred tool definitions cost context in every session, and a client that sees one flat list can't tell a read from a delete. Two knobs fix that:

ASC_TOOLS=core # 41 tools: generic, apps, versions, assets, testflight, submission ASC_TOOLS=testflight,provisioning # just what a build-distribution agent needs ASC_READ_ONLY=1 # 35 read-only tools; writes are withheld entirely

Groups:generic,apps,iap,subscriptions,versions,pricing,availability,submission,testflight,provisioning,assets,offers,offer-codes,promotions,reviews,users,events,xcode-cloud,analytics,custom-product-pages— plusallandcore. An unrecognised name is warned about on stderr and serves nothing rather than quietly falling back to everything.

In read-only modeappstore_requestis kept but refuses any method other thanGET, so the escape hatch still reaches endpoints without a curated tool without becoming a way around the restriction.

Every served tool advertises MCP annotations (readOnlyHint,destructiveHint,idempotentHint), which clients use to decide what needs confirming. Nine tools are marked destructive: the sevendelete_/remove_tools,expire_build,disable_bundle_id_capability, andappstore_request(which can reach anyDELETEendpoint).

Defaults are chosen so a tool call can't hang and a single response can't swamp an agent's context. All of these are optional.

Retries.A429is replayed for any method, since Apple rejected the request without applying it. A5xxor a mid-flight timeout is replayed only forGET/PATCH/PUT/DELETE— neverPOST, which could otherwise create a duplicate resource (and Apple permanently reserves identifiers like a product ID). Backoff is exponential with jitter and honoursRetry-After.

Response shaping.Results are serialized compactly — indented JSON measured 1.72× the bytes for identical content, so the same budget now carries about 40% more of the data you asked for. Per-resourceselflinks and link-only relationships are stripped: no addressable content is lost, andlinks.nextsurvives for pagination. If a response still exceeds the budget,includedis dropped first, then trailingdataitems, and the result carries a_truncatedkey saying what went missing and how to narrow the query. Note that followinglinks.nextafter a trim would skip the dropped items — re-request with a smallerlimitinstead.

cargo build --release ASC_ISSUER_ID=... ASC_KEY_ID=... ASC_PRIVATE_KEY_PATH=/path/AuthKey_XXX.p8 \ ./target/release/appstore-mcp

The server speaks MCP overstdio. Logs go tostderr; stdout is the protocol channel.

Example client config (e.g. Claude Desktop'smcpServers):

{ "mcpServers": { "appstore": { "command": "/absolute/path/to/appstore-mcp/target/release/appstore-mcp", "env": { "ASC_ISSUER_ID": "00000000-0000-0000-0000-000000000000", "ASC_KEY_ID": "ABCD123456", "ASC_PRIVATE_KEY_PATH": "/absolute/path/to/AuthKey_ABCD123456.p8" } } } }
npx @modelcontextprotocol/inspector ./target/release/appstore-mcp

- IDs are opaque.List/get first to resolve app, IAP, subscription, set, and price-point IDs, then pass them to create/update tools.
- Pricing needs a price point.Uselist_iap_price_points/list_subscription_price_pointsto get theidforset_iap_price_schedule/set_subscription_price.
- Asset uploads(upload_) take a local file path and run the full reserve → chunked upload → MD5 commit flow in one call. The file is streamed, so peak memory is one chunk rather than the size of the asset, and a chunk that fails is retried on its own. Screenshots/previews require an existingappScreenshotSet/appPreviewSet; create those with the generic tools if needed.
- Pagination.appstore_listreturns one page by default. Passmax_pages(up to 20) to followlinks.nextand merge the pages into one result —meta.hasMoretells you whether anything is left.
- Analytics data.request_analytics_reportlist_analytics_reportslist_analytics_report_instanceslist_analytics_report_segmentsgets you a presigned segment URL;download_analytics_segmentfetches it, gunzips it, and returns the rows as JSON. Apple can take up to 48 hours to generate the first report for a new request.
- Anything not listedis reachable viaappstore_request(raw method + path + JSON:API body) orappstore_list(paginated GET). Example:appstore_request { "method": "GET", "path": "/v1/apps/123/customerReviews" }.
- Not covered:sales/finance report endpoints return gzipped TSV (not JSON:API) and are out of scope for these tools.

- You cannot create an app via the API.Theappsresource only allows GET and UPDATE —POST /v1/appsreturns403 FORBIDDEN_ERROR. Create the app record in theApp Store Connect website(Apps → ➕ → New App); you can pre-create its bundle ID withcreate_bundle_id. All other tools operate on an existing app.
- A deleted in-app purchase'sproductIdis permanently reserved by Apple and cannot be reused.

cargo test # 200+ tests, no network or credentials needed cargo clippy --all-targets -- -D warnings cargo fmt --check

Tests come in three layers: pure unit tests for request-body builders, retry decisions, and response shaping;wiremocktests that drive the real HTTP client against a mock API (retries, timeouts, pagination, the three-step upload protocol, segment downloads); andtests/tool_surface.rs, which asserts the invariants of what a client actually sees — unique names, real descriptions, object schemas, correct annotations, and thatASC_TOOLS/ASC_READ_ONLYwithhold exactly what they claim to.

The minimum supported Rust version is1.88, checked by its own CI job.

Regenerate the tool reference after adding/changing tools (needs the release binary; no credentials required):

cargo build --release && python3 scripts/gen_tools_doc.py # rewrites docs/TOOLS.md

scripts/integration_test.pydrives the compiled server against the real API. Read-only by default;--writeadds a self-cleaning IAP lifecycle.

cargo build --release # Credentials via env (ASC_ISSUER_ID/ASC_KEY_ID/ASC_PRIVATE_KEY_PATH) or local # appstore-connect.txt + AuthKey_.p8 in the repo root (both gitignored). python3 scripts/integration_test.py --app <APP_ID> # read-only sweep python3 scripts/integration_test.py --app <APP_ID> --write # + write lifecycle

This is a web browser that enables your coding agent, such as Claude Code, to visit websites on your behalf and assist you in identifying bugs or creating UI test cases.

Clix MCP Server for assisting Clix SDK/API integrations with semantic search across Clix docs and SDK source (iOS, Android, Flutter, React Native).

One shared context layer for AI agents and humans — live API specs, DB schemas, and versioned contracts across repos so every agent and teammate works from the same source of truth.

The MCP server for Bitrix24 provides AI assistants with structured access to the Bitrix24 API. It delivers up-to-date method descriptions, parameters, and valid values, allowing assistants to work with precise data instead of guesswork. This reduces code errors and accelerates Bitrix24 integration development.

Extentos is a multi-vendor development platform for adding smart-glasses capabilities to existing iOS and Android apps. The simplest analogy is Stripe for smart glasses

An MCP server tailored for React Native–first development using Gluestack UI

Tool platform by IBM to build, test and deploy tools for any data source

One remote MCP server for 500+ production APIs — Stripe, HubSpot, Postgres, Gmail, and more. OAuth and API key auth, credential management, and a CLI.

MCP Server for PGYER platform, supports uploading, querying apps, etc.

An MCP server for interacting with the Postman API, requiring an API key.

Arbitrary code execution and tool-use platform for LLMs by Riza

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.