ZD

zelentsov-dev/asc-mcp

Developer tools
60 stars 0 forks 품질 99 트렌드 99

App Store Connect MCP Server A local Model Context Protocol server for the App Store Connect API. Manage apps, builds, TestFlight, reviews, and more from Codex, Claude, and other MCP clients on macOS.

개요

App Store Connect MCP Server A local Model Context Protocol server for the App Store Connect API. Manage apps, builds, TestFlight, reviews, and more from Codex, Claude, and other MCP clients on macOS.

README

App Store Connect MCP Server

A local Model Context Protocol server for the App Store Connect API.
Manage apps, builds, TestFlight, reviews, and more from Codex, Claude, and other MCP clients on macOS.

Overview

asc-mcp is a Swift-based MCP server that connects a local macOS MCP client to the App Store Connect API. It exposes 502 tools across 33 App Store tool domains + 2 core domains, enabling you to automate iOS and macOS release workflows through natural language.

Configuration examples are included for Codex, Claude Code, Claude Desktop, Gemini CLI, VS Code with GitHub Copilot, Continue, Cursor, and Devin Desktop (formerly Windsurf). Client configuration is documented; release CI verifies installation, MCP initialization, and tool discovery on macOS rather than launching every third-party client.

New here? Follow the Quick Start. The remaining sections are reference material for advanced configuration, tool selection, and contributors.

Key capabilities

  • Release and metadata — versions, localizations, builds, review submissions, phased rollout, and Xcode Cloud
  • TestFlight and uploads — beta groups, testers, feedback, recruitment, build delivery, processing, and export compliance
  • Monetization — in-app purchases, subscriptions, pricing, availability, offer codes, and promotional offers
  • Marketing — screenshots, previews, custom product pages, product page optimization, and promoted purchases
  • Accounts and provisioning — multiple App Store Connect teams, users, bundle IDs, devices, certificates, profiles, and capabilities
  • Feedback and operations — customer reviews, webhooks, accessibility declarations, analytics, metrics, and diagnostics
  • Safer automation — read-only mode, confirmation safeguards, strict pagination, and mutation recovery guidance
  • Auditable API coverage — a versioned Apple OpenAPI contract and release-time drift checks

Platform Support

asc-mcp is a local stdio server: the MCP client starts it on the same computer. A client being available on Linux or Windows does not make this Swift server cross-platform.

Environment Status Notes
macOS 15.6+ with Xcode 26.x Recommended Release CI specifically uses GitHub’s macOS 15 runner with Xcode 26.2
macOS 14.0-15.5 Declared deployment target only Build and runtime are unverified; a separately installed Swift 6.2+ toolchain may be needed
Linux Not supported yet Porting work and Linux CI are not complete
Windows Not supported Current source dependencies and Swift MCP stdio transport are not Windows-compatible

See Apple’s Xcode system requirements for the macOS versions supported by each Xcode release.

Web and cloud sessions do not automatically inherit a local MCP configuration. Run the MCP client locally on a compatible Mac, or use a client feature that explicitly keeps execution on that Mac.

Quick Start

The recommended setup stores App Store Connect credentials once in a private local file. MCP clients then need only the path to the asc-mcp executable.

1. Install asc-mcp

brew install mint
mint install zelentsov-dev/[email protected]
~/.mint/bin/asc-mcp --version

2. Create an App Store Connect API key

  1. Open App Store Connect → Users and Access → Integrations → Team Keys.
  2. Generate a key with the least-privileged role that covers your workflow. App Manager or Admin is needed only when the corresponding operations require it.
  3. Download the .p8 file. Apple allows it to be downloaded only once.
  4. Copy the Key ID and Issuer ID.

3. Save the credentials locally

Create private configuration directories, then move the downloaded .p8 file into ~/.keys/. Replace the source path and filename in the second command:

mkdir -p ~/.config/asc-mcp ~/.keys
chmod 700 ~/.config/asc-mcp ~/.keys
mv /path/to/downloaded/AuthKey_XXXXXXXXXX.p8 ~/.keys/

Create ~/.config/asc-mcp/companies.json:

{
  "companies": [
    {
      "id": "my-company",
      "name": "My Company",
      "key_id": "XXXXXXXXXX",
      "issuer_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "key_path": "/Users/you/.keys/AuthKey_XXXXXXXXXX.p8"
    }
  ]
}

Replace /Users/you with your actual home-directory path. Keep both files outside the repository and restrict access:

chmod 600 ~/.config/asc-mcp/companies.json
chmod 600 /Users/you/.keys/AuthKey_XXXXXXXXXX.p8

[!CAUTION] Never commit companies.json, a .p8 key, or raw credentials to Git. Revoke the App Store Connect key immediately if it is exposed.

4. Connect your MCP client

Choose one client. You do not need to configure every client.

Codex

codex mcp add asc-mcp -- ~/.mint/bin/asc-mcp
codex mcp list

Claude Code

claude mcp add \
  --transport stdio \
  --scope user \
  asc-mcp \
  -- ~/.mint/bin/asc-mcp

claude mcp get asc-mcp
claude mcp list

For Claude Desktop, Gemini CLI, VS Code, Continue, Cursor, and Devin Desktop, use the ready-to-copy examples in MCP Client Setup.

5. Try it

Restart a GUI client after changing its configuration, open its MCP tool list, and ask:

List my App Store Connect apps.

If the connection or request fails, see Troubleshooting.

Installation

Mint installs the pinned release from source and keeps the executable at ~/.mint/bin/asc-mcp.

brew install mint
mint install zelentsov-dev/[email protected]

Update or reinstall the pinned release:

mint install zelentsov-dev/[email protected] --force

Stable users should install a version tag. Installing main or develop is intended only for maintainers and pre-release testing.

Build from source

Use Xcode 26.x on a compatible macOS version, or install a standalone Swift 6.2+ toolchain.

git clone https://github.com/zelentsov-dev/asc-mcp.git
cd asc-mcp
swift build -c release

The executable is .build/release/asc-mcp. If you copy it elsewhere, also copy the adjacent resource bundle:

cp .build/release/asc-mcp /usr/local/bin/asc-mcp
cp -R .build/release/asc-mcp_asc-mcp.bundle /usr/local/bin/

The bundle contains the versioned OpenAPI operation contract used by release checks.

Upgrading from an older release

Configuration

Credentials

The default ~/.config/asc-mcp/companies.json file shown in the Quick Start is recommended because it works consistently for terminal and GUI clients without duplicating secrets in every client configuration.

For multiple companies, add more entries:

{
  "companies": [
    {
      "id": "my-company",
      "name": "My Company",
      "key_id": "XXXXXXXXXX",
      "issuer_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "key_path": "/Users/you/.keys/AuthKey_XXXXXXXXXX.p8",
      "vendor_number": "YOUR_VENDOR_NUMBER"
    },
    {
      "id": "client-company",
      "name": "Client Company",
      "key_id": "YYYYYYYYYY",
      "issuer_id": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
      "key_path": "/Users/you/.keys/AuthKey_YYYYYYYYYY.p8"
    }
  ]
}

vendor_number is required only for analytics_sales_report, analytics_financial_report, and analytics_app_summary. Find it in App Store Connect → Sales and Trends → Reports.

MCP Client Setup

All examples below assume a Mint installation and the recommended companies.json credential file. Replace /Users/you with your actual home-directory path. GUI clients generally require an absolute executable path.

Client Configuration scope Notes
Codex User config by CLI; optional trusted-project config Shared by local Codex clients on the same Mac
Claude Code user, local, or project scope user is simplest for a personal App Store utility
Claude Desktop User-level desktop config Restart after editing
Gemini CLI User settings Local stdio server
VS Code with GitHub Copilot User profile or .vscode/mcp.json Confirm server trust on first start
Continue Workspace .continue/mcpServers/ Separate from native VS Code MCP configuration
Cursor User or project mcp.json Use an absolute command path
Devin Desktop (formerly Windsurf) User MCP config Keep no more than 100 active tools

[!IMPORTANT] command must point to the real executable. GUI clients often do not inherit shell aliases, PATH changes, or environment variables. Use an absolute path and prefer the default companies.json credential file.

