Skip to main content
Glama
README.md
# asc-mcp

**App Store Connect MCP Server — register, test, ship.**

Every other ASC MCP can list your apps. This one **ships** them — and now manages TestFlight too.

One tool, 28 actions. Bundle ID registration, metadata, screenshots, age rating, TestFlight groups + testers, composite one-call shipping — all from your AI agent.

## Why This Exists

Existing ASC MCP servers ([JoshuaRileyDev](https://github.com/JoshuaRileyDev/app-store-connect-mcp-server) 288 stars, [SardorbekR](https://github.com/SardorbekR/appstore-connect-mcp) 13 stars) are **read-heavy, write-light**. They can list apps and manage basic TestFlight. None can submit for review. None have composite actions.

We built this after shipping two iOS apps entirely from Claude Code's CLI — and burning ~15 API calls just discovering age rating field types. The schemas are now baked in.

## What It Does

### Read

| Action | What |
|--------|------|
| `schema` | Returns all ASC API schemas — age rating fields, categories, screenshot types. **Call this first.** |
| `list_apps` | List all apps |
| `find_app` | Find app by bundle ID |
| `get_app` | App details + versions |
| `get_version` | Version details + localizations |
| `get_builds` | Recent builds + processing state + TestFlight status |
| `check_submission` | Check review status |
| `list_beta_groups` | List TestFlight groups (internal + external) |
| `list_beta_testers` | List TestFlight testers for an app |

### Write

| Action | What |
|--------|------|
| `register_bundle_id` | Register a new bundle ID (identifier + name, optional platform) |
| `upload_metadata` | Description, keywords, promo text, support URL, what's new |
| `upload_app_info` | Subtitle, privacy URL, categories |
| `set_age_rating` | All 22 fields in one call — defaults to 4+ (NONE/false) |
| `set_copyright` | Copyright text on version |
| `set_content_rights` | Third-party content declaration |
| `set_encryption` | Export compliance (most apps: `uses_non_exempt=false`) |
| `set_pricing_free` | Set price to FREE |
| `attach_build` | Attach a processed build to a version |
| `create_review_detail` | Reviewer contact info + notes |
| `upload_screenshots` | Upload screenshots with auto-cleanup of existing sets |
| `submit_for_review` | Full 3-step submission: create → add version → confirm |

### TestFlight

| Action | What |
|--------|------|
| `create_beta_group` | Create internal or external testing group |
| `add_build_to_group` | Assign a build to a beta group |
| `add_beta_tester` | Add tester by email (optionally to a specific group) |
| `set_beta_whats_new` | Set "What to Test" for a build |
| `set_beta_app_info` | Set TestFlight description + feedback email |

### Composites (multi-step in one call)

| Action | What |
|--------|------|
| `testflight_setup` | **One call**: set encryption → beta app info → what-to-test → create/find group → add build. TestFlight live in one action. |
| `ship_app` | **One call**: find app → get version → get build → set encryption → attach build → age rating → content rights. App ready for metadata + submission. |

## Schemas Baked In

The stuff that wastes tokens if you don't know it:

- **Age rating**: 13 enum fields (`NONE`/`INFREQUENT_OR_MILD`/`FREQUENT_OR_INTENSE`) + 9 boolean fields. ALL required in one PATCH call.
- **Categories**: String IDs like `TRAVEL`, `SOCIAL_NETWORKING` — not UUIDs.
- **Screenshot types**: `iphone_67` → `APP_IPHONE_67` (1290x2796), etc.
- **Phone format**: Must be international: `+44 844 209 0611`
- **Privacy labels**: No API — must use ASC web UI (we tell you this upfront instead of letting you waste calls discovering it).
- **App creation**: Cannot be done via API — must use ASC web UI (Apple limitation).

## Setup

### 1. Get an API Key

App Store Connect → Users and Access → Integrations → Keys → Generate.

You need:
- **Key ID** (from the key name, e.g., `V82Q36H9CR`)
- **Issuer ID** (UUID at the top of the Keys page)
- **`.p8` key file** (download once, save to `~/private_keys/`)

### 2. Install

Using `uv` (recommended):
```bash
cd /path/to/asc-mcp
uv venv && uv pip install fastmcp PyJWT cryptography
```

Or with pip:
```bash
pip install fastmcp PyJWT cryptography
```

### 3. Configure

Add to your `.mcp.json` (Claude Code, Cursor, etc.):

```json
{
  "mcpServers": {
    "asc": {
      "command": "python3",
      "args": ["/path/to/asc-mcp/server.py"],
      "env": {
        "ASC_KEY_ID": "YOUR_KEY_ID",
        "ASC_ISSUER_ID": "YOUR_ISSUER_ID",
        "ASC_KEY_PATH": "~/private_keys/AuthKey_XXXX.p8"
      }
    }
  }
}
```

If your key is in `~/private_keys/AuthKey_*.p8`, Key ID and path are auto-discovered. You still need `ASC_ISSUER_ID`.

## Example: Ship an App (8 calls)

```
asc action=schema
asc action=find_app bundle_id=com.example.myapp
asc action=upload_metadata version_id=XXX description="My app" keywords="app,cool"
asc action=set_age_rating app_id=XXX
asc action=set_pricing_free app_id=XXX
asc action=upload_screenshots version_id=XXX display_type=iphone_67 screenshot_paths=["/path/1.png","/path/2.png"]
asc action=attach_build version_id=XXX build_id=YYY
asc action=submit_for_review app_id=XXX version_id=XXX
```

## Example: Ship an App (2 calls with composites)

```
asc action=ship_app bundle_id=com.example.myapp
asc action=submit_for_review app_id=XXX version_id=XXX
```

## Example: TestFlight (1 call)

```
asc action=testflight_setup app_id=XXX build_id=YYY whats_new="Test the new onboarding flow" beta_description="Beta version of MyApp" feedback_email=dev@example.com
```

## Example: Add a Tester

```
asc action=add_beta_tester app_id=XXX email_addr=tester@example.com first_name=Jane last_name=Doe
```

## Known Limitations

- **Privacy nutrition labels** cannot be set via the ASC API. You must use the [App Store Connect web UI](https://appstoreconnect.apple.com).
- **App creation** cannot be done via API (Apple 403s the endpoint). Register apps in the ASC web UI.
- **IPA upload** is done via `xcrun altool`, not this MCP (Apple's Transporter handles binary upload, not the REST API).
- **Paid apps**: Only `set_pricing_free` is implemented. Paid tiers need price point lookup per territory.

## License

MIT