appstore-connect-mcp

mcp
Guvenlik Denetimi
Uyari
Health Gecti
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 14 GitHub stars
Code Uyari
  • network request — Outbound network request in package.json
  • network request — Outbound network request in src/api/client.ts
  • crypto private key — Private key handling in src/auth/jwt-manager.ts
  • process.env — Environment variable access in src/index.ts
  • process.env — Environment variable access in src/test-all-tools.ts
  • process.env — Environment variable access in src/test-api.ts
  • process.env — Environment variable access in src/test-auth.ts
  • process.env — Environment variable access in src/test-complete-financial.ts
  • process.env — Environment variable access in src/test-complete-revenue.ts
Permissions Gecti
  • Permissions — No dangerous permissions requested
Purpose
This MCP server provides a bridge to the Apple App Store Connect API, allowing LLMs to query and interact with 923 API endpoints using just two dynamic tools.

Security Assessment
Overall risk: Medium. The tool inherently handles highly sensitive data. It requires your Apple App Store Connect private key (`.p8` file) to generate JWT tokens for authentication, which grants access to financial and app management data. The code makes legitimate outbound network requests to Apple's servers to execute these API calls. It accesses environment variables strictly to read these configured credentials, with no hardcoded secrets or dangerous shell execution commands detected.

Quality Assessment
The project is actively maintained with recent updates and uses modern TypeScript. It uses the standard MIT license and has basic community trust with 14 GitHub stars. The developer experience looks solid, featuring a clever, token-efficient design that dynamically maps Apple's OpenAPI spec rather than hardcoding each endpoint.

Verdict
Use with caution — the architecture is safe and well-built, but you must protect your Apple API keys and strictly limit which AI agents you trust to execute financial or app management actions.
SUMMARY

Code Mode MCP server for App Store Connect — 923 endpoints through 2 tools

README.md

App Store Connect MCP Server — Code Mode

923 endpoints. 2 tools. The spec IS the implementation.

TypeScript
MCP SDK
License: MIT
API Version

The Problem

Traditional MCP servers wrap each API endpoint as a separate tool. Apple's App Store Connect API has 923 endpoints. That means 923 tool definitions, ~100K+ context tokens, and a new release every time Apple adds an endpoint.

The Solution

Code Mode: 2 tools replace 923.

Tool What It Does
search(code) Write JS to query Apple's OpenAPI spec. Discover endpoints, check parameters, read schemas.
execute(code) Write JS to call the API. Auth is automatic. Chain multiple calls.

The LLM writes the query. The spec IS the implementation. Adding endpoints = Apple updates their spec. Zero code changes on our side.

Traditional MCP:  923 endpoints → 923 tools → ~100K tokens → constant maintenance
Code Mode:        923 endpoints → 2 tools   → ~1K tokens   → zero maintenance

Quick Start

1. Get App Store Connect credentials

  1. Go to App Store Connect → Users and Access → Integrations → Keys
  2. Click "+" to generate a new key (Admin or Finance role)
  3. Download the .p8 file (only downloadable once!)
  4. Note your Key ID and Issuer ID

2. Install via Claude Code

claude mcp add appstore-connect -s user \
  -e APP_STORE_KEY_ID=YOUR_KEY_ID \
  -e APP_STORE_ISSUER_ID=YOUR_ISSUER_ID \
  -e APP_STORE_P8_PATH=/absolute/path/to/AuthKey_XXXXXXXXXX.p8 \
  -e APP_STORE_VENDOR_NUMBER=YOUR_VENDOR_NUMBER \
  -- npx -y @trialanderror/appstore-connect-mcp

-s user makes the server available across all your projects. Drop -e APP_STORE_VENDOR_NUMBER if you don't need financial reports.

Or skip the env-var inline form and set them in your shell / MCP config (see below).

3. Configure credentials

Three required env vars (one optional):

Variable Description
APP_STORE_KEY_ID 10-character key ID
APP_STORE_ISSUER_ID UUID issuer ID
APP_STORE_P8_PATH Absolute path to your .p8 file
APP_STORE_VENDOR_NUMBER (optional) Required for financial reports

Configure for Claude Code

Either set env vars in your shell, or pass them via .mcp.json:

{
  "mcpServers": {
    "appstore-connect": {
      "command": "npx",
      "args": ["-y", "@trialanderror/appstore-connect-mcp"],
      "env": {
        "APP_STORE_KEY_ID": "YOUR_KEY_ID",
        "APP_STORE_ISSUER_ID": "YOUR_ISSUER_ID",
        "APP_STORE_P8_PATH": "/path/to/AuthKey_XXXXXXXXXX.p8",
        "APP_STORE_VENDOR_NUMBER": "YOUR_VENDOR_NUMBER"
      }
    }
  }
}

