Skip to main content
Glama

app-store-connect-mcp

Un servidor MCP para ambas APIs comerciales de Apple — App Store Connect (1.263 operaciones) y la API del Servidor de la App Store / StoreKit 2 (30 operaciones) — detrás de cinco herramientas, con la clave privada en el Llavero de macOS y las escrituras con consecuencias protegidas por una confirmación explícita.

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

Por qué está construido así

Existen varios servidores MCP para App Store Connect. Cada uno resuelve parte del problema; este toma la parte que cada uno hizo bien y descarta lo que hicieron mal.

Enfoque

Conservado

Rechazado

Herramientas manuales

Una herramienta MCP por endpoint

Argumentos tipados y descubribles

70–900 definiciones de herramientas, >100k tokens, obsoletas cuando Apple lanza una versión

Modo Código

El LLM escribe JS, el servidor lo evalúa

Dos herramientas, ~1k tokens, cobertura completa

Ejecuta código generado en un proceso que tiene una clave de firma

Meta-herramientas

searchcall con parámetros

Misma ventaja de contexto, sin ejecución de código

Este servidor usa la tercera. La cobertura es una propiedad de la especificación de Apple, no de cuántos endpoints alguien envolvió; y el modelo nunca puede ejecutar código dentro de un proceso que pueda cambiar tus precios.

Sobre el sandbox

La premisa del Modo Código es que el JavaScript generado se ejecuta de forma segura dentro del vm de Node. No es así. La propia documentación de Node dice que vm no es un mecanismo de seguridad, y cualquier objeto anfitrión inyectado como global devuelve el ámbito del anfitrión a través de su propia cadena de prototipos:

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

Verificado contra una reproducción fiel de ese sandbox: devuelve el entorno anfitrión. La opción timeout tampoco ayuda — solo limita la ejecución síncrona, por lo que un bucle ocupado async se ejecuta para siempre y agota el bucle de eventos.

El envío parametrizado obtiene la misma cobertura y el mismo costo de tokens sin un intérprete del que escapar.

Related MCP server: App Store Connect MCP Server

Credenciales

La clave privada debe estar en el Llavero. Apple permite descargar un .p8 una sola vez, y una copia en texto plano en disco es una copia que puede filtrarse.

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

Un elemento del Llavero puede contener un PEM simple, o JSON en base64:

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

La forma de sobre es preferible: los identificadores viajan con el material de la clave, por lo que ASC_KEY_ID no puede desincronizarse de la clave que nombra — una discrepancia que solo se manifiesta como un 401 opaco.

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

Instalación

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 solo es necesario para llamadas a la API del Servidor de la App Store — Apple rechaza un token de la API del Servidor sin una declaración bid.

Herramientas

Herramienta

Propósito

asc_status

Verificar credenciales, informar accesibilidad y el presupuesto restante de límite de tasa. Ejecútala primero cuando algo falle — separa una clave mala de una solicitud mala.

asc_search_endpoints

Buscar en ambas APIs por palabra clave, método, etiqueta o nivel de riesgo. Devuelve operationIds y dice a qué herramienta pertenece cada uno.

asc_describe_endpoint

Parámetros, esquema del cuerpo de la solicitud con nombres de campo reales, nivel de riesgo.

asc_call

Lecturas. Parámetros de ruta y consulta, paginación, ambas APIs.

asc_write

Todo lo que cambia datos. Confirmación, dry_run, ambas APIs.

Las lecturas y escrituras son herramientas separadas porque Claude Code ignora la anotación estándar destructiveHint pero respeta _meta["anthropic/requiresUserInteraction"] — y esa bandera es por herramienta. Un único despachador no podría variarla por operación. asc_write la lleva, por lo que una escritura solicita al usuario incluso bajo bypassPermissions. Esa es una garantía más fuerte que la puerta en proceso, que --no-confirm puede desactivar.

Recursos

Material de referencia que el modelo puede incorporar deliberadamente, mediante @asc::

Recurso

Contenido

asc://cookbook

Casos en los que Apple devuelve una respuesta exitosa que significa algo diferente de lo que parece — paginación, territorios alfa-3, sort rechazado, informes comprimidos

asc://enums

Los 90 campos enumerados, generados a partir de la especificación de Apple para que no queden obsoletos

asc://risk

Qué significa cada nivel de riesgo y qué tan reversible es

asc://sources

De dónde vino cada descripción de API y cuándo

asc-response://…

Almacenamiento de desbordamiento — ver más abajo

Un resultado demasiado grande para devolver en línea no se corta. La lista se reduce a lo que cabe, se indica el truncamiento junto con cómo acotar la solicitud, y la respuesta completa se mantiene como un recurso que el cliente puede leer sin gastar contexto. Cortar JSON serializado a medio camino le da al modelo algo no analizable; cortar en silencio es peor, porque una lista parcial se lee como completa.

Prompts

Cuatro flujos de trabajo, disponibles como /mcp__asc__<nombre>:

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

Cada uno encadena varias llamadas — un comando de barra que envuelve una sola solicitud es un sinónimo, no un flujo de trabajo — y cada uno codifica las trampas, como que sort sea rechazado en customerReviews y que el texto de las reseñas sea entrada no confiable.

Seguridad en escrituras

