asc-mcp
by aldanchenko
README.md
# asc-mcp
An MCP server for the App Store Connect API. It lets an MCP client such as Claude Code read your
apps, customer reviews and TestFlight builds, and publish a reply to a review, while the API key
stays inside this process and never reaches the model.
## Tools
| Tool | What it does | Writes? |
|---|---|---|
| `list_apps` | Apps in the account with ids, bundle ids, primary locale | no |
| `get_reviews` | Reviews of one app for the last N days, with filters by territory and rating | no |
| `get_review_reply` | The existing developer reply to one review | no |
| `list_builds` | Recent builds with marketing version, platform and processing state | no |
| `reply_to_review` | Publishes a public developer reply to one review | **yes** |
`reply_to_review` is the only tool with side effects. Its description asks the model to show the
exact text to the user first, and MCP clients normally ask for permission before running a tool
that is not on their allow-list.
Every call is appended to `~/.asc-mcp/calls.jsonl` (override with `ASC_MCP_LOG`): time, tool,
arguments, duration, success or error message.
## Credentials
1. In App Store Connect open **Users and Access → Integrations → App Store Connect API → Team Keys**
and generate a key. The **Developer** role is enough for everything this server does.
2. Download the `.p8` file (it can be downloaded only once) and keep it outside this repository,
for example in `~/.keys/`.
3. Note the **Issuer ID** (top of the Integrations page) and the **Key ID** of the new key.
The server reads three environment variables:
| Variable | Meaning |
|---|---|
| `ASC_ISSUER_ID` | Issuer ID from the Integrations page |
| `ASC_KEY_ID` | Key ID of the generated key |
| `ASC_KEY_PATH` | Path to the `.p8` file (or put the PEM text in `ASC_PRIVATE_KEY` instead) |
See `.env.example`. The key is used to sign short-lived JWTs (15 minutes, ES256). It is read once
and never written anywhere.
## Build and run
```bash
npm install
npm run build
```
Try the tools by hand in the MCP Inspector (opens a web page that starts the server for you):
```bash
ASC_ISSUER_ID=... ASC_KEY_ID=... ASC_KEY_PATH=~/.keys/AuthKey_XXXX.p8 npm run inspect
```
Or list the tools from the command line without any credentials:
```bash
npm run tools
```
## Use from Claude Code
Add the server to the project where you want it (a `.mcp.json` file in the project root), or to
`~/.claude.json` for all projects:
```json
{
"mcpServers": {
"asc": {
"command": "node",
"args": ["/Users/you/Projects/asc-mcp/dist/index.js"],
"env": {
"ASC_ISSUER_ID": "00000000-0000-0000-0000-000000000000",
"ASC_KEY_ID": "ABCDEF1234",
"ASC_KEY_PATH": "/Users/you/.keys/AuthKey_ABCDEF1234.p8"
}
}
}
}
```
Then, in a Claude Code session: *"What did users write about my app this week, and which reviews
should I answer?"* Claude calls `list_apps`, then `get_reviews`, and drafts replies. Nothing is
published until you ask it to call `reply_to_review` and approve the call.
## Project layout
```
src/
index.ts server start-up and tool registration (stdio transport)
auth.ts JWT minting and caching from the .p8 key
api.ts GET/POST helpers, error messages, pagination
log.ts JSONL call log
register.ts wraps tool handlers: JSON results, error results, logging
tools/
apps.ts list_apps
reviews.ts get_reviews, get_review_reply, reply_to_review
builds.ts list_builds
```
## Notes and things to verify
- Field names and endpoints follow the App Store Connect API reference as of this writing:
`GET /v1/apps`, `GET /v1/apps/{id}/customerReviews`, `GET /v1/customerReviews/{id}/response`,
`POST /v1/customerReviewResponses`, `GET /v1/builds`. If Apple changes a field, the error
message from `api.ts` names the request that failed.
- The reply length limit (`MAX_REPLY_LENGTH` in `reviews.ts`) mirrors Apple's limit for developer
responses; check it against the current App Store Connect help before relying on it.
- Sales and download reports use a different endpoint that returns gzipped TSV files. They are not
implemented yet; see the roadmap.
## Roadmap
- `get_downloads`: units per day from the Sales Reports API.
- `get_app_metadata`: current name, subtitle, keywords and description per locale.
- Resources (MCP `resources/list`) exposing the app list for clients that prefer resources to tools.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues