Install
$ agentstack add mcp-sardorbekr-appstore-connect-mcp ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v1.0.4 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v1.0.4. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
App Store Connect MCP Server
[](https://www.npmjs.com/package/asc-mcp) [](https://opensource.org/licenses/MIT) [](https://nodejs.org)
A Model Context Protocol (MCP) server for Apple's App Store Connect API. Manage your iOS, macOS, tvOS, and visionOS apps directly from Claude, Cursor, or any MCP-compatible client.
Features
- App Store Localizations - Full CRUD for version descriptions, keywords, and what's new
- App Management - List and inspect apps across all platforms
- Version Control - Create and manage app store versions
- Beta Testing - Manage TestFlight groups and testers
- Screenshot Management - Upload and organize app screenshots
- Bundle ID Management - Full CRUD for bundle identifiers
- Device Management - List and inspect registered devices
- User Management - List and inspect team users
- Build Management - List and inspect app builds
- Category & Pricing - Browse categories, check pricing and availability
- Pricing & PPP - Set per-territory pricing with Purchase Power Parity support
- In-App Purchases - Create and manage one-time purchases (lifetime/non-consumable, consumable, non-renewing): metadata, localization, pricing & PPP, availability, and review submission (review-screenshot upload excluded)
- Analytics Reports - Request and download app analytics reports (engagement, commerce, usage, performance)
- Sales & Finance - Download sales, trends, and financial reports
- Performance & Diagnostics - App/build power & performance metrics and diagnostic logs
- Secure by Default - ES256 JWT auth with automatic token refresh, credential redaction in logs
Table of Contents
- [Quick Start](#quick-start)
- [Installation](#installation)
- [Configuration](#configuration)
- [Available Tools](#available-tools)
- [Usage Examples](#usage-examples)
- [Security](#security)
- [Troubleshooting](#troubleshooting)
- [Development](#development)
- [License](#license)
Quick Start
# 1. Install
npm install -g asc-mcp
# 2. Set credentials (get from App Store Connect > Users and Access > Keys)
export APP_STORE_CONNECT_KEY_ID="YOUR_KEY_ID"
export APP_STORE_CONNECT_ISSUER_ID="YOUR_ISSUER_ID"
export APP_STORE_CONNECT_P8_PATH="/path/to/AuthKey.p8"
# 3. Add to your MCP client config and start using!
Installation
npm (recommended)
npm install -g asc-mcp
Using npx
npx asc-mcp
From Source
git clone https://github.com/SardorbekR/appstore-connect-mcp.git
cd appstore-connect-mcp
npm install
npm run build
Configuration
Prerequisites: Get Your Apple API Credentials
- Sign in to App Store Connect
- Go to Users and Access → Integrations → App Store Connect API
- Click Generate API Key (or use existing)
- Select appropriate role (Admin or App Manager recommended)
- Download the .p8 file - you can only download it once!
- Note your Key ID (shown in the keys list)
- Note your Issuer ID (shown at the top of the page)
Environment Variables
| Variable | Required | Description | |----------|----------|-------------| | APP_STORE_CONNECT_KEY_ID | Yes | Your API Key ID (e.g., ABC123DEFG) | | APP_STORE_CONNECT_ISSUER_ID | Yes | Your Issuer ID (UUID format) | | APP_STORE_CONNECT_P8_PATH | Yes | Path to your .p8 private key file | | APP_STORE_CONNECT_P8_CONTENT | Yes | Raw content of .p8 key (alternative to path) |
*One of P8_PATH or P8_CONTENT is required.
MCP Client Configuration
Claude Desktop
Add to your Claude Desktop config file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"app-store-connect": {
"command": "asc-mcp",
"env": {
"APP_STORE_CONNECT_KEY_ID": "YOUR_KEY_ID",
"APP_STORE_CONNECT_ISSUER_ID": "YOUR_ISSUER_ID",
"APP_STORE_CONNECT_P8_PATH": "/absolute/path/to/AuthKey.p8"
}
}
}
}
Cursor
Add to your Cursor MCP settings (Settings → MCP Servers):
{
"mcpServers": {
"app-store-connect": {
"command": "npx",
"args": ["-y", "asc-mcp"],
"env": {
"APP_STORE_CONNECT_KEY_ID": "YOUR_KEY_ID",
"APP_STORE_CONNECT_ISSUER_ID": "YOUR_ISSUER_ID",
"APP_STORE_CONNECT_P8_PATH": "/absolute/path/to/AuthKey.p8"
}
}
}
}
VS Code with Continue
Add to your Continue configuration:
{
"mcpServers": {
"app-store-connect": {
"command": "asc-mcp",
"env": {
"APP_STORE_CONNECT_KEY_ID": "YOUR_KEY_ID",
"APP_STORE_CONNECT_ISSUER_ID": "YOUR_ISSUER_ID",
"APP_STORE_CONNECT_P8_PATH": "/absolute/path/to/AuthKey.p8"
}
}
}
}
Using P8 Content Instead of Path
For CI/CD or containerized environments, you can pass the key content directly:
{
"mcpServers": {
"app-store-connect": {
"command": "asc-mcp",
"env": {
"APP_STORE_CONNECT_KEY_ID": "YOUR_KEY_ID",
"APP_STORE_CONNECT_ISSUER_ID": "YOUR_ISSUER_ID",
"APP_STORE_CONNECT_P8_CONTENT": "-----BEGIN PRIVATE KEY-----\nMIGT...your key here...AB12\n-----END PRIVATE KEY-----"
}
}
}
}
Available Tools
Apps
| Tool | Description | Parameters | |------|-------------|------------| | list_apps | List all apps in your account | limit? (number, 1-200) | | get_app | Get details of a specific app | appId (string, required) |
Versions
| Tool | Description | Parameters | |------|-------------|------------| | list_app_versions | List all versions for an app | appId, platform?, versionState?, limit? | | get_app_version | Get version details | versionId | | create_app_version | Create a new app version | appId, platform, versionString, releaseType? |
Version Localizations
| Tool | Description | Parameters | |------|-------------|------------| | list_version_localizations | List localizations for a version | versionId, limit? | | get_version_localization | Get localization details | localizationId | | create_version_localization | Add a new locale | versionId, locale, description?, keywords?, whatsNew? | | update_version_localization | Update localization | localizationId, description?, keywords?, whatsNew?, promotionalText? | | delete_version_localization | Remove a locale | localizationId |
App Info Localizations
| Tool | Description | Parameters | |------|-------------|------------| | list_app_infos | List app info records | appId, limit? | | list_app_info_localizations | List name/subtitle localizations | appInfoId, limit? | | update_app_info_localization | Update app name, subtitle | localizationId, name?, subtitle?, privacyPolicyUrl? |
Beta Testing (TestFlight)
| Tool | Description | Parameters | |------|-------------|------------| | list_beta_groups | List beta groups for an app | appId, limit? | | list_beta_testers | List testers in a group | betaGroupId, limit? | | add_beta_tester | Add a tester to a group | betaGroupId, email, firstName?, lastName? | | remove_beta_tester | Remove a tester from a group | betaGroupId, betaTesterId |
Screenshots
| Tool | Description | Parameters | |------|-------------|------------| | list_screenshot_sets | List screenshot sets | localizationId, limit? | | list_screenshots | List screenshots in a set | screenshotSetId, limit? | | upload_screenshot | Upload a new screenshot | screenshotSetId, fileName, fileSize, filePath |
Bundle IDs
| Tool | Description | Parameters | |------|-------------|------------| | list_bundle_ids | List all bundle IDs | limit?, platform? | | get_bundle_id | Get bundle ID details | bundleIdId | | create_bundle_id | Register a new bundle ID | identifier, name, platform | | update_bundle_id | Update bundle ID name | bundleIdId, name | | delete_bundle_id | Delete a bundle ID | bundleIdId |
Devices
| Tool | Description | Parameters | |------|-------------|------------| | list_devices | List registered devices | limit?, platform?, status? | | get_device | Get device details | deviceId |
Users
| Tool | Description | Parameters | |------|-------------|------------| | list_users | List team users | limit?, roles? | | get_user | Get user details | userId |
Builds
| Tool | Description | Parameters | |------|-------------|------------| | list_builds | List builds for an app | appId, limit? | | get_build | Get build details | buildId |
Categories & Pricing
| Tool | Description | Parameters | |------|-------------|------------| | list_app_categories | List app categories | limit?, platform? | | get_app_price_schedule | Get app pricing info | appId | | get_app_availability | Get app territory availability | appId |
Pricing (PPP)
| Tool | Description | Parameters | |------|-------------|------------| | list_territories | List all territories with currencies | limit? | | list_app_price_points | List available price tiers for an app | appId, territory?, limit? | | get_price_point_equalizations | Get PPP equivalent prices across countries | pricePointId, territories?, limit? | | set_app_prices | Set per-territory manual pricing (replaces entire schedule) | appId, baseTerritory, manualPrices |
In-App Purchases (Lifetime / Non-Consumable)
One-time purchases via Apple's In-App Purchases v2 API. create_in_app_purchase defaults to NON_CONSUMABLE — a "lifetime" unlock. To ship one: create → add a localization → set a price → set availability → submit for review.
> Note: App Review usually requires a review screenshot on the in-app purchase. Uploading IAP review screenshots is not yet covered by these tools — add one in App Store Connect if submit_in_app_purchase_for_review is rejected for a missing screenshot.
| Tool | Description | Parameters | |------|-------------|------------| | list_in_app_purchases | List an app's in-app purchases, optionally by type | appId, inAppPurchaseType?, limit? | | get_in_app_purchase | Get a single in-app purchase's details and state | inAppPurchaseId | | create_in_app_purchase | Create an IAP (defaults to NON_CONSUMABLE / lifetime) | appId, name, productId, inAppPurchaseType?, familySharable?, reviewNote? | | update_in_app_purchase | Update name, Family Sharing, or review note (productId/type immutable) | inAppPurchaseId, name?, familySharable?, reviewNote? | | delete_in_app_purchase | Delete an in-app purchase | inAppPurchaseId | | list_in_app_purchase_localizations | List localized names/descriptions | inAppPurchaseId, limit? | | create_in_app_purchase_localization | Add a localized display name (+ description) | inAppPurchaseId, locale, name, description? | | update_in_app_purchase_localization | Update a localization | localizationId, name?, description? | | delete_in_app_purchase_localization | Delete a localization | localizationId | | list_in_app_purchase_price_points | List price points (customer price & proceeds) | inAppPurchaseId, territory?, limit?, offset? | | get_in_app_purchase_price_point_equalizations | Apple's PPP-equivalent price points for a base price point | pricePointId, territories?, limit? | | set_in_app_purchase_price | Set pricing (replaces schedule; one base territory to auto-equalize, or full PPP list) | inAppPurchaseId, baseTerritory, manualPrices | | list_in_app_purchase_prices | Read current per-territory prices (manual; optional automatic) | inAppPurchaseId, territory?, includeAutomatic?, limit? | | get_in_app_purchase_availability | Get territory availability | inAppPurchaseId | | set_in_app_purchase_availability | Set territory availability | inAppPurchaseId, availableInNewTerritories, territories? | | submit_in_app_purchase_for_review | Submit the IAP to App Review (independent of an app version) | inAppPurchaseId |
Analytics Reports
| Tool | Description | Parameters | |------|-------------|------------| | create_analytics_report_request | Request an analytics report (ongoing or one-time snapshot) | appId, accessType | | list_analytics_report_requests | List analytics report requests for an app | appId | | get_analytics_report_request | Get an analytics report request | requestId | | delete_analytics_report_request | Delete an analytics report request | requestId | | list_analytics_reports | List reports available within a request | requestId | | list_analytics_report_instances | List instances (by date) of a report | reportId | | list_analytics_report_segments | List downloadable segments of a report instance | instanceId | | download_analytics_report_segment | Download a report segment | url |
Sales & Finance
| Tool | Description | Parameters | |------|-------------|------------| | get_sales_report | Download a sales/trends report | vendorNumber, reportType, reportSubType, frequency, reportDate | | get_finance_report | Download a financial report | vendorNumber, regionCode, reportDate, reportType |
Performance & Diagnostics
| Tool | Description | Parameters | |------|-------------|------------| | get_app_perf_metrics | Get an app's power & performance metrics | appId, metricType | | get_build_perf_metrics | Get a build's performance metrics | buildId, metricType | | list_diagnostic_signatures | List diagnostic signatures for a build | buildId | | list_diagnostic_logs | List diagnostic logs for a signature | signatureId |
Usage Examples
List Your Apps
> "Show me all my apps in App Store Connect"
Claude will use list_apps to retrieve and display your apps.
Update App Description
> "Update the English description for version 2.0 of MyApp to: 'A revolutionary app that simplifies your daily tasks.'"
Claude will:
- Find the app using
list_apps - Get the version using
list_app_versions - Find the English localization using
list_version_localizations - Update it using
update_version_localization
Add Japanese Localization
> "Add Japanese localization to MyApp version 2.0 with description '素晴らしいアプリです' and keywords 'アプリ,便利,簡単'"
Claude will use create_version_localization with locale ja.
Add a Beta Tester
> "Add john@example.com as a beta tester to the Internal Testing group for MyApp"
Claude will:
- Find the app and beta group using
list_beta_groups - Add the tester using
add_beta_tester
Set PPP Pricing
> "Show me the equivalent prices for my $9.99 tier in India, Brazil, and Turkey"
Claude will:
- Find the $9.99 price point using
list_app_price_points - Get equivalent prices using
get_price_point_equalizations - Show you the PPP-adjusted prices in each territory
> "Set my app to $9.99 in the US and use PPP pricing for India and Brazil"
Claude will use set_app_prices with the appropriate price point IDs for each territory.
Create a Lifetime Purchase
> "Add a $99.99 lifetime unlock to MyApp with PPP pricing for India and Brazil"
Claude will:
- Create a non-consumable IAP with
create_in_app_purchase - Add a display name with
create_in_app_purchase_localization - Find the $99.99 tier with
list_in_app_purchase_price_points, then PPP equivalents withget_in_app_purchase_price_point_equalizations - Apply per-territory pricing with
set_in_app_purchase_priceand open availability withset_in_app_purchase_availability - Confirm the result with
list_in_app_purchase_prices
Check Version Status
> "What's the status of all versions of MyApp?"
Claude will use list_app_versions to show version states (PREPAREFORSUBMISSION, INREVIEW, READYFOR_SALE, etc.)
Securi
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: SardorbekR
- Source: SardorbekR/appstore-connect-mcp
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v1.0.4 Imported from the upstream source.