Skip to main content
Glama

app-store-connect-mcp

Ein MCP-Server für beide Apple-Commerce-APIs – App Store Connect (1.263 Operationen) und die App Store Server API / StoreKit 2 (30 Operationen) – hinter fünf Tools, mit dem privaten Schlüssel in der macOS-Tastaturverwaltung und folgenschweren Schreibvorgängen, die durch eine explizite Bestätigung abgesichert sind.

1,293 operations · 5 tools · key never on disk · verified against the live APIs

Warum es so gebaut ist

Es gibt mehrere App Store Connect MCP-Server. Jeder löst einen Teil des Problems; dieser übernimmt das, was jeder richtig gemacht hat, und verwirft das, was falsch lief.

Ansatz

Behalten

Abgelehnt

Manuell verpackte Tools

Ein MCP-Tool pro Endpunkt

Typisierte, auffindbare Argumente

70–900 Tool-Definitionen, >100k Tokens, veraltet, sobald Apple eine Version ausliefert

Code-Modus

LLM schreibt JS, Server evalt es

Zwei Tools, ~1k Tokens, vollständige Abdeckung

Führt generierten Code in einem Prozess aus, der einen Signaturschlüssel hält

Meta-Tools

searchcall mit Parametern

Gleicher Kontextgewinn, keine Code-Ausführung

Dieser Server verwendet den dritten Ansatz. Die Abdeckung ist eine Eigenschaft von Apples Spezifikation, nicht davon, wie viele Endpunkte jemand verpackt hat; und das Modell darf niemals Code in einem Prozess ausführen, der Ihre Preise ändern kann.

Zur Sandbox

Die Prämisse des Code-Modus ist, dass generierter JavaScript-Code sicher innerhalb von Nodes vm läuft. Das tut er nicht. Nodes eigene Dokumentation sagt, dass vm kein Sicherheitsmechanismus ist, und jedes als global injizierte Host-Objekt gibt die Host-Umgebung über seine eigene Prototyp-Kette zurück:

spec.constructor.constructor('return process.env.HOME')()   // → /Users/you

Überprüft gegen eine originalgetreue Nachbildung dieser Sandbox: Sie gibt die Host-Umgebung zurück. Die timeout-Option hilft ebenfalls nicht – sie begrenzt nur die synchrone Ausführung, sodass eine async-Endlosschleife ewig läuft und die Ereignisschleife aushungert.

Parametrisierter Dispatch bietet die gleiche Abdeckung und die gleichen Token-Kosten ohne zu entkommenden Interpreter.

Related MCP server: App Store Connect MCP Server

Anmeldeinformationen

Der private Schlüssel gehört in die Tastaturverwaltung. Apple erlaubt Ihnen, eine .p8-Datei genau einmal herunterzuladen, und eine unverschlüsselte Kopie auf der Festplatte ist eine Kopie, die durchsickern kann.

ASC_KEY=keychain:my-asc-key          # recommended
ASC_KEY=/path/to/AuthKey.p8          # works, but plaintext
ASC_PRIVATE_KEY='-----BEGIN…'        # discouraged: `ps -E` exposes it

Ein Eintrag in der Tastaturverwaltung kann ein reines PEM oder base64-JSON enthalten:

{ "issuerID": "…", "keyID": "…", "privateKeyPEM": "-----BEGIN PRIVATE KEY-----\n…" }

Die Hüllenform ist vorzuziehen: Die Identifikatoren reisen mit dem Schlüsselmaterial, sodass ASC_KEY_ID nicht aus dem Takt mit dem von ihm benannten Schlüssel geraten kann – eine Diskrepanz, die sich nur als undurchsichtiger 401 zeigt.

security add-generic-password -s my-asc-key -a api -w "$(
  jq -nc --arg i "$ISSUER" --arg k "$KEYID" --arg p "$(cat AuthKey.p8)" \
    '{issuerID:$i,keyID:$k,privateKeyPEM:$p}' | base64
)"

Installation

git clone https://github.com/abd3lraouf-studios/app-store-connect-mcp
cd app-store-connect-mcp
npm install && npm run build
{
  "mcpServers": {
    "app-store-connect": {
      "command": "node",
      "args": ["/path/to/app-store-connect-mcp/dist/index.js"],
      "env": {
        "ASC_KEY": "keychain:my-asc-key",
        "ASC_BUNDLE_ID": "com.example.app"
      }
    }
  }
}

ASC_BUNDLE_ID wird nur für App Store Server API-Aufrufe benötigt – Apple lehnt ein Server-API-Token ohne einen bid-Anspruch ab.

Tools

Tool

Zweck

asc_status

Überprüft Anmeldeinformationen, meldet Erreichbarkeit und das verbleibende Rate-Limit-Budget. Zuerst ausführen, wenn etwas fehlschlägt – es trennt einen schlechten Schlüssel von einer schlechten Anfrage.

asc_search_endpoints

Durchsucht beide APIs nach Schlüsselwort, Methode, Tag oder Risikostufe. Gibt operationIds zurück und sagt, zu welchem Tool jede gehört.

asc_describe_endpoint

Parameter, Request-Body-Schema mit echten Feldnamen, Risikostufe.

asc_call

Lesevorgänge. Pfad- und Query-Parameter, Paginierung, beide APIs.

asc_write

Alles, was Daten ändert. Bestätigung, dry_run, beide APIs.

Lese- und Schreibvorgänge sind getrennte Tools, da Claude Code die standardmäßige destructiveHint-Annotation ignoriert, aber _meta["anthropic/requiresUserInteraction"] beachtet – und dieses Flag ist pro Tool. Ein einzelner Dispatcher könnte es nicht pro Operation variieren. asc_write trägt es, sodass ein Schreibvorgang den Benutzer selbst unter bypassPermissions auffordert. Das ist eine stärkere Garantie als die prozessinterne Absicherung, die --no-confirm deaktivieren kann.

Ressourcen

Referenzmaterial, das das Modell gezielt über @asc: abrufen kann:

Ressource

Inhalt

asc://cookbook

Fälle, in denen Apple eine erfolgreiche Antwort zurückgibt, die etwas anderes bedeutet, als es scheint – Paginierung, Alpha-3-Territorien, abgelehntes sort, gzippte Berichte

asc://enums

Alle 90 aufgezählten Felder, generiert aus Apples Spezifikation, sodass sie nicht veralten können

asc://risk

Was jede Risikostufe bedeutet und wie reversibel sie ist

asc://sources

Woher jede API-Beschreibung stammt und wann

asc-response://…

Überlaufspeicher – siehe unten

Ein zu großes Ergebnis, um es inline zurückzugeben, wird nicht abgeschnitten. Die Liste wird auf das reduziert, was hineinpasst, die Kürzung wird zusammen mit einem Hinweis, wie die Anfrage eingegrenzt werden kann, angegeben, und die vollständige Antwort wird als Ressource aufbewahrt, die der Client lesen kann, ohne Kontext zu verbrauchen. Das Abschneiden von serialisiertem JSON mitten in der Struktur gibt dem Modell etwas Unparsbares; stilles Abschneiden ist schlimmer, da eine Teilliste wie eine vollständige gelesen wird.

Prompts

Vier Workflows, verfügbar als /mcp__asc__<name>:

release-readiness · pricing-audit · review-triage · testflight-status

Jeder verknüpft mehrere Aufrufe – ein Slash-Befehl, der eine Anfrage umschließt, ist ein Synonym, kein Workflow – und jeder kodiert die Fallstricke, wie z. B., dass sort bei customerReviews abgelehnt wird und Prüftext eine unvertrauenswürdige Eingabe ist.

Schreibsicherheit

