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 288 stars, SardorbekR 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)
.p8key 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.):
{
"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.
- 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_freeis implemented. Paid tiers need price point lookup per territory.
License
MIT











