npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

asc-mcp

v1.0.4

Published

MCP server for Apple's App Store Connect API - manage iOS, macOS, tvOS, and visionOS apps with AI

Readme

App Store Connect MCP Server

npm version License: MIT Node.js Version

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
  • Secure by Default - ES256 JWT auth with automatic token refresh, credential redaction in logs

Table of Contents

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

  1. Sign in to App Store Connect
  2. Go to Users and AccessIntegrationsApp Store Connect API
  3. Click Generate API Key (or use existing)
  4. Select appropriate role (Admin or App Manager recommended)
  5. Download the .p8 file - you can only download it once!
  6. Note your Key ID (shown in the keys list)
  7. 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

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"
      }
    }
  }
}

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"
      }
    }
  }
}

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"
      }
    }
  }
}

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 |

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:

  1. Find the app using list_apps
  2. Get the version using list_app_versions
  3. Find the English localization using list_version_localizations
  4. 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 [email protected] as a beta tester to the Internal Testing group for MyApp"

Claude will:

  1. Find the app and beta group using list_beta_groups
  2. Add the tester using add_beta_tester

Check Version Status

"What's the status of all versions of MyApp?"

Claude will use list_app_versions to show version states (PREPARE_FOR_SUBMISSION, IN_REVIEW, READY_FOR_SALE, etc.)

Security

Credential Handling

  • Private keys are never logged or exposed in error messages
  • JWT tokens are automatically redacted from any error output
  • Issuer IDs (UUIDs) are redacted from logs
  • Token caching minimizes key usage (15-min tokens, refreshed at 10 min)

Path Validation

  • P8 file paths are validated against directory traversal attacks (.. not allowed)
  • Only absolute paths are resolved

Best Practices

  1. Never commit credentials - Use environment variables or a secrets manager
  2. Restrict API key permissions - Use minimal required role (App Manager for most operations)
  3. Rotate keys periodically - Generate new API keys and revoke old ones
  4. Secure your .p8 file - Set file permissions to 600 (owner read/write only)
chmod 600 /path/to/AuthKey.p8

Troubleshooting

"Configuration error: APP_STORE_CONNECT_KEY_ID environment variable is required"

Ensure all required environment variables are set:

  • APP_STORE_CONNECT_KEY_ID
  • APP_STORE_CONNECT_ISSUER_ID
  • APP_STORE_CONNECT_P8_PATH or APP_STORE_CONNECT_P8_CONTENT

"Failed to read private key"

  1. Verify the path in APP_STORE_CONNECT_P8_PATH is correct and absolute
  2. Check file permissions: ls -la /path/to/AuthKey.p8
  3. Ensure the file is a valid .p8 from Apple (starts with -----BEGIN PRIVATE KEY-----)

"Authentication failed"

This usually means:

  1. The API key was revoked in App Store Connect
  2. The Key ID or Issuer ID doesn't match the .p8 file
  3. The .p8 file is corrupted or incomplete

"Rate limit exceeded"

The server includes built-in rate limiting (50 requests/minute). If you hit Apple's limits:

  1. Wait for the indicated retry time
  2. Batch your operations when possible
  3. The server automatically retries with exponential backoff

Tools Not Appearing in Claude

  1. Verify the server is running: check Claude Desktop logs
  2. Ensure the config file path is correct for your OS
  3. Restart Claude Desktop after config changes

Development

Prerequisites

  • Node.js 20+
  • npm or pnpm

Setup

# Clone the repository
git clone https://github.com/SardorbekR/appstore-connect-mcp.git
cd appstore-connect-mcp

# Install dependencies
npm install

# Build
npm run build

# Run tests
npm test

# Lint
npm run lint

# Type check
npm run typecheck

Project Structure

src/
├── index.ts          # MCP server entry point
├── auth/
│   └── jwt.ts        # JWT token generation & caching
├── api/
│   ├── client.ts     # HTTP client with retry logic
│   └── types.ts      # TypeScript interfaces
├── tools/
│   ├── index.ts      # Tool registry
│   ├── apps.tools.ts
│   ├── versions.tools.ts
│   ├── localizations.tools.ts
│   ├── app-info.tools.ts
│   ├── beta.tools.ts
│   ├── screenshots.tools.ts
│   ├── bundle-ids.tools.ts
│   ├── devices.tools.ts
│   ├── users.tools.ts
│   ├── builds.tools.ts
│   └── categories.tools.ts
└── utils/
    ├── errors.ts     # Error classes with redaction
    └── validation.ts # Zod schemas

Running Locally

# Development mode with auto-reload
npm run dev

# Or run the built version
npm start

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Make your changes and add tests
  4. Run npm test and npm run lint
  5. Submit a pull request

License

MIT License - see LICENSE for details.

Links