Eine HTTP-Methode ist ein schlechter Stellvertreter für die Konsequenz: PATCH /v1/subscriptionPrices und PATCH /v1/appInfos/{id} sind beide Schreibvorgänge, aber nur einer ändert, was Kunden berechnet wird, und keiner wird durch Wiederholung rückgängig gemacht. Operationen haben eine Risikostufe:

Stufe

Anzahl

Bedeutung

READ

797

Keine Änderung.

WRITE

238

Ändert Daten.

REVENUE

61

Preise, Abonnements, Berechtigungen.

DESTRUCTIVE

132

Löscht.

RELEASE

12

Builds, Einreichungen, was ausgeliefert wird.

ACCESS

12

Wer auf das Konto zugreifen kann.

INFRASTRUCTURE

11

Zertifikate, Identifikatoren, Callback-URLs.

Standardmäßig geben die unteren fünf Stufen ein Bestätigungstoken zurück, anstatt auszuführen. Das Token ist per Hash an die genaue Operation, den Pfad, die Query und den Body gebunden, sodass es nicht für einen günstigen Aufruf erlangt und für einen teuren ausgegeben werden kann. Es ist einmalig verwendbar und läuft in fünf Minuten ab.

--read-only    block every write        --confirm     confirm every write
--no-confirm   never confirm            (default)     confirm the five tiers above

Wenn der Client Elicitation unterstützt, fragt asc_write die Person direkt und zeigt die Methode, den Pfad, den Body und die Stufe an. Andernfalls fällt es auf ein Bestätigungstoken zurück, das per Hash an die genaue Operation, den Pfad, die Query und den Body gebunden ist, sodass ein Token, das für einen günstigen Aufruf ausgestellt wurde, nicht für einen teuren ausgegeben werden kann. Ein Client, der Elicitation deklariert, aber nicht bedient, fällt zurück, anstatt durchzusegeln. dry_run meldet die genaue Anfrage, ohne sie zu senden.

Transporte

node dist/index.js                       # stdio (default)
node dist/index.js --transport http --http-token "$(openssl rand -hex 32)"

HTTP bindet an 127.0.0.1 und weigert sich, ohne ein Bearer-Token zu starten. Dieser Prozess hält einen Schlüssel, der die App Store-Preise ändern kann; er sollte nicht unauthentifiziert lauschen. Eine Bindung außerhalb des Loopbacks warnt und ist am besten mit einem TLS-terminierenden Proxy oder einem SSH-Tunnel zu kombinieren.

Mit Apple Schritt halten

npm run fetch:specs   # re-download both descriptions
npm run build         # recompile the operation index
npm run verify        # drift check + live calls against both APIs

Die beiden APIs werden notgedrungen unterschiedlich bezogen:

  • App Store Connect – Apple veröffentlicht ein echtes OpenAPI 3.0-Dokument. Es wird heruntergeladen und in einen schlanken Index (360 KB, gegenüber einer 3,3 MB großen Spezifikation) kompiliert, damit die Suche schnell bleibt und das vollständige Dokument nur geöffnet wird, um eine Operation zu beschreiben.

  • App Store Server – Apple veröffentlicht kein OpenAPI-Dokument; die Dokumentation ist Prosa. Die maßgebliche maschinenlesbare Beschreibung ist Apples eigener Client, apple/app-store-server-library-node, in dem jeder Endpunkt ein literaler makeRequest-Aufruf ist. fetch:specs parst die Endpunktmenge aus dieser Quelle bei einem festgelegten Release-Tag, und verify vergleicht sie mit dem Katalog in src/storekit.ts.

Zwei Details in diesem Katalog widersprechen dem, was die Dokumentation impliziert, und beide sind tragend:

  • Die Hosts sind api.storekit.apple.com / api.storekit-sandbox.apple.com. Die älteren api.storekit.itunes.apple.com-Namen bedienen diese API nicht mehr.

  • Der Statuspfad für die Massenverlängerung ordnet seine Segmente {productId}/{requestIdentifier} – nicht umgekehrt.

Überprüfung