Worker Filtering

The server exposes 502 tools across 33 App Store tool domains + 2 core domains. Some MCP clients impose a tool limit; Cascade in Devin Desktop currently allows 100 active tools. Use the 35 --workers filter keys to enable only the workers you need:

# Only load apps, builds, and version lifecycle tools
asc-mcp --workers apps,builds,versions

# App Store release preparation subset (99 tools, including always-on and build sub-workers)
asc-mcp --workers apps,accessibility,builds,export_compliance,versions,app_info,screenshots

# TestFlight review helpers can be loaded separately (49 tools)
asc-mcp --workers apps,builds,beta_app,pre_release

# Monetization focus
asc-mcp --workers apps,iap,subscriptions,pricing,promoted,review_submissions

company and auth workers are always enabled regardless of the filter (they provide core multi-account and authentication functionality).

When builds is enabled, it automatically includes build_processing and build_beta sub-workers.

Read-Only Mode

Use --read-only when you want safe inspection without App Store Connect mutations:

asc-mcp --read-only
asc-mcp --read-only --workers apps,builds,reviews,analytics

In this mode, read tools such as *_list, *_get, *_search, *_status, *_verify, *_parse, *_triage, auth_*, analytics, and metrics remain available. Tools that can create, update, upload, submit, release, delete, revoke, clear, cancel, or otherwise mutate App Store Connect are blocked before their worker handler runs. company_switch remains available because it changes only the local active company context.

OpenAPI Contract and Drift Tooling

Use the operation-contract command to compare the actual credential-free WorkerManager catalog with the semantic manifest and the pinned Apple App Store Connect OpenAPI specification. The production manifest records exact Apple operationId, HTTP method, path, invocation-scoped input bindings, typed fixed values, response lineage, local workflows, implementation state, deprecated aliases, and deliberately deferred operations. The command does not load App Store Connect credentials or start the MCP server.

rm -rf /tmp/asc-openapi
mkdir -p /tmp/asc-openapi
curl -L --fail -o /tmp/asc-openapi/spec.zip \
  https://developer.apple.com/sample-code/app-store-connect/app-store-connect-openapi-specification.zip
spec_entry="$(unzip -Z1 /tmp/asc-openapi/spec.zip | grep -E '(^|/)openapi\.oas[^/]*\.json$')"
test "$(echo "$spec_entry" | grep -c .)" -eq 1
unzip -p /tmp/asc-openapi/spec.zip "$spec_entry" > /tmp/asc-openapi/openapi.oas.json

swift run asc-mcp openapi-contract-check \
  --spec /tmp/asc-openapi/openapi.oas.json \
  --json-output /tmp/asc-openapi/operation-contract.json \
  --markdown-output /tmp/asc-openapi/operation-contract.md \
  --strict

The manifest is pinned to Apple API 4.4.1 by version, SHA-256, path count, and operation count. It currently maps 476 Apple operations, explicitly defers 424, and scopes out 363, covering all 1,263 operations without overlap. CI fails when the Apple document changes, a mapped operation moves or disappears, a public tool or worker drifts from the manifest, an input field loses its binding, response lineage becomes invalid, or a deferred decision expires. Unexposed optional Apple parameters are warnings so they remain visible in the generated backlog.

Manifest schema v2 also accounts for every optional Apple query and request-body input as publicly bound, internally controlled, intentionally omitted with a reviewed reason, or still unclassified. The checked-in optionalInputCoveragePin records the exact current totals and a SHA-256 digest of the sorted input identities and dispositions; --strict rejects a missing pin or any count- or identity-level drift. The pin makes phased remediation auditable and regression-safe, but it is not a claim that every optional Apple input is already public. The v4.1.3 pin is 2,905 total: 1,122 bound, 40 internally controlled, 1,743 intentionally omitted, and 0 unclassified. Its identity SHA-256 is c975f4e4eebb62ec87864a73fbf72bb8841f644108e54e6ffb25168bcf2a2766.

