App Store Connect MCP
# App Store Connect MCP
**The entire App Store Connect API for Claude Code, Claude Desktop and Cursor.** All 1,303 operations in Apple's OpenAPI spec (v4.5.1): apps, builds, TestFlight, metadata and screenshots, pricing, in-app purchases and subscriptions, customer reviews, Game Center, Xcode Cloud, provisioning, analytics and sales/finance reports.
Built and maintained by [iHux](https://github.com/iHux-LLC).
[](https://github.com/iHux-LLC/appstore-connect-mcp/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/@ihux/appstore-connect-mcp)
[](LICENSE)
## Install
### Claude Desktop: one-click extension
1. Download **[appstore-connect.mcpb](https://github.com/iHux-LLC/appstore-connect-mcp/releases/latest/download/appstore-connect.mcpb)** from the latest release.
2. Double-click it, or drag it into **Claude Desktop → Settings → Extensions**, and click **Install**.
3. In a chat, ask Claude to ***"open the App Store Connect settings"*** and add your API key there ([how to get one](#get-an-api-key)).
No terminal and no Node.js install needed; Claude Desktop runs the extension itself.
### Claude Code, Cursor (or Claude Desktop without the extension)
Needs [Node.js](https://nodejs.org) 20 or later. Run:
```bash
npx -y @ihux/appstore-connect-mcp settings
```
A settings page opens in your browser. Add your API key, choose what Claude may do, then click **Install** next to each app you use. Restart Claude Desktop or Cursor afterwards; Claude Code picks it up immediately.
### Get an API key
1. In App Store Connect, open **[Users and Access → Integrations → App Store Connect API](https://appstoreconnect.apple.com/access/integrations/api)**.
2. Create a **Team Key**. Its role sets what the server can do: *Developer* is enough for reading, *App Manager* for most writes, *Finance* for financial reports.
3. Download the `AuthKey_XXXXXXXXXX.p8` file (Apple only lets you download it once) and note the **Issuer ID** shown above the keys list.
Then ask Claude: *"Check my App Store Connect connection"* and *"List my apps"*.
## What you get
Exposing 1,303 tools would overload any MCP client, so the server uses a small set of tools instead:
| Tool | What it does |
|---|---|
| `asc_search_operations` | Finds the right operation among all 1,303 by keyword ("customer reviews", "testflight testers", "subscription prices") |
| `asc_describe_operation` | Shows an operation's parameters, filters, `fields[...]` options and full request-body schema |
| `asc_call_operation` | Calls any operation, checking parameters against Apple's spec first, and can follow pagination |
| `asc_fetch_url` | Follows a `nextUrl` or related link from an earlier response |
| `asc_list_resource_groups` | Lists the 204 resource groups so you can browse the API |
| `asc_upload_asset` | Uploads screenshots, previews, IAP images and similar files with Apple's reserve, upload and commit flow *(write mode)* |
On top of those, shortcuts for common jobs return compact, flattened results:
- **Read:** `asc_check_connection`, `asc_list_apps`, `asc_app_overview`, `asc_list_builds`, `asc_list_customer_reviews`, `asc_list_beta_groups`, `asc_list_version_localizations`, `asc_download_sales_report`, `asc_download_finance_report`
- **Write** (only in `write` or `full` mode): `asc_reply_to_customer_review`, `asc_invite_beta_tester`, `asc_update_version_localization`, `asc_create_app_store_version`, `asc_attach_build_to_version`, `asc_submit_for_review`
Sales and finance reports arrive gzipped. The server decompresses them and returns the rows; pass `saveTo` to write the full TSV to a file.
## How it works on your machine
```
Claude Code / Claude Desktop / Cursor
│ launch the server as a background process and talk to it over stdin/stdout
▼
appstore-connect-mcp ── reads ~/.config/appstore-connect-mcp/ (key ID, issuer ID, mode, .p8 key)
│ signs a 20-minute token with your key; the key itself never leaves your machine
▼
api.appstoreconnect.apple.com
```
All three clients share one settings folder. Their own config files only hold the command that launches the server, never secrets.
## The settings page
Open it with `npx -y @ihux/appstore-connect-mcp settings`, or by asking Claude to *"open the App Store Connect settings"*. On it you:
1. **Add your key.** Drop the `.p8` file; the Key ID is read from its name and you enter the Issuer ID. The page tests the key against Apple and saves it only if Apple accepts it. The key is copied into the settings folder, readable only by you.
2. **Choose what Claude may do:** Read-only, Write or Full (see [Access modes](#access-modes)).
3. **Add the server to your apps:** one click each for Claude Code, Claude Desktop and Cursor. Each config file is backed up before it changes.
Claude can open the page, but only you can change anything on it. The page only listens on `127.0.0.1`, needs the one-time token in the URL it opens, and shuts down after 15 minutes idle or when you click **Done**.
### Prefer the terminal?
```bash
npx -y @ihux/appstore-connect-mcp set-key --key-file ~/Downloads/AuthKey_2X9R4HXF34.p8 --issuer-id <issuer-id>
npx -y @ihux/appstore-connect-mcp mode write # readonly | write | full
npx -y @ihux/appstore-connect-mcp install # every app found; or: install claude-code | claude-desktop | cursor
npx -y @ihux/appstore-connect-mcp status # what is set, where it comes from, which apps have it
```
## Access modes
| Mode | Allowed |
|---|---|
| `readonly` *(default)* | GET requests only. Write shortcuts and the upload tool are hidden |
| `write` | Also creates and updates (POST and PATCH): metadata, TestFlight, review replies, submissions, uploads |
| `full` | Also deletes |
Changing the mode takes effect within about a second: running servers watch the settings file and tell the client its tool list has changed. If a client doesn't support that notification, restart it.
**What "only you can change it" means.** No MCP tool can change settings, and the settings page's token never reaches the model. An agent that can run shell commands, such as Claude Code, could still edit files in your settings folder. Claude Code asks for your permission before running those commands, so approve shell commands with care.
## Advanced: environment variables
Environment variables override the settings file field by field. They are useful in CI or for a different key per client. Set them in the client's `env` block:
| Variable | Value |
|---|---|
| `ASC_KEY_ID`, `ASC_ISSUER_ID` | Key ID and Issuer ID |
| `ASC_PRIVATE_KEY_PATH` / `ASC_PRIVATE_KEY` | Path to the `.p8`, or its PEM contents (`\n` escapes are fine) |
| `ASC_MODE` | `readonly`, `write` or `full`. If set, it pins the mode for that client; the settings page warns when it detects this |
| `ASC_CONFIG_DIR` | Use a different settings folder |
| `ASC_MAX_RESPONSE_CHARS` | Largest response returned inline (default `60000`) |
> Claude Desktop doesn't load your shell profile, so the installer writes the absolute path to `node`. If you install by hand and use nvm, fnm or asdf, use the full path that `which node` prints.
## Example prompts
- "Which of my apps have a version waiting for review?"
- "Show the 1- and 2-star reviews from the last month for MyApp that have no reply yet, and draft replies."
- "List the TestFlight builds of version 2.3 and which are still processing."
- "Invite jane@example.com to the External Testers group."
- "Update the What's New text for en-US and de-DE on version 2.4."
- "Download last month's sales summary for vendor 8xxxxxxx and total the units by country."
- "Which Xcode Cloud workflows failed this week?" (uses the generic tools)
## Development
```bash
git clone https://github.com/iHux-LLC/appstore-connect-mcp.git
cd appstore-connect-mcp
npm install # also builds dist/
node dist/index.js settings
```
### Keeping up with Apple
When Apple publishes a new API version:
```bash
npm run update-spec # downloads the latest spec and regenerates catalog/catalog.json
npm run build
```
New endpoints become available through `asc_search_operations` and `asc_call_operation` without any code changes.
### Commands
```bash
npm test # unit and integration tests, with Apple's API mocked
npm run typecheck
npm run generate # rebuild the catalog from spec/openapi.oas.json
npm run bundle # build the Claude Desktop extension into build/appstore-connect.mcpb
```
### Code layout
| Path | Purpose |
|---|---|
| `scripts/generate.ts` | Turns Apple's spec into `catalog/catalog.json` (operations, parameters and request schemas with refs resolved) |
| `src/auth.ts` | ES256 JWT signing; tokens are cached and re-signed before the 20-minute limit |
| `src/client.ts` | HTTP client: mode checks, retries on 429 and 5xx, Apple error formatting, pagination; only sends the token to `api.appstoreconnect.apple.com` |
| `src/validate.ts` | Checks path, query and body against the spec before each request |
| `src/format.ts` | Strips JSON:API links, keeps responses within the size budget, decodes gzipped TSV reports |
| `src/upload.ts` | Generic asset upload for all 27 upload-capable resource types |
| `src/settings/store.ts` | The settings folder: atomic writes with owner-only permissions |
| `src/settings/web.ts`, `assets/settings.html` | The local settings page and its API |
| `src/settings/clients.ts` | Detects Claude Code, Claude Desktop and Cursor, and installs the server with backups |
| `manifest.json`, `scripts/bundle.ts` | Claude Desktop extension: manifest and build script (fills in version and tool list) |
| `src/index.ts` | CLI: `settings`, `status`, `mode`, `install`, `uninstall`, `set-key`; with no command it runs the MCP server |
| `src/tools/` | MCP tool definitions |
### Releasing
1. Bump `version` in `package.json` and commit.
2. Tag and push: `git tag v0.3.0 && git push origin v0.3.0`.
3. The release workflow runs the tests, attaches `appstore-connect.mcpb` to a new GitHub Release, and publishes `@ihux/appstore-connect-mcp` to npm.
If a step fails, fix the cause and re-run the workflow; it skips what already succeeded. To publish an existing tag to npm on its own, run **Actions → Publish to npm** with the tag. The `NPM_TOKEN` secret must be a granular token with publish rights to `@ihux` and **Bypass 2FA** enabled.
## Not covered
- The **App Store Server API** (transactions, refunds, server notifications). It is a separate API with its own keys.
- Downloading **Analytics report segments**. The API returns signed URLs on Apple's CDN, outside the API host the server is allowed to call. Listing the reports and their segments works.
## License
[MIT](LICENSE) © 2026 iHux LLC. Not affiliated with or endorsed by Apple. App Store Connect is a trademark of Apple Inc.
TDQS
Scored across 15 tools
Each tool has a clearly distinct role: curated list/overview/report tools target specific resources, while the generic search/describe/call/fetch pipeline is explicitly layered. Descriptions clarify when to use curated tools versus generic API access, and no two tools appear to do the same thing.
All tools share the asc_ prefix and snake_case, and nearly all follow a verb_noun pattern (list_apps, download_sales_report, search_operations). The only deviation is asc_app_overview, which is noun-based rather than verb-based, a minor inconsistency.
15 tools is well-scoped for a broad App Store Connect integration: 8 curated tools cover common read workflows, and 7 generic/setup tools provide safe access to the full 1,300+ operation API without exploding the surface. Each tool earns its place, with no obvious redundancy.
The curated tools cover key read paths (apps, versions, builds, reviews, beta groups, reports), and asc_search_operations/describe_operation/call_operation provide full CRUD and lifecycle access across the entire App Store Connect API. Auth, pagination, and settings are also addressed, leaving no structural dead ends.