app-store-connect-mcp
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 APIsPor 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 |
| 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/youVerificado 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 itUn 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 |
| 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. |
| Buscar en ambas APIs por palabra clave, método, etiqueta o nivel de riesgo. Devuelve operationIds y dice a qué herramienta pertenece cada uno. |
| Parámetros, esquema del cuerpo de la solicitud con nombres de campo reales, nivel de riesgo. |
| Lecturas. Parámetros de ruta y consulta, paginación, ambas APIs. |
| Todo lo que cambia datos. Confirmación, |
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 |
| Casos en los que Apple devuelve una respuesta exitosa que significa algo diferente de lo que parece — paginación, territorios alfa-3, |
| Los 90 campos enumerados, generados a partir de la especificación de Apple para que no queden obsoletos |
| Qué significa cada nivel de riesgo y qué tan reversible es |
| De dónde vino cada descripción de API y cuándo |
| 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 |
| 797 | Sin cambio. |
| 238 | Cambia datos. |
| 61 | Precios, suscripciones, derechos. |
| 132 | Elimina. |
| 12 | Compilaciones, envíos, lo que se publica. |
| 12 | Quién puede acceder a la cuenta. |
| 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 aboveCuando 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 APIsLas 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 literalmakeRequest.fetch:specsanaliza el conjunto de endpoints de esa fuente en una etiqueta de versión fija, yverifylo compara con el catálogo ensrc/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 antiguosapi.storekit.itunes.apple.comya 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 failedLas 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-limitde Apple, que tiene en cuenta otros clientes que comparten la clave.x-request-idse 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
linksyrelationshipsque solo contienen enlaces, se conservalinks.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
*_decodedy 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_endpointantes 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-confirmdesactiva la puerta por completo. Existe para CI; es un valor predeterminado pobre para un agente interactivo.
Licencia
MIT
This server cannot be installed
Maintenance
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
- AlicenseBqualityCmaintenanceEnables interaction with Apple's App Store Connect API through natural language to manage apps, beta testing, localizations, analytics, sales reports, and CI/CD workflows for iOS and macOS development.3182MIT
- Flicense-qualityDmaintenanceEnables management of App Store Connect apps including registration, listing, IPA upload, store listing updates, and in-app purchase creation via natural language.
- AlicenseAqualityCmaintenanceEnables AI assistants to manage Apple App Store Connect resources like apps, builds, TestFlight, and reviews through natural language.2018MIT
- Alicense-qualityDmaintenanceEnables managing your iOS app's entire lifecycle with natural language through App Store Connect, offering 48 tools across 14 categories for ASO, reviews, analytics, subscriptions, pricing, and more.6MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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