--strict is the merge- and tag-time release gate. Every declared target or broken tool remains an error in reports, and a regression test pins their exact state. The current baseline has no target or broken implementations and no implementation drift, so any implementation that leaves asBuilt, any structural contract error, or any optional-input coverage drift blocks both merges and releases. --structural-strict remains available only for local phased remediation work.

This gate proves operation identity, top-level MCP field ownership, required Apple inputs, typed internal values, and response source/pointer lineage. Full MCP type/enum/range parity and complete typed response schemas remain separate optimization phases; the current mapping status is 469 partial and 33 deprecated.

The older openapi-coverage command remains available for the high-level domain report in ASC-OPENAPI-COVERAGE-GENERATED.md. The operation contract is the authoritative release gate.

Available worker names:

Worker Prefix Tools Description
company company_ 3 Multi-account management
auth auth_ 4 JWT token tools
apps apps_ 10 App listing, metadata, localizations, search keyword IDs
accessibility accessibility_ 6 App Store accessibility declarations
webhooks webhooks_ 11 Webhook notifications, delivery diagnostics, and receiver helpers
xcode_cloud xcode_cloud_ 42 Xcode Cloud products, workflow management, build runs, artifacts, issues, test results, and SCM
builds builds_ 4 Build management
build_uploads build_uploads_ 10 Build upload parents, files, safe transfers, and recovery
build_processing builds_get_processing_*, builds_update_encryption, builds_check_readiness 4 Build states, encryption
export_compliance export_compliance_ 11 Encryption declarations, document uploads, build linkage, readiness
build_beta builds_*_beta_*, individual tester build tools 11 TestFlight localizations, notifications
versions app_versions_ 17 Version lifecycle, age ratings, submit, release
reviews reviews_ 8 Customer reviews and responses
beta_groups beta_groups_ 15 TestFlight groups and public-link recruitment criteria
beta_feedback beta_feedback_ 8 TestFlight feedback screenshots, crash submissions, crash logs
beta_testers beta_testers_ 12 Tester management
iap iap_ 59 In-app purchases, versioned metadata, pricing, availability, offer codes, review assets
subscriptions subscriptions_ 99 Subscription and group versions, pricing, plan availability, offers, assets
sandbox sandbox_ 3 Sandbox testers
beta_app beta_app_ 10 Beta app localizations and review
pre_release pre_release_ 3 Pre-release versions
beta_license beta_license_ 3 Beta license agreements
provisioning provisioning_ 17 Bundle IDs, devices, certificates
app_info app_info_ 10 App info, categories, EULA
pricing pricing_ 9 Territories, pricing
users users_ 10 Team members, roles
app_events app_events_ 9 In-app events, localizations
analytics analytics_ 11 Sales/financial reports, analytics
screenshots screenshots_ 19 Screenshots, previews, sets, and verified ordering
custom_pages custom_pages_ 17 Custom product pages, versions, localizations, and search keywords
ppo ppo_ 15 Product page optimization experiments, treatments, and localizations
promoted promoted_ 10 Promoted in-app purchases and verified ordering
review_attachments review_attachments_ 4 App Store review attachments
review_submissions review_submissions_ 9 Generic App Store review submissions and submission items
metrics metrics_ 9 Performance metrics, diagnostics, and TestFlight usage metrics

Tool Catalog Size

When an MCP client eagerly loads every tool definition, the approximate schema footprint is:

Configuration Tools ~Tokens
All workers (default) 502 ~60,000
Release workflow: apps,builds,export_compliance,versions,reviews ~72 ~8,900
Monetization: apps,iap,subscriptions,pricing 184 ~21,100
TestFlight: apps,builds,beta_groups,beta_testers ~63 ~7,100
Marketing: apps,screenshots,custom_pages,ppo,promoted ~78 ~8,800
--workers apps 17 ~2,100

Heaviest workers: Subscriptions (99 tools), InAppPurchases (59 tools), Xcode Cloud (42 tools), Screenshots (19 tools), Provisioning (17 tools).

Exact cost depends on the MCP host’s serialization, tokenizer, and tool-discovery strategy. Modern clients may defer schemas until they are needed. Use --workers when the client enforces a tool limit or when you want a smaller, more focused catalog.