Configure for Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "appstore-connect": {
      "command": "npx",
      "args": ["-y", "@trialanderror/appstore-connect-mcp"],
      "env": {
        "APP_STORE_KEY_ID": "YOUR_KEY_ID",
        "APP_STORE_ISSUER_ID": "YOUR_ISSUER_ID",
        "APP_STORE_P8_PATH": "/path/to/AuthKey_XXXXXXXXXX.p8"
      }
    }
  }
}

Build from source (alternative)

git clone https://github.com/TrialAndErrorAI/appstore-connect-mcp
cd appstore-connect-mcp
npm install
npm run build

Then point your MCP config at node /path/to/appstore-connect-mcp/dist/index.js instead of npx.

Usage Examples

Discover endpoints

search: "Find all endpoints related to customer reviews"

The LLM writes:

const reviews = Object.entries(spec.paths)
  .filter(([p]) => p.includes('customerReview'))
  .map(([path, methods]) => ({
    path,
    methods: Object.keys(methods).map(m => m.toUpperCase())
  }));
return reviews;

List your apps

execute: "List all my apps"

The LLM writes:

const apps = await api.request({ method: 'GET', path: '/v1/apps' });
return apps.data.map(a => ({ id: a.id, name: a.attributes.name }));

Chain multiple calls

execute: "Get latest reviews for my first app"

The LLM writes:

const apps = await api.request({ method: 'GET', path: '/v1/apps', params: { limit: '1' } });
const appId = apps.data[0].id;
const reviews = await api.request({
  method: 'GET',
  path: `/v1/apps/${appId}/customerReviews`,
  params: { limit: '5', sort: '-createdDate' }
});
return {
  app: apps.data[0].attributes.name,
  reviews: reviews.data.map(r => ({
    rating: r.attributes.rating,
    title: r.attributes.title,
    body: r.attributes.body
  }))
};

What You Can Access

All 923 App Store Connect API endpoints, including:

Category Endpoints What You Get
App Metadata 29 Title, subtitle, keywords, description — read AND write
Analytics 10 Impressions, page views, downloads, source attribution
Sales & Finance 2 Revenue, units, proceeds by country
Customer Reviews 5 Ratings, review text, respond to reviews
Subscriptions 30 Sub management, pricing, groups, offers
In-App Purchases 29 IAP management, offer codes
Versions 28 Version management, phased rollout
Screenshots 12 Upload, reorder, manage screenshot sets
A/B Testing 24 Product page experiments, treatment variants
Custom Product Pages 18 Custom landing pages per ad campaign
TestFlight 23 Beta groups, testers, builds
Pricing 11 Per-territory pricing, price points
Builds 29 Build management, processing state

See API-COVERAGE.md for the full grouped map.

How It Works

Claude writes JavaScript
    │
    ▼
┌─────────────────────────────────────────────────┐
│ search({ code })                                │
│  Sandbox executes code against OpenAPI spec     │
│  923 paths, 1337 schemas — pre-resolved $refs   │
│  Returns: matching endpoints + parameters       │
└─────────────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────────────┐
│ execute({ code })                               │
│  Sandbox executes code against auth'd client    │
│  JWT injected — code never sees credentials     │
│  Supports GET/POST/PATCH/DELETE + chaining      │
│  Auto-decompresses gzipped report responses     │
│  Returns: API response (truncated to 40K chars) │
└─────────────────────────────────────────────────┘

Security

  • Code runs in Node.js vm sandbox
  • No fetch, require, process, eval, setTimeout available
  • Credentials injected via binding — never visible to generated code
  • Response truncated to prevent context bloat
  • Only spec (search) or api (execute) available as globals

Architecture

src/
├── auth/jwt-manager.ts      — JWT with P8 key, ES256, 19-min cache
├── api/client.ts             — HTTP client, rate limiting, gzip handling
├── spec/
│   ├── openapi.json          — Apple's official spec (923 endpoints)
│   └── loader.ts             — Loads + resolves $refs for flat traversal
├── executor/sandbox.ts       — vm-based sandboxed execution
├── server/mcp-server.ts      — MCP server (search, execute, test_connection)
└── index.ts                  — Entry point

Why Code Mode?

Traditional MCP Code Mode
Tools 1 per endpoint (923) 2 total
Context tokens ~100K+ ~1K
Adding endpoints New tool + code + schema + release Apple updates spec. Zero changes.
Chaining calls Re-enter LLM between each Single execution, multiple calls
Maintenance Update 923 tool definitions Update 1 spec file

Inspired by Cloudflare's Code Mode pattern.

Development

npm install          # Install dependencies
npm run build        # Compile + copy spec
npm run dev          # Watch mode (tsx)
npm start            # Run compiled server
npm run type-check   # TypeScript check

License

MIT — Use it, modify it, sell it. Just make it work.

Credits

Built by Trial and Error Inc. Used in production by RenovateAI, an AI-powered home design app for iOS, Android, and web. Code mode pattern from Cloudflare.


"We don't implement individual endpoints. We implement the ability to call ANY endpoint."

Yorumlar (0)

Sonuc bulunamadi