Skip to main content
Glama
ravenKaisar

App Store Connect MCP

by ravenKaisar

App Store Connect MCP

Node.js and TypeScript MCP server for App Store Connect. It supports multiple Apple accounts and can run either as a self-hosted remote MCP gateway or as a local npx stdio MCP server.

Features

  • Multiple named App Store Connect accounts

  • Account-prefixed MCP tools, so one server can expose several Apple accounts safely

  • ES256 App Store Connect JWT generation and caching

  • Remote Streamable HTTP MCP endpoint at /mcp

  • Bearer-token protection for remote HTTP mode

  • Local stdio mode for npx usage

  • Dockerfile and Docker Compose support

  • Secret-safe logging and responses

  • Zod validation for account configuration and tool inputs

Related MCP server: appstore-mcp

Modes

Mode

Best For

Credentials Location

MCP Transport

Remote HTTP gateway

Teams, shared servers, centralized access

Mounted server-side JSON file

Streamable HTTP

Local stdio package

Individual developers or local automation

MCP client environment variable

stdio

Use remote HTTP mode when developers should not receive Apple private keys. Use local stdio mode only when the machine running the MCP client is allowed to hold Apple credentials.

Architecture

Remote HTTP mode:

MCP Client
   |
   | HTTPS /mcp
   | Authorization: Bearer server-token
   v
App Store Connect MCP Gateway
   |
   | ES256 Apple JWT
   v
App Store Connect API
Local stdio mode:

MCP Client
   |
   | npx @kaisar/mcp-appstore-connect
   | APPLE_ACCOUNTS=base64-json
   v
Local MCP Server
   |
   | ES256 Apple JWT
   v
App Store Connect API

Apple Account Configuration

Create an apple_accounts.json file:

[
  {
    "id": "production",
    "keyId": "ABC123DEFG",
    "issuerId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "privateKey": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
    "vendorNumber": "12345678"
  },
  {
    "id": "client_a",
    "keyId": "XYZ123DEFG",
    "issuerId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
    "privateKey": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
  }
]

Fields:

  • id: local account name used to generate MCP tool prefixes

  • keyId: App Store Connect API key ID

  • issuerId: App Store Connect issuer ID

  • privateKey: .p8 private key content, with newlines preserved or escaped as \n

  • vendorNumber: optional Sales and Trends vendor number

The config does not support defaultBundleId or defaultAppStoreId. Pass app IDs explicitly to tools.

Account IDs can contain spaces or symbols. Tool prefixes are generated by lowercasing the account ID and replacing unsafe characters with _. Prefixes must be unique.

Example:

"Client A" -> client_a
"Production" -> production

Tool Names

The server exposes one set of tools per account. Tool names use:

account_prefix__tool_name

Examples:

production__list_apps
production__get_builds
production__get_sales_data
client_a__list_beta_groups
client_a__get_customer_reviews

The server also exposes:

list_gateway_accounts

This returns configured account IDs and generated tool prefixes only. It never returns Apple keys, issuer IDs, private keys, or vendor numbers.

Remote HTTP Gateway

Remote mode runs a web server with:

  • GET /healthz

  • POST /mcp

Required environment variables:

APPLE_ACCOUNTS_FILE=/run/secrets/apple_accounts.json
MCP_SERVER_TOKEN=replace-with-long-random-token

APPLE_ACCOUNTS_JSON is intentionally not supported in remote HTTP mode. Use a mounted file so Apple credentials are not baked into the image or visible in process environment dumps.

Docker Compose

Create local files:

mkdir -p secrets
cp .env.example .env

Add Apple credentials to:

secrets/apple_accounts.json

Set the gateway token in .env:

MCP_SERVER_TOKEN=replace-with-long-random-token

Start the server:

docker compose up --build

Health check:

curl http://localhost:3000/healthz

Unauthorized MCP requests return 401:

curl -i -X POST http://localhost:3000/mcp

Manual initialize request:

curl -i http://localhost:3000/mcp \
  -H "Authorization: Bearer replace-with-long-random-token" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  --data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Remote MCP Client Config