Available Tools

502 tools organized across 33 App Store tool domains + 2 core domains (use the 35 --workers filter keys — see Worker Filtering):

Usage Examples

Complete Release Workflow

You: "Release version 2.2.0 of my app with build 456"

Claude will:
1. app_versions_create(app_id, platform: "IOS", version_string: "2.2.0")
2. app_versions_attach_build(version_id, build_id)
3. app_versions_set_review_details(version_id, contact_email: "...")
4. app_versions_submit_for_review(version_id)
5. app_versions_create_phased_release(version_id)  # after approval

TestFlight Distribution

You: "Create a beta group 'External Testers' and distribute the latest build"

Claude will:
1. beta_groups_create(app_id, name: "External Testers")
2. builds_list(app_id, limit: 1)  # find latest
3. builds_set_beta_localization(build_id, locale: "en-US", whats_new: "...")
4. beta_groups_add_testers(group_id, tester_ids: [...])

Review Management

You: "Show me all 1-star reviews from the last week and draft responses"

Claude will:
1. reviews_list(app_id, rating: 1, sort: "-createdDate", limit: 50)
2. reviews_create_response(review_id, response_body: "...")  # for each

Multi-Company Workflow

You: "Switch to ClientCorp and check their latest build status"

Claude will:
1. company_switch(company: "ClientCorp")
2. apps_list(limit: 5)
3. builds_list(app_id, limit: 1)
4. builds_get_processing_state(build_id)

API Constraints

Constraint Details
No emojis Metadata fields (What’s New, Description, Keywords) must not contain emoji characters
Version state App Store Connect validates editable states for metadata updates. Rejected and metadata-rejected versions can be edited for resubmission; published or in-review versions may be rejected by Apple.
JWT expiry Tokens expire after 20 minutes — the server auto-refreshes them
Rate limits Apple enforces per-account rate limits (documentation)
Locale format Use standard codes: en-US, ru, de-DE, ja, zh-Hans

Architecture

Sources/asc-mcp/
├── EntryPoint.swift                # Entry point, --workers filtering
├── Core/
│   ├── Application.swift           #   MCP server setup & initialization
│   └── ASCError.swift              #   Custom error types
├── Helpers/                        # JSON formatting, pagination, safe helpers
├── Models/                         # API request/response models
│   ├── AppStoreConnect/            #   Apps, versions, localizations
│   ├── Builds/                     #   Builds, beta details, beta groups
│   ├── AppLifecycle/               #   Version lifecycle models
│   ├── InAppPurchases/             #   IAP models
│   ├── Subscriptions/              #   Subscriptions, offer codes, win-back
│   ├── Marketing/                  #   Screenshots, custom pages, PPO, promoted
│   ├── Metrics/                    #   Performance metrics, diagnostics
│   ├── Analytics/                  #   Sales/financial reports
│   ├── Provisioning/               #   Bundle IDs, devices, certificates
│   ├── Shared/                     #   Shared upload/image types
│   └── ...                         #   AppEvents, AppInfo, Pricing, Users
├── Services/
│   ├── HTTPClient.swift            #   Actor-based HTTP with retry logic
│   ├── JWTService.swift            #   ES256 JWT token generation
│   └── CompaniesManager.swift      #   Multi-account management
└── Workers/                        # MCP tool implementations (39 Swift worker classes + MainWorker router)
    ├── MainWorker/WorkerManager    #   Central tool registry & routing
    ├── CompaniesWorker/            #   company_* tools
    ├── AuthWorker/                 #   auth_* tools
    ├── AppsWorker/                 #   apps_* tools
    ├── AccessibilityWorker/        #   accessibility_* tools
    ├── WebhooksWorker/             #   webhooks_* tools
    ├── XcodeCloudWorker/           #   xcode_cloud_* tools
    ├── BuildsWorker/               #   builds_* tools
    ├── BuildUploadsWorker/         #   build_uploads_* tools
    ├── BuildProcessingWorker/      #   builds_*_processing tools
    ├── ExportComplianceWorker/     #   export_compliance_* tools
    ├── BuildBetaDetailsWorker/     #   builds_*_beta_* tools
    ├── AppLifecycleWorker/         #   app_versions_* tools
    ├── ReviewsWorker/              #   reviews_* tools
    ├── BetaGroupsWorker/           #   beta_groups_* tools
    ├── BetaFeedbackWorker/         #   beta_feedback_* tools
    ├── BetaTestersWorker/          #   beta_testers_* tools
    ├── InAppPurchasesWorker/       #   iap_* tools
    ├── SubscriptionsWorker/        #   subscriptions_* tools
    ├── OfferCodesWorker/           #   subscriptions offer-code tools
    ├── IntroductoryOffersWorker/   #   subscriptions intro-offer tools
    ├── PromotionalOffersWorker/    #   subscriptions promotional-offer tools
    ├── WinBackOffersWorker/        #   subscriptions win-back tools
    ├── SandboxTestersWorker/       #   sandbox_* tools
    ├── BetaAppWorker/              #   beta_app_* tools
    ├── PreReleaseVersionsWorker/   #   pre_release_* tools
    ├── BetaLicenseAgreementsWorker/ #  beta_license_* tools
    ├── ProvisioningWorker/         #   provisioning_* tools
    ├── AppInfoWorker/              #   app_info_* tools
    ├── PricingWorker/              #   pricing_* tools
    ├── UsersWorker/                #   users_* tools
    ├── AppEventsWorker/            #   app_events_* tools
    ├── AnalyticsWorker/            #   analytics_* tools
    ├── ScreenshotsWorker/          #   screenshots_* tools
    ├── CustomProductPagesWorker/   #   custom_pages_* tools
    ├── ProductPageOptimizationWorker/ # ppo_* tools
    ├── PromotedPurchasesWorker/    #   promoted_* tools
    ├── ReviewAttachmentsWorker/    #   review_attachments_* tools
    ├── ReviewSubmissionsWorker/    #   review_submissions_* tools
    └── MetricsWorker/              #   metrics_* tools