Un método HTTP es un mal indicador de consecuencia: PATCH /v1/subscriptionPrices y PATCH /v1/appInfos/{id} son ambas escrituras, pero solo una cambia lo que se cobra a los clientes, y ninguna se deshace repitiéndola. Las operaciones tienen un nivel de riesgo:

Nivel

Conteo

Significado

READ

797

Sin cambio.

WRITE

238

Cambia datos.

REVENUE

61

Precios, suscripciones, derechos.

DESTRUCTIVE

132

Elimina.

RELEASE

12

Compilaciones, envíos, lo que se publica.

ACCESS

12

Quién puede acceder a la cuenta.

INFRASTRUCTURE

11

Certificados, identificadores, URLs de devolución de llamada.

Por defecto, los cinco niveles inferiores devuelven un token de confirmación en lugar de ejecutar. El token está vinculado por hash a la operación, ruta, consulta y cuerpo exactos, por lo que no se puede obtener para una llamada barata y gastar en una costosa. Es de un solo uso y caduca en cinco minutos.

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

Cuando el cliente admite elicitation, asc_write pregunta directamente a la persona, mostrando el método, ruta, cuerpo y nivel. De lo contrario, recurre a un token de confirmación vinculado por hash a la operación, ruta, consulta y cuerpo exactos, de modo que un token emitido para una llamada barata no se pueda gastar en una costosa. Un cliente que declara elicitation pero no lo sirve retrocede en lugar de pasar de largo. dry_run informa la solicitud exacta sin enviarla.

Transportes

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

HTTP se vincula a 127.0.0.1 y se niega a iniciar sin un token bearer. Este proceso tiene una clave que puede cambiar los precios de la App Store; no debería escuchar sin autenticación. Vincular fuera del bucle local advierte y es mejor combinarlo con un proxy de terminación TLS o un túnel SSH.

Mantenerse al día con Apple

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

Las dos APIs se obtienen de diferentes fuentes, por necesidad:

  • App Store Connect — Apple publica un documento OpenAPI 3.0 real. Se descarga y se compila en un índice ligero (360KB, frente a una especificación de 3.3MB) para que la búsqueda sea rápida y el documento completo solo se abra para describir una operación.

  • App Store Server — Apple no publica ningún documento OpenAPI; la documentación es prosa. La descripción legible por máquina autorizada es el propio cliente de Apple, apple/app-store-server-library-node, donde cada endpoint es una llamada literal makeRequest. fetch:specs analiza el conjunto de endpoints de esa fuente en una etiqueta de versión fija, y verify lo compara con el catálogo en src/storekit.ts.

Dos detalles en ese catálogo contradicen lo que implica la documentación, y ambos son importantes:

  • Los hosts son api.storekit.apple.com / api.storekit-sandbox.apple.com. Los nombres antiguos api.storekit.itunes.apple.com ya no sirven esta API.

  • La ruta de estado de extensión de renovación masiva ordena sus segmentos {productId}/{requestIdentifier} — no al revés.

Verificación

npm run verify es de solo lectura y realiza llamadas reales. Última ejecución:

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

Las pruebas de StoreKit usan un ID de transacción deliberadamente inválido. La señal es la forma de la respuesta: un errorCode estructurado de Apple demuestra que la solicitud fue autenticada y enrutada, mientras que un 401 demostraría que no lo fue.

Robustez

  • Tiempos de espera y reintentos. Las lecturas reintentan en 408/429/5xx; las escrituras reintentan solo en 429, donde Apple rechazó la solicitud antes de procesarla. Una escritura que falla de manera ambigua se informa como ambigua y nunca se reenvía — un POST duplicado es peor que un fallo informado.

  • Límite de tasa. Regulado tanto contra el límite horario documentado como contra el límite por minuto no documentado, y corregido a partir del encabezado x-rate-limit de Apple, que tiene en cuenta otros clientes que comparten la clave. x-request-id se muestra para el soporte de Apple.

  • Fijación de host. Cada URL, incluido el cursor de paginación links.next, se verifica contra una lista blanca de los tres hosts de API de Apple. Un cursor es una entrada proporcionada por el servidor; seguirlo ciegamente llevaría un token bearer al host que nombre.

  • Modelado de respuesta. Se eliminan links y relationships que solo contienen enlaces, se conserva links.next — más de un 60% más pequeño en una lista real de puntos de precio.

  • Ciclo de vida. El servidor stdio sale al recibir EOF en stdin y ante señales, en lugar de quedar huérfano reteniendo una clave de firma.

Limitaciones conocidas

  • Las respuestas JWS se decodifican, no se verifican. Los payloads de StoreKit llegan firmados por Apple; verificar la cadena necesita los certificados raíz de Apple. Los valores decodificados aparecen en campos *_decoded y se etiquetan como no verificados. No los trates como prueba de compra sin comprobar la firma.

  • Los niveles de riesgo se detectan por patrón a partir del método y la ruta. Son deliberadamente cautelosos, pero lee asc_describe_endpoint antes de una escritura en lugar de confiar solo en el nivel.

  • El almacenamiento en Llavero es solo para macOS. En otros sistemas, usa una ruta de archivo con permisos restrictivos.

  • --no-confirm desactiva la puerta por completo. Existe para CI; es un valor predeterminado pobre para un agente interactivo.

Licencia

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