npm run verify ist schreibgeschützt und führt echte Aufrufe durch. Zuletzt ausgeführt:

1. Catalogue drift — src/storekit.ts vs Apple’s client
  ✓ all 30 Apple endpoints present in the catalogue
  ✓ no endpoints in the catalogue that Apple does not define

2. App Store Connect API — live
  ✓ apps_getCollection → 2 apps
  ✓ apps_getInstance / builds / appStoreVersions → HTTP 200
  ✓ pagination walked 3 pages
  ✓ bogus id → structured 404

3. App Store Server API (StoreKit 2) — live
  ✓ storekit token carries bid;  connect token correctly omits it
  ✓ getTransactionInfo / getAllSubscriptionStatuses / getTransactionHistory v2
      → authenticated and routed (Apple errorCode 4000006)
  ✓ getNotificationHistory (30d window) → HTTP 200

14 passed, 0 failed

StoreKit-Sonden verwenden eine absichtlich ungültige Transaktions-ID. Das Signal ist die Form der Antwort: Ein strukturierter Apple-errorCode beweist, dass die Anfrage authentifiziert und weitergeleitet wurde, während ein 401 beweisen würde, dass sie es nicht war.

Robustheit

  • Timeouts und Wiederholungen. Lesevorgänge wiederholen sich bei 408/429/5xx; Schreibvorgänge wiederholen sich nur bei 429, wenn Apple die Anfrage vor der Verarbeitung abgelehnt hat. Ein Schreibvorgang, der mehrdeutig fehlschlägt, wird als mehrdeutig gemeldet und nie erneut gesendet – ein duplizierter POST ist schlimmer als ein gemeldeter Fehler.

  • Ratenbegrenzung. Abgestimmt sowohl auf das dokumentierte stündliche Limit als auch auf das undokumentierte pro Minute, und korrigiert anhand von Apples eigenem x-rate-limit-Header, der andere Clients berücksichtigt, die den Schlüssel teilen. x-request-id wird für den Apple-Support bereitgestellt.

  • Host-Pinning. Jede URL, einschließlich des links.next-Paginierungszeigers, wird gegen eine Positivliste von Apples drei API-Hosts geprüft. Ein Zeiger ist eine vom Server gelieferte Eingabe; ihm blind zu folgen, würde ein Bearer-Token zu dem Host führen, den er benennt.

  • Antwortformung. links und reine relationships-Links werden entfernt, links.next bleibt erhalten – über 60 % kleiner bei einer echten Preislistenauflistung.

  • Lebenszyklus. Der stdio-Server beendet sich bei stdin-EOF und bei Signalen, anstatt als verwaister Prozess mit einem Signaturschlüssel zu verbleiben.

Bekannte Einschränkungen

  • JWS-Antworten werden dekodiert, nicht verifiziert. StoreKit-Nutzlasten treffen von Apple signiert ein; die Überprüfung der Kette erfordert Apples Root-Zertifikate. Dekodierte Werte erscheinen in *_decoded-Feldern und sind als unverifiziert gekennzeichnet. Behandeln Sie sie nicht als Kaufnachweis, ohne die Signatur zu prüfen.

  • Risikostufen werden per Musterabgleich aus Methode und Pfad ermittelt. Sie sind bewusst vorsichtig, aber lesen Sie vor einem Schreibvorgang asc_describe_endpoint, anstatt sich allein auf die Stufe zu verlassen.

  • Die Tastaturverwaltungsspeicherung ist nur für macOS verfügbar. Verwenden Sie andernfalls einen Dateipfad mit restriktiven Berechtigungen.

  • --no-confirm deaktiviert die Absicherung vollständig. Es existiert für CI; es ist eine schlechte Standardeinstellung für einen interaktiven Agenten.

Lizenz

MIT

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.

  • Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.

  • Manage your NanoCart store from any AI agent: products, orders, coupons, subscribers, reports.

View all MCP Connectors

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/abd3lraouf-studios/app-store-connect-mcp'

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