Skip to main content
Glama
wiseappsai
by wiseappsai
README.md
# app-store-connect-mcp

> An [MCP](https://modelcontextprotocol.io) server that lets AI agents manage Apple App Store Connect through Apple's official App Store Connect API: apps, App Store metadata, reviews, TestFlight, provisioning, users, and reports.

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
[![CI](https://github.com/wiseappsai/app-store-connect-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/wiseappsai/app-store-connect-mcp/actions/workflows/ci.yml)

Apple publishes the App Store Connect REST API and OpenAPI documentation, but I could not find an Apple-owned official App Store Connect MCP server. This project therefore wraps the official API directly. It also includes `asc_api`, a generic request tool, so agents can use new or less common Apple endpoints without waiting for a wrapper update.

Once connected, ask your assistant:

> *"List my App Store Connect apps."*
> *"Show the App Store versions for this app."*
> *"Update the promotional text for the English localization."*
> *"Create a TestFlight beta group."*

## Quick start

Create an App Store Connect API key in App Store Connect:

1. Open **Users and Access**.
2. Go to **Integrations** / **App Store Connect API**.
3. Create or use an API key and note the **Issuer ID**, **Key ID**, and downloaded `.p8` private key.
4. Store the `.p8` outside your repo, for example `~/.config/app-store-connect-mcp/AuthKey_YOUR_KEY_ID.p8`, and restrict it with `chmod 600`.

Add the server to your MCP client:

```json
{
  "mcpServers": {
    "app-store-connect": {
      "command": "npx",
      "args": ["-y", "@wiseappsai/app-store-connect-mcp"],
      "env": {
        "ASC_KEY_ID": "YOUR_KEY_ID",
        "ASC_ISSUER_ID": "YOUR_ISSUER_ID",
        "ASC_PRIVATE_KEY_PATH": "/absolute/path/AuthKey_YOUR_KEY_ID.p8",
        "ASC_READ_ONLY": "true"
      }
    }
  }
}
```

`ASC_READ_ONLY=true` is recommended while exploring. Remove it when you want the agent to make App Store Connect changes.

For local source use:

```bash
npm install
npm run build
node /absolute/path/app-store-connect-mcp/dist/index.js
```

## Docker

Tagged releases publish a container image to GitHub Container Registry. For a file-based key, mount the `.p8` file read-only and set `ASC_PRIVATE_KEY_PATH`:

```json
{
  "mcpServers": {
    "app-store-connect": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "ASC_KEY_ID",
        "-e",
        "ASC_ISSUER_ID",
        "-e",
        "ASC_PRIVATE_KEY_PATH=/run/secrets/appstoreconnect.p8",
        "-e",
        "ASC_READ_ONLY",
        "-v",
        "/absolute/path/AuthKey_YOUR_KEY_ID.p8:/run/secrets/appstoreconnect.p8:ro",
        "ghcr.io/wiseappsai/app-store-connect-mcp:latest"
      ],
      "env": {
        "ASC_KEY_ID": "YOUR_KEY_ID",
        "ASC_ISSUER_ID": "YOUR_ISSUER_ID",
        "ASC_READ_ONLY": "true"
      }
    }
  }
}
```

Inline private keys also work when your MCP client can provide secret environment variables:

```json
{
  "mcpServers": {
    "app-store-connect": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-e", "ASC_KEY_ID", "-e", "ASC_ISSUER_ID", "-e", "ASC_PRIVATE_KEY", "ghcr.io/wiseappsai/app-store-connect-mcp:latest"],
      "env": {
        "ASC_KEY_ID": "YOUR_KEY_ID",
        "ASC_ISSUER_ID": "YOUR_ISSUER_ID",
        "ASC_PRIVATE_KEY": "<escaped-p8-private-key>",
        "ASC_READ_ONLY": "true"
      }
    }
  }
}
```

To build and test the image locally:

```bash
docker build -t app-store-connect-mcp:local .

docker run -i --rm \
  -e ASC_KEY_ID=YOUR_KEY_ID \
  -e ASC_ISSUER_ID=YOUR_ISSUER_ID \
  -e ASC_PRIVATE_KEY_PATH=/run/secrets/appstoreconnect.p8 \
  -v /secure/AuthKey_YOUR_KEY_ID.p8:/run/secrets/appstoreconnect.p8:ro \
  app-store-connect-mcp:local
```

## Tools

Toolsets are enabled with `ASC_TOOLSETS` (default: `all`). Set `ASC_READ_ONLY=true` to hide mutating actions.

| Toolset | Tools | Covers |
| --- | --- | --- |
| `api` | `asc_api` | Generic access to any official App Store Connect API endpoint. |
| `apps` | `asc_apps` | Apps, App Store versions, localizations, customer reviews, review replies, price points, review submissions. |
| `beta` | `asc_testflight` | Builds, beta groups, beta testers, beta review submissions, beta build localization. |
| `provisioning` | `asc_provisioning` | Bundle IDs, capabilities, certificates, devices, provisioning profiles. |
| `users` | `asc_users` | Users, invitations, roles, visible app access. |
| `reports` | `asc_reports` | Sales, finance, and analytics report requests. |

## Generic API usage

`asc_api` is intentionally broad:

```json
{
  "action": "request",
  "method": "GET",
  "path": "/v1/apps",
  "query": {
    "limit": 10,
    "fields[apps]": "name,bundleId,sku,primaryLocale"
  }
}
```

For write calls, pass Apple's JSON:API request body directly:

```json
{
  "action": "request",
  "method": "PATCH",
  "path": "/v1/appStoreVersionLocalizations/123456789",
  "body": {
    "data": {
      "type": "appStoreVersionLocalizations",
      "id": "123456789",
      "attributes": {
        "promotionalText": "New release text"
      }
    }
  }
}
```

## Configuration

| Variable | Description |
| --- | --- |
| `ASC_KEY_ID` | App Store Connect API key id. Required. |
| `ASC_ISSUER_ID` | App Store Connect issuer id. Required. |
| `ASC_PRIVATE_KEY_PATH` | Path to the downloaded `.p8` private key. Required unless `ASC_PRIVATE_KEY` is set. |
| `ASC_PRIVATE_KEY` | Inline `.p8` private key. Escaped newline sequences are supported. |
| `ASC_READ_ONLY` | `true` hides mutating actions. Default `false`. |
| `ASC_TOOLSETS` | Comma-separated toolsets or `all`. Default `all`. |
| `ASC_VENDOR_NUMBER` | Optional default vendor number for sales and finance report queries. |
| `ASC_BASE_URL` | Override API base URL for tests or proxies. Default `https://api.appstoreconnect.apple.com`. |
| `ASC_LOG_LEVEL` | `error`, `warn`, `info`, or `debug`. Default `info`. |

## Notes

- Apple scopes API keys by role and access. The MCP can only do what the API key can do.
- Report downloads may return gzip/binary content. The server returns those as `{ contentType, byteLength, base64 }`.
- Use `asc_api.get_all_pages` for read-only paginated collections that expose `links.next`.
- Keep `.p8` keys out of git and prefer `ASC_READ_ONLY=true` for exploratory use.

## Security

This server can modify App Store Connect when `ASC_READ_ONLY` is not enabled. Use the least-privileged App Store Connect API key that covers your workflow, store `.p8` keys outside repositories, mount key files read-only in Docker, and never commit `.env`, `.p8`, or `.pem` files.

## Development

```bash
npm install
npm run build
npm test
npm run typecheck
npm audit --audit-level=moderate
```

## References

- [App Store Connect API](https://developer.apple.com/documentation/appstoreconnectapi)
- [Creating API keys for App Store Connect API](https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api)
- [Generating tokens for API requests](https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests)

Maintenance

ActivityMaintained
ResponsivenessSyncing