Design Principles

  • Swift 6 strict concurrency — all workers and services are Sendable, proper actor isolation
  • Actor-based HTTP client — thread-safe with exponential backoff and retry logic
  • Prefix-based routing — WorkerManager routes tool calls by name prefix (zero config)
  • Minimal dependencies — only the MCP Swift SDK

Troubleshooting

Getting Help

Before opening a report, search the existing issues. If the problem is new, open an issue and include:

  • macOS version and installation method;
  • MCP client name and version;
  • the selected --workers value, if any;
  • the exact error message and the smallest reproducible request.

Remove Key IDs, Issuer IDs, private keys, signed URLs, tokens, and account data from logs before posting them. Report security vulnerabilities privately by following SECURITY.md. For code contributions, see CONTRIBUTING.md.

Development

Building

swift build              # Debug build
swift build -c release   # Release build (optimized)
swift package clean      # Clean build artifacts

Test Mode

.build/debug/asc-mcp --test    # Runs built-in integration tests

Adding a New Tool

  1. Create handler method in the appropriate Worker+Handlers.swift
  2. Add tool definition in Worker+ToolDefinitions.swift
  3. Register in worker’s getTools() method
  4. Add routing case in worker’s handleTool() switch
  5. The WorkerManager auto-routes by prefix — no changes needed there

Adding a New Worker

  1. Create directory: Workers/MyWorker/
  2. Create 3 files: MyWorker.swift, MyWorker+ToolDefinitions.swift, MyWorker+Handlers.swift
  3. Add worker property and initialization in WorkerManager.swift
  4. Add routing rule in WorkerManager.registerWorkers()
  5. Add getMyTools() helper method

Contributing

We welcome contributions! See Contributing Guide for details.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Acknowledgments


This is an unofficial, community-maintained tool and is not affiliated with or endorsed by Apple Inc.

View this README on GitHub

설치

This server does not publish a one-line install command.

Open the repository installation guide

설정

{ "mcpServers": { "asc-mcp": { "command": "/Users/you/.mint/bin/asc-mcp" } } }