{
  "markdown": "# App Store Connect MCP Server\n\n[![npm version](https://img.shields.io/npm/v/asc-mcp.svg)](https://www.npmjs.com/package/asc-mcp)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Node.js Version](https://img.shields.io/node/v/asc-mcp.svg)](https://nodejs.org)\n\nA 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.\n\n## Features\n\n- **App Store Localizations** - Full CRUD for version descriptions, keywords, and what's new\n- **App Management** - List and inspect apps across all platforms\n- **Version Control** - Create and manage app store versions\n- **Beta Testing** - Manage TestFlight groups and testers\n- **Screenshot Management** - Upload and organize app screenshots\n- **Bundle ID Management** - Full CRUD for bundle identifiers\n- **Device Management** - List and inspect registered devices\n- **User Management** - List and inspect team users\n- **Build Management** - List and inspect app builds\n- **Category & Pricing** - Browse categories, check pricing and availability\n- **Pricing & PPP** - Set per-territory pricing with Purchase Power Parity support\n- **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)\n- **Analytics Reports** - Request and download app analytics reports (engagement, commerce, usage, performance)\n- **Sales & Finance** - Download sales, trends, and financial reports\n- **Performance & Diagnostics** - App/build power & performance metrics and diagnostic logs\n- **Secure by Default** - ES256 JWT auth with automatic token refresh, credential redaction in logs\n\n## Table of Contents\n\n- [Quick Start](#quick-start)\n- [Installation](#installation)\n- [Configuration](#configuration)\n- [Available Tools](#available-tools)\n- [Usage Examples](#usage-examples)\n- [Security](#security)\n- [Troubleshooting](#troubleshooting)\n- [Development](#development)\n- [License](#license)\n\n## Quick Start\n\n```bash\n# 1. Install\nnpm install -g asc-mcp\n\n# 2. Set credentials (get from App Store Connect > Users and Access > Keys)\nexport APP_STORE_CONNECT_KEY_ID=\"YOUR_KEY_ID\"\nexport APP_STORE_CONNECT_ISSUER_ID=\"YOUR_ISSUER_ID\"\nexport APP_STORE_CONNECT_P8_PATH=\"/path/to/AuthKey.p8\"\n\n# 3. Add to your MCP client config and start using!\n```\n\n## Installation\n\n### npm (recommended)\n\n```bash\nnpm install -g asc-mcp\n```\n\n### Using npx\n\n```bash\nnpx asc-mcp\n```\n\n### From Source\n\n```bash\ngit clone https://github.com/SardorbekR/appstore-connect-mcp.git\ncd appstore-connect-mcp\nnpm install\nnpm run build\n```\n\n## Configuration\n\n### Prerequisites: Get Your Apple API Credentials\n\n1. Sign in to [App Store Connect](https://appstoreconnect.apple.com)\n2. Go to **Users and Access** → **Integrations** → **App Store Connect API**\n3. Click **Generate API Key** (or use existing)\n4. Select appropriate role (Admin or App Manager recommended)\n5. **Download the .p8 file** - you can only download it once!\n6. Note your **Key ID** (shown in the keys list)\n7. Note your **Issuer ID** (shown at the top of the page)\n\n### Environment Variables\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `APP_STORE_CONNECT_KEY_ID` | Yes | Your API Key ID (e.g., `ABC123DEFG`) |\n| `APP_STORE_CONNECT_ISSUER_ID` | Yes | Your Issuer ID (UUID format) |\n| `APP_STORE_CONNECT_P8_PATH` | Yes* | Path to your `.p8` private key file |\n| `APP_STORE_CONNECT_P8_CONTENT` | Yes* | Raw content of `.p8` key (alternative to path) |\n\n*One of `P8_PATH` or `P8_CONTENT` is required.\n\n### MCP Client Configuration\n\n<details>\n<summary><strong>Claude Desktop</strong></summary>\n\nAdd to your Claude Desktop config file:\n\n**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`\n**Windows:** `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n```json\n{\n  \"mcpServers\": {\n    \"app-store-connect\": {\n      \"command\": \"asc-mcp\",\n      \"env\": {\n        \"APP_STORE_CONNECT_KEY_ID\": \"YOUR_KEY_ID\",\n        \"APP_STORE_CONNECT_ISSUER_ID\": \"YOUR_ISSUER_ID\",\n        \"APP_STORE_CONNECT_P8_PATH\": \"/absolute/path/to/AuthKey.p8\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><strong>Cursor</strong></summary>\n\nAdd to your Cursor MCP settings (Settings → MCP Servers):\n\n```json\n{\n  \"mcpServers\": {\n    \"app-store-connect\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"asc-mcp\"],\n      \"env\": {\n        \"APP_STORE_CONNECT_KEY_ID\": \"YOUR_KEY_ID\",\n        \"APP_STORE_CONNECT_ISSUER_ID\": \"YOUR_ISSUER_ID\",\n        \"APP_STORE_CONNECT_P8_PATH\": \"/absolute/path/to/AuthKey.p8\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><strong>VS Code with Continue</strong></summary>\n\nAdd to your Continue configuration:\n\n```json\n{\n  \"mcpServers\": {\n    \"app-store-connect\": {\n      \"command\": \"asc-mcp\",\n      \"env\": {\n        \"APP_STORE_CONNECT_KEY_ID\": \"YOUR_KEY_ID\",\n        \"APP_STORE_CONNECT_ISSUER_ID\": \"YOUR_ISSUER_ID\",\n        \"APP_STORE_CONNECT_P8_PATH\": \"/absolute/path/to/AuthKey.p8\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><strong>Using P8 Content Instead of Path</strong></summary>\n\nFor CI/CD or containerized environments, you can pass the key content directly:\n\n```json\n{\n  \"mcpServers\": {\n    \"app-store-connect\": {\n      \"command\": \"asc-mcp\",\n      \"env\": {\n        \"APP_STORE_CONNECT_KEY_ID\": \"YOUR_KEY_ID\",\n        \"APP_STORE_CONNECT_ISSUER_ID\": \"YOUR_ISSUER_ID\",\n        \"APP_STORE_CONNECT_P8_CONTENT\": \"-----BEGIN PRIVATE KEY-----\\nMIGT...your key here...AB12\\n-----END PRIVATE KEY-----\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n## Available Tools\n\n### Apps\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_apps` | List all apps in your account | `limit?` (number, 1-200) |\n| `get_app` | Get details of a specific app | `appId` (string, required) |\n\n### Versions\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_app_versions` | List all versions for an app | `appId`, `platform?`, `versionState?`, `limit?` |\n| `get_app_version` | Get version details | `versionId` |\n| `create_app_version` | Create a new app version | `appId`, `platform`, `versionString`, `releaseType?` |\n\n### Version Localizations\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_version_localizations` | List localizations for a version | `versionId`, `limit?` |\n| `get_version_localization` | Get localization details | `localizationId` |\n| `create_version_localization` | Add a new locale | `versionId`, `locale`, `description?`, `keywords?`, `whatsNew?` |\n| `update_version_localization` | Update localization | `localizationId`, `description?`, `keywords?`, `whatsNew?`, `promotionalText?` |\n| `delete_version_localization` | Remove a locale | `localizationId` |\n\n### App Info Localizations\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_app_infos` | List app info records | `appId`, `limit?` |\n| `list_app_info_localizations` | List name/subtitle localizations | `appInfoId`, `limit?` |\n| `update_app_info_localization` | Update app name, subtitle | `localizationId`, `name?`, `subtitle?`, `privacyPolicyUrl?` |\n\n### Beta Testing (TestFlight)\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_beta_groups` | List beta groups for an app | `appId`, `limit?` |\n| `list_beta_testers` | List testers in a group | `betaGroupId`, `limit?` |\n| `add_beta_tester` | Add a tester to a group | `betaGroupId`, `email`, `firstName?`, `lastName?` |\n| `remove_beta_tester` | Remove a tester from a group | `betaGroupId`, `betaTesterId` |\n\n### Screenshots\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_screenshot_sets` | List screenshot sets | `localizationId`, `limit?` |\n| `list_screenshots` | List screenshots in a set | `screenshotSetId`, `limit?` |\n| `upload_screenshot` | Upload a new screenshot | `screenshotSetId`, `fileName`, `fileSize`, `filePath` |\n\n### Bundle IDs\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_bundle_ids` | List all bundle IDs | `limit?`, `platform?` |\n| `get_bundle_id` | Get bundle ID details | `bundleIdId` |\n| `create_bundle_id` | Register a new bundle ID | `identifier`, `name`, `platform` |\n| `update_bundle_id` | Update bundle ID name | `bundleIdId`, `name` |\n| `delete_bundle_id` | Delete a bundle ID | `bundleIdId` |\n\n### Devices\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_devices` | List registered devices | `limit?`, `platform?`, `status?` |\n| `get_device` | Get device details | `deviceId` |\n\n### Users\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_users` | List team users | `limit?`, `roles?` |\n| `get_user` | Get user details | `userId` |\n\n### Builds\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_builds` | List builds for an app | `appId`, `limit?` |\n| `get_build` | Get build details | `buildId` |\n\n### Categories & Pricing\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_app_categories` | List app categories | `limit?`, `platform?` |\n| `get_app_price_schedule` | Get app pricing info | `appId` |\n| `get_app_availability` | Get app territory availability | `appId` |\n\n### Pricing (PPP)\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_territories` | List all territories with currencies | `limit?` |\n| `list_app_price_points` | List available price tiers for an app | `appId`, `territory?`, `limit?` |\n| `get_price_point_equalizations` | Get PPP equivalent prices across countries | `pricePointId`, `territories?`, `limit?` |\n| `set_app_prices` | Set per-territory manual pricing (replaces entire schedule) | `appId`, `baseTerritory`, `manualPrices` |\n\n### In-App Purchases (Lifetime / Non-Consumable)\n\nOne-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.\n\n> **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.\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `list_in_app_purchases` | List an app's in-app purchases, optionally by type | `appId`, `inAppPurchaseType?`, `limit?` |\n| `get_in_app_purchase` | Get a single in-app purchase's details and state | `inAppPurchaseId` |\n| `create_in_app_purchase` | Create an IAP (defaults to NON_CONSUMABLE / lifetime) | `appId`, `name`, `productId`, `inAppPurchaseType?`, `familySharable?`, `reviewNote?` |\n| `update_in_app_purchase` | Update name, Family Sharing, or review note (productId/type immutable) | `inAppPurchaseId`, `name?`, `familySharable?`, `reviewNote?` |\n| `delete_in_app_purchase` | Delete an in-app purchase | `inAppPurchaseId` |\n| `list_in_app_purchase_localizations` | List localized names/descriptions | `inAppPurchaseId`, `limit?` |\n| `create_in_app_purchase_localization` | Add a localized display name (+ description) | `inAppPurchaseId`, `locale`, `name`, `description?` |\n| `update_in_app_purchase_localization` | Update a localization | `localizationId`, `name?`, `description?` |\n| `delete_in_app_purchase_localization` | Delete a localization | `localizationId` |\n| `list_in_app_purchase_price_points` | List price points (customer price & proceeds) | `inAppPurchaseId`, `territory?`, `limit?`, `offset?` |\n| `get_in_app_purchase_price_point_equalizations` | Apple's PPP-equivalent price points for a base price point | `pricePointId`, `territories?`, `limit?` |\n| `set_in_app_purchase_price` | Set pricing (replaces schedule; one base territory to auto-equalize, or full PPP list) | `inAppPurchaseId`, `baseTerritory`, `manualPrices` |\n| `list_in_app_purchase_prices` | Read current per-territory prices (manual; optional automatic) | `inAppPurchaseId`, `territory?`, `includeAutomatic?`, `limit?` |\n| `get_in_app_purchase_availability` | Get territory availability | `inAppPurchaseId` |\n| `set_in_app_purchase_availability` | Set territory availability | `inAppPurchaseId`, `availableInNewTerritories`, `territories?` |\n| `submit_in_app_purchase_for_review` | Submit the IAP to App Review (independent of an app version) | `inAppPurchaseId` |\n\n### Analytics Reports\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `create_analytics_report_request` | Request an analytics report (ongoing or one-time snapshot) | `appId`, `accessType` |\n| `list_analytics_report_requests` | List analytics report requests for an app | `appId` |\n| `get_analytics_report_request` | Get an analytics report request | `requestId` |\n| `delete_analytics_report_request` | Delete an analytics report request | `requestId` |\n| `list_analytics_reports` | List reports available within a request | `requestId` |\n| `list_analytics_report_instances` | List instances (by date) of a report | `reportId` |\n| `list_analytics_report_segments` | List downloadable segments of a report instance | `instanceId` |\n| `download_analytics_report_segment` | Download a report segment | `url` |\n\n### Sales & Finance\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `get_sales_report` | Download a sales/trends report | `vendorNumber`, `reportType`, `reportSubType`, `frequency`, `reportDate` |\n| `get_finance_report` | Download a financial report | `vendorNumber`, `regionCode`, `reportDate`, `reportType` |\n\n### Performance & Diagnostics\n\n| Tool | Description | Parameters |\n|------|-------------|------------|\n| `get_app_perf_metrics` | Get an app's power & performance metrics | `appId`, `metricType` |\n| `get_build_perf_metrics` | Get a build's performance metrics | `buildId`, `metricType` |\n| `list_diagnostic_signatures` | List diagnostic signatures for a build | `buildId` |\n| `list_diagnostic_logs` | List diagnostic logs for a signature | `signatureId` |\n\n## Usage Examples\n\n### List Your Apps\n\n> \"Show me all my apps in App Store Connect\"\n\nClaude will use `list_apps` to retrieve and display your apps.\n\n### Update App Description\n\n> \"Update the English description for version 2.0 of MyApp to: 'A revolutionary app that simplifies your daily tasks.'\"\n\nClaude will:\n1. Find the app using `list_apps`\n2. Get the version using `list_app_versions`\n3. Find the English localization using `list_version_localizations`\n4. Update it using `update_version_localization`\n\n### Add Japanese Localization\n\n> \"Add Japanese localization to MyApp version 2.0 with description '素晴らしいアプリです' and keywords 'アプリ,便利,簡単'\"\n\nClaude will use `create_version_localization` with locale `ja`.\n\n### Add a Beta Tester\n\n> \"Add john@example.com as a beta tester to the Internal Testing group for MyApp\"\n\nClaude will:\n1. Find the app and beta group using `list_beta_groups`\n2. Add the tester using `add_beta_tester`\n\n### Set PPP Pricing\n\n> \"Show me the equivalent prices for my $9.99 tier in India, Brazil, and Turkey\"\n\nClaude will:\n1. Find the $9.99 price point using `list_app_price_points`\n2. Get equivalent prices using `get_price_point_equalizations`\n3. Show you the PPP-adjusted prices in each territory\n\n> \"Set my app to $9.99 in the US and use PPP pricing for India and Brazil\"\n\nClaude will use `set_app_prices` with the appropriate price point IDs for each territory.\n\n### Create a Lifetime Purchase\n\n> \"Add a $99.99 lifetime unlock to MyApp with PPP pricing for India and Brazil\"\n\nClaude will:\n1. Create a non-consumable IAP with `create_in_app_purchase`\n2. Add a display name with `create_in_app_purchase_localization`\n3. Find the $99.99 tier with `list_in_app_purchase_price_points`, then PPP equivalents with `get_in_app_purchase_price_point_equalizations`\n4. Apply per-territory pricing with `set_in_app_purchase_price` and open availability with `set_in_app_purchase_availability`\n5. Confirm the result with `list_in_app_purchase_prices`\n\n### Check Version Status\n\n> \"What's the status of all versions of MyApp?\"\n\nClaude will use `list_app_versions` to show version states (PREPARE_FOR_SUBMISSION, IN_REVIEW, READY_FOR_SALE, etc.)\n\n## Security\n\n### Credential Handling\n\n- **Private keys** are never logged or exposed in error messages\n- **JWT tokens** are automatically redacted from any error output\n- **Issuer IDs** (UUIDs) are redacted from logs\n- Token caching minimizes key usage (15-min tokens, refreshed at 10 min)\n\n### Path Validation\n\n- P8 file paths are validated against directory traversal attacks (`..` not allowed)\n- Only absolute paths are resolved\n\n### Best Practices\n\n1. **Never commit credentials** - Use environment variables or a secrets manager\n2. **Restrict API key permissions** - Use minimal required role (App Manager for most operations)\n3. **Rotate keys periodically** - Generate new API keys and revoke old ones\n4. **Secure your .p8 file** - Set file permissions to `600` (owner read/write only)\n\n```bash\nchmod 600 /path/to/AuthKey.p8\n```\n\n## Troubleshooting\n\n### \"Configuration error: APP_STORE_CONNECT_KEY_ID environment variable is required\"\n\nEnsure all required environment variables are set:\n- `APP_STORE_CONNECT_KEY_ID`\n- `APP_STORE_CONNECT_ISSUER_ID`\n- `APP_STORE_CONNECT_P8_PATH` or `APP_STORE_CONNECT_P8_CONTENT`\n\n### \"Failed to read private key\"\n\n1. Verify the path in `APP_STORE_CONNECT_P8_PATH` is correct and absolute\n2. Check file permissions: `ls -la /path/to/AuthKey.p8`\n3. Ensure the file is a valid `.p8` from Apple (starts with `-----BEGIN PRIVATE KEY-----`)\n\n### \"Authentication failed\"\n\nThis usually means:\n1. The API key was revoked in App Store Connect\n2. The Key ID or Issuer ID doesn't match the .p8 file\n3. The .p8 file is corrupted or incomplete\n\n### \"Rate limit exceeded\"\n\nThe server includes built-in rate limiting (50 requests/minute). If you hit Apple's limits:\n1. Wait for the indicated retry time\n2. Batch your operations when possible\n3. The server automatically retries with exponential backoff\n\n### Tools Not Appearing in Claude\n\n1. Verify the server is running: check Claude Desktop logs\n2. Ensure the config file path is correct for your OS\n3. Restart Claude Desktop after config changes\n\n## Development\n\n### Prerequisites\n\n- Node.js 20+\n- npm or pnpm\n\n### Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/SardorbekR/appstore-connect-mcp.git\ncd appstore-connect-mcp\n\n# Install dependencies\nnpm install\n\n# Build\nnpm run build\n\n# Run tests\nnpm test\n\n# Lint\nnpm run lint\n\n# Type check\nnpm run typecheck\n```\n\n### Project Structure\n\n```\nsrc/\n├── index.ts          # MCP server entry point\n├── auth/\n│   └── jwt.ts        # JWT token generation & caching\n├── api/\n│   ├── client.ts     # HTTP client with retry logic\n│   └── types.ts      # TypeScript interfaces\n├── tools/\n│   ├── index.ts      # Tool registry\n│   ├── apps.tools.ts\n│   ├── versions.tools.ts\n│   ├── localizations.tools.ts\n│   ├── app-info.tools.ts\n│   ├── beta.tools.ts\n│   ├── screenshots.tools.ts\n│   ├── bundle-ids.tools.ts\n│   ├── devices.tools.ts\n│   ├── users.tools.ts\n│   ├── builds.tools.ts\n│   └── categories.tools.ts\n└── utils/\n    ├── errors.ts     # Error classes with redaction\n    └── validation.ts # Zod schemas\n```\n\n### Running Locally\n\n```bash\n# Development mode with auto-reload\nnpm run dev\n\n# Or run the built version\nnpm start\n```\n\n### Contributing\n\n1. Fork the repository\n2. Create a feature branch: `git checkout -b feature/my-feature`\n3. Make your changes and add tests\n4. Run `npm test` and `npm run lint`\n5. Submit a pull request\n\n## License\n\nMIT License - see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Security Policy](SECURITY.md)\n- [App Store Connect API Documentation](https://developer.apple.com/documentation/appstoreconnectapi)\n- [Model Context Protocol](https://modelcontextprotocol.io)\n",
  "bytes": 20047,
  "sha": "6d605d143fe8a53e8e4a3ecf4743a4d791107234ede680ba7878b653aefd3176",
  "repo_slug": "sardorbekr/appstore-connect-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_sardorbekr_appstore_connect_851b17bd/readme"
}