Use this pattern for clients that support remote Streamable HTTP MCP servers:

{
  "servers": {
    "appstore-connect": {
      "type": "http",
      "url": "https://example.com/mcp",
      "headers": {
        "Authorization": "Bearer replace-with-long-random-token"
      }
    }
  }
}

Developers using remote mode only need the URL and gateway token. They do not need Apple API credentials.

Local npx stdio

Local stdio mode runs directly from npm:

npx -y @kaisar/mcp-appstore-connect

It requires APPLE_ACCOUNTS, a base64-encoded copy of apple_accounts.json.

Generate the value:

node -e "process.stdout.write(Buffer.from(require('fs').readFileSync('secrets/apple_accounts.json')).toString('base64'))"

MCP client config:

{
  "mcpServers": {
    "appstore-connect": {
      "command": "npx",
      "args": ["-y", "@kaisar/mcp-appstore-connect"],
      "env": {
        "APPLE_ACCOUNTS": "base64-encoded-apple-accounts-json"
      }
    }
  }
}

Base64 is not encryption. Anyone who can read this MCP client config can decode the Apple credentials.

Development

Install dependencies:

pnpm install

Build:

pnpm run build

Run tests:

pnpm test

Run remote HTTP mode locally:

APPLE_ACCOUNTS_FILE="./secrets/apple_accounts.json" \
MCP_SERVER_TOKEN="replace-with-long-random-token" \
pnpm run dev

Run stdio mode locally:

APPLE_ACCOUNTS="base64-encoded-apple-accounts-json" pnpm run dev:stdio

Validate mounted-file configuration:

APPLE_ACCOUNTS_FILE="./secrets/apple_accounts.json" pnpm run validate:config

Validate base64 configuration:

APPLE_ACCOUNTS="base64-encoded-apple-accounts-json" pnpm run validate:config

Validation prints only account IDs, tool prefixes, private key validity, and key type. It does not print private key content.

Security

  • Do not commit real apple_accounts.json files.

  • Do not commit .env files.

  • Do not bake Apple private keys into Docker images.

  • Use HTTPS for remote HTTP deployments.

  • Use a long random MCP_SERVER_TOKEN.

  • Rotate MCP_SERVER_TOKEN when access changes.

  • Treat the base64 APPLE_ACCOUNTS value as secret material.

  • Give App Store Connect API keys the minimum Apple role needed for the tools users will call.

  • Review logs before sharing them. Logs are designed to avoid secrets, but operational logs can still reveal account IDs and request timing.

Supported Tool Areas

The server focuses on read-oriented App Store Connect operations, including:

  • apps and app metadata

  • builds and TestFlight resources

  • beta groups and beta feedback

  • customer reviews and review summaries

  • app versions, screenshots, previews, and localizations

  • in-app purchases, subscriptions, offers, prices, and promoted purchases

  • app availability and pricing

  • analytics, sales, finance, and performance reports

  • App Store Connect users

Troubleshooting

Set APPLE_ACCOUNTS_FILE to the mounted apple_accounts.json path

Remote HTTP mode needs APPLE_ACCOUNTS_FILE and a readable mounted JSON file.

Set APPLE_ACCOUNTS to base64-encoded apple_accounts.json content

Local stdio mode needs APPLE_ACCOUNTS.

Set MCP_SERVER_TOKEN

Remote HTTP mode needs a gateway token.

Unauthorized

The MCP client bearer token does not match MCP_SERVER_TOKEN.

JWT generation failed

The private key is not a valid App Store Connect .p8 EC private key. Re-copy the complete key, including the BEGIN PRIVATE KEY and END PRIVATE KEY lines.

Sales report errors mentioning reportSubType or vendorNumber

Sales and Trends reports require Apple report filters and a numeric Vendor Number. Pass vendorNumber in the tool call or configure it in the account entry.

App lookup errors for values like com.example.app

Most App Store Connect API app endpoints expect the numeric app resource ID returned by list_apps, not the bundle ID.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ravenKaisar/mcp-appstore-connect'

If you have feedback or need assistance with the MCP directory API, please join our Discord server