App Store Connect
Servidor MCP para la API de App Store Connect: gestiona precios de apps iOS, suscripciones, compras integradas, TestFlight, metadatos de App Store, capturas de pantalla, eventos dentro de la app y envíos de revisiones desde Claude.
Documentación
appstoreconnect-mcp
Un servidor de Protocolo de Contexto de Modelo para la API de App Store Connect de Apple. Gestiona aplicaciones, suscripciones, precios y más desde cualquier cliente compatible con MCP (Claude Code, Claude Desktop, Cursor, Windsurf).
La primera superficie publicada es precios de suscripciones — incluyendo un flujo de reequilibrio de Paridad de Poder Adquisitivo que ya se ha utilizado para programar 120 cambios de precios en producción en 65 territorios en una aplicación iOS real. Nuevos dominios de ASC (TestFlight, ventas, capturas de pantalla, compras dentro de la aplicación) están diseñados para conectarse un archivo a la vez; consulta Hoja de ruta.
Instalación (configuración cero)
npx @akoskomuves/appstoreconnect-mcp init
El asistente:
- Abre App Store Connect → Claves para que puedas descargar un
.p8(se omite si ya tienes uno). - Copia la clave a
~/.appstore/conchmod 600. - Solicita tu ID de Emisor y el ID de Clave (auto-detectado).
- Verifica la autenticación con una llamada real a la API antes de escribir nada.
- Detecta qué clientes MCP tienes instalados — Claude Code, Claude Desktop, Cursor, Windsurf — y se registra en los que elijas.
Cuando algo parezca incorrecto más adelante, ejecuta un diagnóstico de solo lectura:
npx @akoskomuves/appstoreconnect-mcp doctor
Instalación manual
Si prefieres configurarlo a mano, añádelo a ~/.claude.json (Claude Code), claude_desktop_config.json (Claude Desktop), o el equivalente de tu cliente:
{
"mcpServers": {
"appstoreconnect": {
"command": "npx",
"args": ["-y", "@akoskomuves/appstoreconnect-mcp"],
"env": {
"ASC_ISSUER_ID": "...",
"ASC_KEY_ID": "...",
"ASC_PRIVATE_KEY_PATH": "~/.appstore/AuthKey_XXXXXXXXXX.p8"
}
}
}
}
O mediante la CLI de Claude Code:
claude mcp add appstoreconnect \
-e ASC_ISSUER_ID=... \
-e ASC_KEY_ID=... \
-e ASC_PRIVATE_KEY_PATH=~/.appstore/AuthKey_XXXXXXXXXX.p8 \
-- npx -y @akoskomuves/appstoreconnect-mcp
Configuración
Genera una clave de API de App Store Connect en App Store Connect → Usuarios y Acceso → Integraciones → Claves. Las escrituras de precios necesitan el rol de Administrador; las operaciones de solo lectura funcionan con Gestor de Aplicaciones.
| Variable | Qué es |
|---|---|
ASC_ISSUER_ID | UUID del emisor de la página de Claves |
ASC_KEY_ID | ID de clave de 10 caracteres |
ASC_PRIVATE_KEY_PATH | Ruta a tu archivo AuthKey_XXXXXXXXXX.p8 descargado (~ se expande) |
El archivo .p8 es una clave privada — nunca lo confirmes en el repositorio. Recomendado: ~/.appstore/AuthKey_XXXXXXXXXX.p8 fuera de cualquier repositorio.
Opcional: Clave de firma para compras dentro de la aplicación
Solo se necesita para las herramientas asc_sign_* (firma de canje de ofertas de suscripción). Emite una segunda clave en App Store Connect → Usuarios y Acceso → Integraciones → Compra dentro de la aplicación — esta es una clave separada de la clave de API de ASC anterior, generada en una pestaña diferente de la misma página.
| Variable | Qué es |
|---|---|
ASC_IAP_ISSUER_ID | UUID del emisor de la pestaña de claves de Compra dentro de la aplicación (diferente de ASC_ISSUER_ID) |
ASC_IAP_KEY_ID | ID de clave de 10 caracteres para la clave de IAP |
ASC_IAP_PRIVATE_KEY_PATH | Ruta al .p8 de firma de IAP (~ se expande) |
El servidor se inicia correctamente sin estos — solo las herramientas asc_sign_* se niegan con un mensaje de configuración si faltan. Configura uno o dos pero no los tres y el servidor rechaza con un error claro. Ejecuta appstoreconnect-mcp doctor para verificar que la clave se carga como un ES256 PKCS#8 válido.
Opcional: número de proveedor (informes de ventas y finanzas)
Solo se usa por asc_get_sales_report / asc_get_finance_report. Tu número de proveedor es a nivel de cuenta, se muestra en App Store Connect → Pagos e Informes Financieros junto al nombre de tu equipo (una cadena numérica como 85123456).
| Variable | Qué es |
|---|---|
ASC_VENDOR_NUMBER | Número de proveedor predeterminado para descargas de informes de ventas/finanzas |
Sin él, las dos herramientas de informes aún funcionan — solo necesitan vendorNumber pasado por llamada (y su mensaje de error te dice dónde encontrarlo). Nota: descargar informes de ventas/finanzas requiere una clave de API con el rol de Administrador, Finanzas o Ventas.
Herramientas
Aplicaciones
asc_list_apps— lista aplicaciones (filtra porbundleId)asc_get_app— obtén una aplicación por ID
Suscripciones
asc_list_subscription_groups— grupos para una aplicaciónasc_get_subscription_group— obtén un grupo por IDasc_list_subscriptions— suscripciones renovables automáticamente en un grupoasc_get_subscription— obtén una suscripción por IDasc_list_subscription_prices— programa de precios actual por suscripción. Una fila por territorio (~175 sin filtrar) — pasaterritoryIdpara limitar a un mercadoasc_list_subscription_price_points— puntos de precio válidos para una suscripción en un territorio. PasanearAmountpara limitar la respuesta a los niveles más cercanos alrededor de un precio objetivo.
Productos de suscripción (escrituras)
Crear la jerarquía en sí — el paso que solía enviarte a la interfaz web de App Store Connect. Cuatro nombres, de los cuales solo dos los ven los clientes:
| Recurso | Atributo | Quién lo ve |
|---|---|---|
SubscriptionGroup | referenceName | solo interno |
SubscriptionGroupLocalization | name | cliente — encabezado sobre las opciones de plan |
Subscription | name | solo interno |
SubscriptionLocalization | name | cliente — el plan individual |
asc_post_subscription_group— crea el contenedor en el que debe vivir cada suscripción. Un cliente puede tener solo una suscripción activa por grupo, por lo que los planes mutuamente excluyentes (Mensual vs Anual) pertenecen al mismo grupoasc_patch_subscription_group— renombra (referenceNamees el único atributo mutable; los grupos no pueden moverse entre aplicaciones)asc_delete_subscription_group— lista las suscripciones del grupo primero y se niega a nombrar del lado del cliente los productos específicos que bloquean la eliminación, en lugar de dejar que Apple devuelva un 409 simpleasc_post_subscription— crea una suscripción renovable automáticamente.productIdes permanente: no se puede cambiar, y Apple nunca permite que se reutilice en la cuenta — ni siquiera después de que se elimine la suscripción.subscriptionPeriodes opcional al crear pero requerido antes del envío; el nuevo producto comienza enMISSING_METADATAy el mensaje de éxito enumera los pasos restantesasc_patch_subscription—name,subscriptionPeriod,familySharable,reviewNote,groupLevel.productIdno tiene ruta de código aquí por construcción. Los arreglos anidados de oferta/precio no se admiten deliberadamente — su semántica de cable es reemplazar, por lo que un llamador que pase una oferta eliminaría silenciosamente el resto; usa las herramientas dedicadas de oferta y precioasc_delete_subscription— verifica previamente el estado y se niega para productos bajo revisión o aprobados alguna vez, señalando aasc_post_subscription_availabilitycomo la forma de dejar de vender un producto activo
Localizaciones de grupos de suscripción
El encabezado de grupo visible para el cliente — lo que la App Store muestra sobre las opciones de plan, y lo que aparece en Configuración → Suscripciones. Un grupo sin localizaciones no puede enviarse.
asc_list_subscription_group_localizations/asc_get_subscription_group_localizationasc_post_subscription_group_localization—name+locale, máscustomAppNameopcional (anula cómo se lee el nombre de la aplicación dentro de la hoja de suscripción; normalmente se omite). Problema de cable resuelto: la clave de relación principal essubscriptionGroup, mientras queSubscriptionllama al mismo padregroupasc_patch_subscription_group_localization—name/customAppName; la configuración regional es la clave de búsqueda inmutableasc_delete_subscription_group_localization
Precios de suscripción (escrituras)
asc_post_subscription_price— establece el precio para un territorio, ya sea el precio inicial o un cambio programado. El orden importa, y ambos pasos se confirman en vivo: disponibilidad del territorio → línea base sin fecha → cambios con fecha.- Omite
startDatepara el primer precio de una suscripción en un territorio. La fila inicial es la línea base sin fecha; un primer precio con fecha es un cambio de precio sin nada desde lo que cambiar. Apple lo dice explícitamente — "Invalid startDate. Create a starting price before creating future prices." — y la distancia no ayuda (1, 8 y 29 días después todos dan 409). - La disponibilidad debe existir primero. Sin ella, incluso un POST sin fecha correctamente formado falla, con un 409 que culpa al punto de precio (
ENTITY_ERROR.RELATIONSHIP.INVALID→/data/relationships/subscriptionPricePoint/id). El punto de precio está bien; Apple simplemente no puede poner precio a un territorio donde el producto no se vende. La herramienta traduce ambos en lugar de pasar el 409 crudo. preserveCurrentPricees verdadero por defecto en un cambio con fecha y se omite en una línea base, donde no hay cohorte existente a la que aplicar el abuelo. La fila creada se leepreserved: falsehasta que un precio más nuevo la supere; eso es esperado, no un fallo de abuelo
- Omite
asc_delete_subscription_price— cancela un cambio programado pendiente
Precios de aplicaciones (aplicaciones de pago no suscritas)
asc_list_app_prices— programa de precios actual para una aplicación, separando anulaciones manuales de precios derivados automáticamente y mostrando el territorio baseasc_list_app_price_points— niveles de precio válidos de Apple para una aplicación en un territorio dado (~600+ niveles por territorio). PasanearAmount(precio objetivo) ynearCountopcional (predeterminado 10) para limitar la respuesta a los niveles más cercanos — Apple no admite un filtro de cantidad cercana en el servidor, por lo que la lista completa aún se pagina pero solo se muestran los niveles más cercanos.asc_post_app_price_schedule— reemplaza todo el programa de precios (reemplazo de programa completo, NO una fusión — coincide con la API de Apple). La verificación previa se niega a menos que al menos una entrada apunte al territorio base sinstartDate, y requiereacknowledgeReplacesAll: trueexplícito. Se requiere un acuse de recibo separado deacknowledgeDeletesScheduledIfBaseChangesal cambiar el territorio base (Apple borra los cambios programados pendientes en el cambio de base). Las aplicaciones no tienen mecanismo de abuelo — los nuevos programas se activan atómicamente en elstartDatede cada entrada.
Compras dentro de la aplicación (consumibles, no consumibles, suscripciones no renovables)
asc_list_iaps— lista IAP para una aplicación (solo superficie v2 — las suscripciones renovables automáticamente están cubiertas por las herramientas de Suscripciones anteriores). Filtrable porinAppPurchaseTypeystate. Si esto devuelve cero filas para una aplicación que sabes que tiene IAP, las IAP pueden ser solo heredadas y necesitan migrarse en la interfaz web de App Store Connect antes de aparecer aquí.asc_get_iap— obtén una sola IAP por ID.asc_list_iap_prices— programa de precios actual para una IAP (misma forma que los precios de aplicaciones: anulaciones manuales + derivadas automáticamente + territorio base).asc_list_iap_price_points— niveles de precio válidos de Apple para una IAP en un territorio dado. Mismo estrechamiento denearAmount/nearCountque las herramientas de puntos de precio de aplicaciones y suscripciones.asc_post_iap_price_schedule— reemplaza todo el programa de precios de IAP (misma semántica de reemplazo de programa completo queasc_post_app_price_schedule:acknowledgeReplacesAll: true, entrada de territorio base sinstartDate, acuse de recibo de cambio de base requerido). Sin mecanismo de abuelo — igual que las aplicaciones.
Ofertas introductorias de suscripción
Las ofertas introductorias se dirigen a suscriptores nuevos — la "primera ventana" con descuento antes de que el precio regular entre en vigor.
asc_list_subscription_introductory_offers— lista ofertas introductorias (prueba gratuita / pago por uso / pago por adelantado) configuradas para una suscripción, en todos los territorios. El comodín de "todos los territorios" de Apple (una sola oferta sinterritory) aparece comoTERR=(all)en la tabla. PasaterritoryIdpara limitar a un mercado — las ofertas comodín siempre se mantienen, ya que están activas en todas partes.asc_get_subscription_introductory_offer— obtén una oferta por ID.asc_post_subscription_introductory_offer— crea una oferta. TresofferModes:FREE_TRIAL(sin precio; omitepricePointId),PAY_AS_YOU_GO(cobra el precio de la oferta cada período durantenumberOfPeriodsperíodos),PAY_UP_FRONT(cargo único por toda la duración; Apple aún requierenumberOfPeriods— predeterminado a 1 cuando se omite). PasaterritoryIdpara apuntar a un mercado, u omítelo para el comodín de "todos los territorios" de Apple (usa el punto de precio literal en cada mercado — sin FX automático). La validación del lado del servidor se niega aPAY_*sinpricePointId,PAY_AS_YOU_GOsinnumberOfPeriods, yendDate ≤ startDate— el error de Apple se muestra en línea de lo contrario.asc_patch_subscription_introductory_offer— ruta de actualización limitada: solostartDate,endDateypricePointIdpueden cambiar después de la creación. Para cambiar modo / duración / períodos, elimina y vuelve a crear.asc_delete_subscription_introductory_offer— elimina una oferta pendiente o activa. Apple se niega a eliminar una que actualmente es canjeable; PATCHendDatea hoy para detenerla en su lugar.
Ofertas promocionales de suscripción
Las ofertas promocionales están dirigidas a suscriptores existentes o caducados — elegibilidad opuesta a las ofertas introductorias, establecida por el propio tipo de recurso (sin indicador por oferta). Apple limita las ofertas promocionales activas a 10 por suscripción. Después de la creación, solo se pueden editar los precios por territorio — name, offerCode, offerMode, duration y numberOfPeriods son inmutables.
asc_list_subscription_promotional_offers— lista las ofertas promocionales configuradas para una suscripción.asc_get_subscription_promotional_offer— obtiene una oferta individual, incluidos sus precios por territorio.asc_list_subscription_promotional_offer_prices— lista las filas de precios por territorio asociadas a una oferta (territorio + moneda + importe + ID de punto de precio).asc_post_subscription_promotional_offer— crea una oferta (name+offerCode+ modo + duración + todos los precios por territorio) en un único POST atómico. Verifica previamente el límite de 10 ofertas de Apple y las colisiones deofferCode, rechazando con un mensaje de solución claro en lugar de dejar que Apple devuelva un 409.asc_patch_subscription_promotional_offer_prices— actualiza los precios por territorio de la oferta. La semántica de red de Apple es de reemplazo (el nuevo array de precios se convierte en el estado posterior, eliminando cualquier territorio no listado); el parámetromode: 'replace' | 'add' | 'remove'de la herramienta oculta esta trampa —'add'lee los precios actuales y los fusiona,'remove'los lee y filtra.asc_delete_subscription_promotional_offer— DELETE → 204.
Ofertas de recuperación de suscripción
Las ofertas de recuperación están dirigidas a suscriptores caducados — clientes que se suscribieron anteriormente y se dieron de baja — y Apple las muestra automáticamente a clientes elegibles según las reglas de elegibilidad de la oferta (o mediante tu propio mensajería de StoreKit). Este es el tercer tipo de oferta junto con las introductorias y promocionales. Son más ricas que las ofertas promocionales: añaden segmentación de elegibilidad, un calendario, prioridad y una intención de recurso automático. referenceName, offerId, duration, offerMode, periodCount, targetSubscriptionPlanType y los precios son inmutables después de la creación.
asc_list_subscription_win_back_offers— lista las ofertas de recuperación configuradas para una suscripción.asc_get_subscription_win_back_offer— obtiene una oferta individual, incluida su suscripción y precios por territorio.asc_list_subscription_win_back_offer_prices— lista las filas de precios por territorio asociadas a una oferta (territorio + moneda + importe + ID de punto de precio).asc_post_subscription_win_back_offer— crea una oferta (identidad + reglas de elegibilidad + calendario + prioridad + todos los precios por territorio) en un único POST atómico. La elegibilidad se expresa comocustomerEligibilityPaidSubscriptionDurationInMonths,customerEligibilityTimeSinceLastSubscribedInMonths(un rango de{ minimum, maximum? }) y uncustomerEligibilityWaitBetweenOffersInMonthsopcional. Verifica previamente las colisiones deofferIdy valida el rango +endDate > startDate.asc_patch_subscription_win_back_offer— actualiza solo los atributos mutables: elegibilidad,startDate/endDate,priorityypromotionIntent. Para cambiar identidad, modo, duración, periodos o precios, elimina y vuelve a crear.asc_delete_subscription_win_back_offer— DELETE → 204.
Recursos de revisión de compras dentro de la app y suscripciones
La captura de pantalla de revisión que Apple requiere antes de que una compra dentro de la app o suscripción pueda enviarse, más las imágenes promocionales opcionales — y, desde la v1.5, los adjuntos de revisión de App Review de una versión (archivos para el revisor, p. ej., un vídeo de demostración). Cinco recursos, cada uno con el mismo flujo de carga de tres pasos que las capturas de pantalla de la app (reservar → subir fragmentos → confirmar), con una herramienta compuesta asc_upload_* que hace los tres desde un archivo local. La trampa de red se maneja por ti: la imagen de la compra dentro de la app se relaciona mediante inAppPurchase, mientras que la captura de pantalla de revisión de la compra dentro de la app usa inAppPurchaseV2.
- Imágenes (de muchos a muchos, por compra dentro de la app / suscripción):
asc_list_{iap,subscription}_images·asc_get_*·asc_upload_*(compuesta) ·asc_post_*/asc_patch_*(reserva/confirmación en bruto) ·asc_delete_*. - Capturas de pantalla de revisión (de uno a uno, por compra dentro de la app / suscripción):
asc_get_{iap,subscription}_review_screenshot(devuelve la única, o null) ·asc_upload_*·asc_post_*/asc_patch_*·asc_delete_*. Como es de uno a uno, las herramientas de carga/reserva se niegan si ya existe una — elimínala primero. - Adjuntos de revisión de App Review (de muchos a muchos, por detalle de revisión de versión):
asc_list_review_attachments·asc_get_review_attachment·asc_upload_review_attachment(compuesta) ·asc_post_*/asc_patch_*·asc_delete_*. El ID principal es el ID deappStoreReviewDetaildeasc_get_app_store_review_detail.
Detalles de revisión de App Review, envíos y publicación
Los últimos pasos manuales entre "los metadatos están listos" y "la compilación está en vivo":
asc_get_app_store_review_detail/asc_post_…/asc_patch_…— la tarjeta de Qué-decir-a-App-Review de una versión: persona de contacto, cuenta de demostración (nombre/contraseña/requerida), notas. De uno a uno por versión; Apple fusiona en PATCH.asc_post_app_store_version_release_request— ⚠️ publica una versión aprobada (PENDING_DEVELOPER_RELEASE) en la App Store pública ahora — el clic de "Publicar esta versión", automatizado. Solo para versiones de publicación manual; sin deshacer.asc_post_iap_submission/asc_post_subscription_submission/asc_post_subscription_group_submission— envía los cambios de metadatos pendientes de una compra dentro de la app / suscripción / grupo de suscripciones para revisión de forma independiente, sin una publicación de versión. La trampa de red se maneja: la de la compra dentro de la app se relaciona medianteinAppPurchaseV2.asc_get_subscription_grace_period/asc_patch_…— periodo de gracia de facturación por app:optIn/sandboxOptIn, duración (3 / 16 / 28 días),renewalType(todas las renovaciones vs solo de pago a pago). Mantiene a los suscriptores caducados con derecho mientras Apple reintenta el pago.
Disponibilidades (suscripciones, compras dentro de la app, planes)
Disponibilidad por territorio de productos dentro de la app — el hermano de Disponibilidad de App con una diferencia clave: el vínculo de territorio usa códigos ISO de 3 letras simples (territories simple), no los compuestos opacos que usan las apps.
- Suscripciones:
asc_get_subscription_availability·asc_list_subscription_available_territories·asc_post_subscription_availability(reemplazo completo solo POST — envía la lista completa de territorios; ⚠️ los territorios eliminados dejan de estar a la venta). - Compras dentro de la app:
asc_get_iap_availability(lee a través de la ruta principal v2) ·asc_list_iap_available_territories·asc_post_iap_availability(misma semántica de reemplazo). - Planes de suscripción (por tipo de plan
MONTHLY/UPFRONT):asc_list_subscription_plan_availabilities·asc_list_subscription_plan_available_territories·asc_post_…·asc_patch_…(el único recurso de disponibilidad con PATCH).
Firma de ofertas de suscripción (canje dentro de la app)
El firmante criptográfico que hace que las ofertas promocionales/introductorias sean canjeables en tu app de iOS mediante StoreKit. Usa una clave de firma separada de la clave de API de ASC — emitida en App Store Connect → Usuarios y Acceso → Integraciones → Compra dentro de la app. Consulta la sección de configuración opcional para las variables de entorno. Basado en el @apple/app-store-server-library oficial de Apple.
asc_sign_promotional_offer_legacy— firma heredada concatenada ECDSA utilizada porSKPaymentDiscountde StoreKit 1 y la API originalProduct.PurchaseOption.promotionalOffer(offerID:keyID:nonce:signature:timestamp:)de StoreKit 2. Devuelve la firma base64 más el nonce, la marca de tiempo y el keyId para que el llamador los pase a StoreKit. Genera automáticamente un nonce UUID y la marca de tiempo actual; ambos se pueden sobrescribir para pruebas.asc_sign_promotional_offer— formato JWS v2 presentado en WWDC 2025 (implementado retroactivamente en iOS 15). Úsalo con las opciones de compra de ofertas promocionales más nuevas de StoreKit 2. Devuelve directamente la serialización compacta JWS.transactionId(elappTransactionIddel cliente) es opcional pero muy recomendado.asc_sign_introductory_offer_eligibility— JWS v2 conaud="introductory-offer-eligibility". Te permite sobrescribir la verificación de elegibilidad predeterminada de ofertas introductorias de StoreKit (p. ej., conceder a un cliente que regresa otra prueba). Nuevo en WWDC 2025.
Todas las firmas son válidas durante 24 horas desde el momento de la firma — vuelve a firmar en cada intento de canje en lugar de prefirmar y almacenar en caché.
Clasificación por edad
El cuestionario con el que App Review evalúa una app — bloquea el envío, y anteriormente no había forma de configurarlo desde aquí.
asc_get_age_rating_declaration— lee las respuestas. Muestra solo las no predeterminadas (una declaración típica tiene 29 atributos, casi todos enNONE/false) más cada sobrescritura, para que las pocas que realmente determinan la clasificación destaquen.asc_patch_age_rating_declaration— responde el cuestionario. Las preguntas de contenido toman una frecuencia (NONE/INFREQUENT_OR_MILD/FREQUENT_OR_INTENSE); el resto son booleanos, más las sobrescrituras de clasificación y la banda de edad para niños.
Dos cosas sobre este recurso son fáciles de hacer mal, así que las herramientas las manejan por ti. Cuelga de AppInfo, no de la versión — la clasificación por edad son metadatos por app como las categorías, y /v1/appStoreVersions/{id}/ageRatingDeclaration devuelve 404. Y su ID es el ID de AppInfo, así que pasar appId resuelve el objetivo automáticamente (si una app tiene varios AppInfos en pistas de notarización, la herramienta informa los candidatos en lugar de adivinar).
Apple fusiona al escribir: las claves omitidas mantienen su valor actual, así que una actualización parcial es segura — pero no puedes borrar una respuesta omitiéndola, tienes que enviar el NONE/false explícito. Las sobrescrituras solo elevan la clasificación, nunca la bajan.
Xcode Cloud (CI/CD)
El lado de compilación del bucle de envío: observa ejecuciones, lee fallos, lanza compilaciones. Jerarquía: productos → flujos de trabajo → ejecuciones de compilación → acciones (compilar/probar/archivar/analizar) → problemas / resultados de pruebas / artefactos. Una ejecución finalizada vincula las compilaciones de TestFlight que produjo, pasando el testigo a las herramientas de TestFlight.
- Lecturas:
asc_list_ci_products·asc_list_ci_workflows/asc_get_ci_workflow(resumen de configuración compacto: indicadores, patrones de condición de inicio, acciones, Xcode/macOS resueltos —raw:truepara el documento completo de ~90k caracteres de Apple) ·asc_list_ci_build_runs(por flujo de trabajo o producto) /asc_get_ci_build_run·asc_list_ci_build_actions·asc_list_ci_issues·asc_list_ci_test_results·asc_list_ci_artifacts/asc_get_ci_artifact(prefirmado, con límite de tiempodownloadUrl— obténlo sin el portador de ASC) ·asc_list_ci_build_run_builds(el traspaso de TestFlight) ·asc_list_ci_environment_versions(catálogos de Xcode/macOS). - Lecturas de SCM:
asc_list_scm_providers·asc_list_scm_repositories·asc_list_scm_git_references(IDs de referencia de rama/etiqueta — lo que toma el inicio de compilación) ·asc_list_scm_pull_requests. - Disparadores:
asc_post_ci_build_run(inicia una compilación — sobrescritura opcional de rama/etiqueta +clean; usa las horas de cómputo del equipo) ·asc_patch_ci_workflow(pausar/reanudar medianteisEnabled,clean, nombre, descripción — las condiciones de inicio y acciones siguen siendo propiedad de Xcode por diseño).
Nominaciones para destacados
Presenta una versión al equipo editorial de Apple para que aparezca en la App Store (pestaña Hoy, colecciones seleccionadas). Los borradores son privados; el envío es unidireccional.
asc_list_nominations(filtrar por app / estado / tipo) ·asc_get_nomination·asc_post_nomination(por defecto es un BORRADOR revisable —submitted:false) ·asc_patch_nomination(editar el borrador;submitted:truelo envía a Apple — sin desenviar, soloarchived:true) ·asc_delete_nomination.- La propuesta viaja en
description+notes;publishStartDate/publishEndDateenmarcan la ventana de relevancia;supplementalMaterialsUrisllevan enlaces de kit de prensa/TestFlight;launchInSelectMarketsFirstes la clave de red (Mercados, no la redacción de "tiendas" de la interfaz).
Aprovisionamiento y firma de código
La superficie del Developer portal (territorio de fastlane match/sigh/cert). Restricción de rol: necesita una clave de API de Admin (o Titular de cuenta) — las claves de App Manager/Developer reciben 403 aquí (las herramientas lo explican).
- Bundle IDs:
asc_list_bundle_ids(filtro de identificador) ·asc_get_bundle_id(con capacidades + perfiles) ·asc_post_bundle_id(identificador inmutable — verifica la cadena de DNS inverso) ·asc_patch_bundle_id(solo renombrar) ·asc_delete_bundle_id(rechazado mientras una app esté adjunta). - Capacidades:
asc_post_bundle_id_capability·asc_patch_bundle_id_capability·asc_delete_bundle_id_capability— los cambios de capacidad invalidan los perfiles existentes; regenéralos después. - Certificados:
asc_list_certificates·asc_get_certificate(contenido DER en base64) ·asc_post_certificate(a partir de un CSR PEM — la clave privada nunca va a Apple) ·asc_delete_certificate(⚠️ ELIMINAR = revocar; la firma de CI con él se rompe inmediatamente). - Perfiles:
asc_list_profiles·asc_get_profile(profileContent= el.mobileprovisionbase64 real) ·asc_post_profile·asc_delete_profile. No hay PATCH — los perfiles son inmutables; rota mediante eliminar + recrear. - Dispositivos:
asc_list_devices·asc_post_device(⚠️ efectivamente permanente — los dispositivos solo se pueden deshabilitar, nunca eliminar, y cuentan contra el límite anual de 100 por clase) ·asc_patch_device(renombrar, ENABLED/DISABLED).
Probadores de sandbox
Cuentas de prueba de StoreKit, para ejercitar la superficie de monetización de extremo a extremo. Los probadores se crean en la interfaz de ASC; la API gestiona sus ajustes.
asc_list_sandbox_testers·asc_patch_sandbox_tester(territorio,interruptPurchases,subscriptionRenewalRateacelerado — un mes de suscripción se renueva cada 3–60 minutos) ·asc_post_sandbox_testers_clear_purchase_history(borrado solo de sandbox para que los flujos de compra se puedan volver a probar; también restablece la elegibilidad de ofertas introductorias).
Territorios
asc_list_territories— los 175 territorios de la App Store
Reequilibrio de PPP
ppp_load_index— devuelve la instantánea de precios del plan Individual de Apple Music incluida, utilizada como señal de PPPppp_compute_proposal— calcula un calendario de precios propuesto por territorio (simulación de solo lectura; usa las proporciones de Apple Music como PPP-FX implícito, ajusta a puntos de precio válidos de Apple, aplica una estrategia de redondeo y un mínimo configurables). PasaresourceType: "subscription"(predeterminado) consubscriptionId,resourceType: "app"conappIdpara apps de pago,resourceType: "iap"coniapId,resourceType: "introductoryOffer"consubscriptionIdmásofferMode/duration(ynumberOfPeriodsparaPAY_AS_YOU_GO;PAY_UP_FRONTlo establece en 1 por defecto), oresourceType: "promotionalOffer"consubscriptionIdmásofferMode/duration/promoOfferName/promoOfferCode(ynumberOfPeriodsparaPAY_AS_YOU_GO;PAY_UP_FRONTlo establece en 1 por defecto).ppp_apply_proposal— recalcula y aplica la propuesta contra ASC después de confirmar mediante elicitación de MCP (oconfirm: truepara uso desatendido). Se rechaza si alguna fila cae más demaxDropPct(90% por defecto); omite territorios donde la moneda de facturación de ASC ≠ moneda de Apple Music.- Para suscripciones: POSTs de
subscriptionPricespor territorio, con ritmo demaxConcurrency(2 por defecto), reintentando 429s automáticamente; los suscriptores existentes se mantienen conpreserveCurrentPrice: true(predeterminado). - Para apps e IAPs: un único POST de reemplazo completo del calendario (una llamada HTTP, atómica). Las apps/IAPs no tienen mecanismo de abuelo — los nuevos precios se activan en el
startDatede cada entrada. RequiereacknowledgeDeletesScheduledIfBaseChanges: trueal cambiar el territorio base (Apple borra los cambios programados pendientes al cambiar la base). - Para ofertas introductorias: POSTs de
subscriptionIntroductoryOfferspor territorio, con ritmo demaxConcurrency. La columna Δ compara el precio de oferta ajustado contra el precio regular actual de la suscripción en ese territorio, por lo que-50%significa que la oferta está a mitad de precio de la suscripción.FREE_TRIALse rechaza (sin precio que calcular — usaasc_post_subscription_introductory_offerconterritoryIdomitido para una prueba gratuita global única). Las ofertas introductorias son adiciones, no reemplazos — Apple devuelve 409 si ya existe una oferta activa para una celda de(sub, territory), y esas filas se muestran comofaileden la tabla de resultados. - Para ofertas promocionales: un único POST atómico a
/v1/subscriptionPromotionalOfferscrea la oferta + todos los precios PPP ajustados por territorio en una sola solicitud. Solo creación — se rechaza siofferCodecolisiona con una oferta existente o la suscripción está en el límite de 10 ofertas de Apple.FREE_TRIALrechazado (sin precio que calcular). Mismo informe de Δ vs precio actual de suscripción que las ofertas introductorias.
- Para suscripciones: POSTs de
Forma de la respuesta
Cada herramienta de listar/obtener devuelve una tabla de texto compacta por defecto — diseñada para que un LLM la lea sin quemar contexto. Cada herramienta también acepta:
raw: true— devuelve el payload JSON:API completo (data,included,links,meta) para depuración o uso avanzado.maxItems: number— limita la paginación automática (500–1000 por defecto según la herramienta). El MCP siguelinks.nexty fusiona + deduplica los recursos deincludedentre páginas.
Los fieldsets dispersos (fields[type]=...) se aplican por herramienta para evitar extraer atributos no utilizados. El calendario de precios completo de 175 territorios vuelve en una llamada paginada (200/página) a aproximadamente 1/10 del tamaño del payload sin filtrar.
Soporte de protocolo
Habla la revisión MCP 2026-07-28 y el protocolo de la era 2025 de la misma compilación — tu cliente elige. No hay nada que configurar en ningún caso.
En 2026-07-28 el servidor es sin estado (sin handshake de initialize; las capacidades vienen de server/discover), y el aviso de confirmación de escritura usa solicitudes de múltiples rondas: ppp_apply_proposal devuelve un resultado de input_required, tu cliente muestra el acuse de recibo, y la misma llamada de herramienta se reemite con tu respuesta. A los clientes que no soportan elicitación se les dice que vuelvan a ejecutar con confirm: true, exactamente como antes.
La propuesta se recalcula al reingresar en lugar de llevarse a través de la ronda, por lo que los precios se releen de App Store Connect inmediatamente antes de escribir nada — nunca se reutilizan de antes de que te detuvieras a considerar. El costo es que una aplicación interactiva calcula dos veces: en una suscripción de 64 territorios eso es aproximadamente 95s en lugar de 48s. Las ejecuciones desatendidas con confirm: true nunca preguntan, por lo que calculan una vez y no se ven afectadas.
Comportamiento en producción
Algunos detalles que vale la pena conocer antes de ejecutar ppp_apply_proposal contra una cuenta de App Store Connect en vivo:
- Manejo de límite de tasa. Apple limita los endpoints POST alrededor de 50/min.
client.requestrespeta los encabezados deRetry-Aftery cae en backoff exponencial (2s → 60s, con tope, hasta 6 reintentos). Un reequilibrio de 60 territorios con ritmo a través de reintentos termina en aproximadamente 2 minutos de tiempo real con cero intervención manual. - Omisión por discrepancia de moneda. Si el índice de Apple Music incluido lista un territorio en una moneda (digamos BHD) pero ASC factura tu suscripción en otra (USD), la proporción PPP-FX se rompe dimensionalmente. La propuesta marca esas filas como
currency-mismatch (asc=USD, am=BHD)y las excluye del conjunto de aplicación. Común en mercados del Golfo facturados en USD (BHR, KWT, OMN). Establécelas manualmente si quieres. - Mínimo de cordura.
floorFactor(0.15 por defecto) es un límite inferior duro en las caídas por territorio como fracción del precio actual — protege contra una entrada de índice obsoleta que colapse un precio a casi cero. Para un reequilibrio más conservador, pasa 0.30 o 0.50. - Techo de cordura en caídas.
maxDropPct(90% por defecto) se niega a aplicar cualquier ejecución donde una sola fila caiga más de esto. Si alguna vez has visto a Apple Music hundir agresivamente un precio de mercado, esto atrapa el valor atípico resultante antes de que lo escribas en ASC. - Actualiza la instantánea cuando te importe.
data/apple-music-prices.jsones una instantánea curada a mano. Cada entrada está fechada; la fecha de la instantánea se muestra en la salida de la propuesta. Solicita una actualización mediante pull request cuando los precios de Apple Music se muevan y el proyecto la incorporará.
Informes de error anónimos (opt-in, desactivados por defecto)
Este servidor guarda tus credenciales de App Store Connect, por lo que el listón para que algo salga de tu máquina es alto. La telemetría está desactivada a menos que la actives explícitamente, y no hay paso de "activado por defecto, desactívalo después".
appstoreconnect-mcp init pregunta una vez. Cámbialo en cualquier momento:
appstoreconnect-mcp telemetry status
appstoreconnect-mcp telemetry on
appstoreconnect-mcp telemetry off
Qué se envía
| Enviado | Nombre de la herramienta (asc_patch_subscription_localization), estado HTTP (409), code de error de Apple (ENTITY_ERROR.ATTRIBUTE.INVALID.UNMODIFIABLE), title genérico de Apple, el puntero JSON (/data/attributes/state), versión del paquete, versión de Node, SO + arquitectura, y un UUID de instalación aleatorio. Más un ping de actividad por día. |
| Nunca enviado | Texto del detail de error de Apple, URLs o rutas de solicitudes, IDs de app, bundle IDs, nombres de app, precios, nombres de suscripciones, cualquier cuerpo de solicitud o respuesta, tu issuer ID, key ID, o cualquier credencial. La geolocalización está explícitamente deshabilitada ($geoip_disable), por lo que no se registra ciudad derivada de IP, código postal o coordenadas. |
El depurador es una lista de permitidos, no una lista de bloqueados: un campo que Apple agregue mañana está ausente por construcción en lugar de por revisión. Está reforzado por pruebas en tests/telemetry-scrubbing.test.ts, que afirman sobre lo ausente tan firmemente como sobre lo presente.
Por qué
Para que un error como "Apple empezó a rechazar cada asc_patch_subscription_localization con un 409" aparezca como una señal en lugar de esperar a que alguien presente un issue. Ese es un ejemplo real — se encontró a mano, y esta es la versión automatizada de eso.
Desactivándolo en todas partes
DO_NOT_TRACK=1se respeta y supera un opt-in explícito.ASC_MCP_TELEMETRY=0desactiva de forma dura;=1activa para esa ejecución sin registrar consentimiento en disco.ASC_MCP_TELEMETRY_HOST/ASC_MCP_TELEMETRY_KEYapuntan un fork a su propio recolector.
El transporte es de fuego y olvido detrás de un timeout de 3s: nunca bloquea una llamada de herramienta, nunca lanza, y nunca escribe a stdout (ese flujo es el canal del protocolo MCP).
Habilidad de reequilibrio de PPP
El directorio examples/ppp-rebalance/ contiene una habilidad de Claude Code que envuelve estas herramientas en un flujo de trabajo de Paridad de Poder Adquisitivo (simulación → calendario → reversión) con los problemas incorporados.
mkdir -p ~/.claude/skills && \
ln -s "$PWD/examples/ppp-rebalance" ~/.claude/skills/ppp-rebalance
Luego pregunta a Claude: "Reequilibra mis precios de suscripción usando la habilidad ppp-rebalance."
Hoja de ruta
v0.1–v1.0 cubren monetización + distribución beta + la superficie completa de la página de producto de la App Store + eventos promocionales en vivo + territorio / despliegue / cumplimiento de exportación + notificaciones push + informes de ingresos/analítica + comentarios de clientes + pruebas A/B de página de producto + salud/accessibilidad en tiempo de ejecución + pre-órdenes/FX real + distribución alternativa DMA de la UE: la superficie completa de precios/IAP/ofertas (suscripciones, apps de pago, IAPs, ofertas introductorias, ofertas promocionales, campañas de códigos de oferta, firmantes), TestFlight (builds, grupos beta, probadores beta, localizaciones beta, envíos de revisión beta), el texto de la página de producto por locale (notas de versión, descripciones, palabras clave, texto promocional), el ciclo de vida de lanzamiento (escritura de versión de App Store + envío de revisión V2), superficies de App Info / categoría / etiqueta / palabras clave de búsqueda (v0.12), carga de capturas de pantalla + vistas previas + páginas de producto personalizadas (v0.13), eventos en la app + compras promocionadas (v0.14), disponibilidad de la app + lanzamiento por fases + declaraciones de cifrado (v0.15), el bucle de retroalimentación de TestFlight — capturas de pantalla/fallos de retroalimentación beta, notificaciones de build, criterios de reclutamiento de enlace público (v0.16), webhooks — push de eventos por app con historial de entrega, reentrega y pings de prueba (v0.17), descargas de informes de ventas/finanzas + la cadena de informes de Analytics (v0.18), reseñas de clientes — leer, responder, resumir (v0.19), experimentos de versión de App Store — pruebas A/B de página de producto con tratamientos + activos de variante (v0.20), superficies de diagnóstico/rendimiento/accessibilidad (v0.21), pre-órdenes por territorio + PPP de FX real (v0.22), y distribución alternativa DMA de la UE (v1.0). La hoja de ruta planificada está completa. El resto es terreno fértil para operaciones impulsadas por LLM porque gran parte del trabajo de la App Store es texto con mucho juicio — respuestas a reseñas, posicionamiento de precios — que un modelo puede redactar y un humano aprueba.
| Fase | Dominio | Qué desbloquea |
|---|---|---|
| v0.1 ✓ | Apps · suscripciones · precios de suscripción · reequilibrio de PPP | Programar cambios de precios por territorio según el poder adquisitivo. |
| v0.2.0 ✓ | Precios de apps (no suscripciones): lista / puntos de precio de lista / programación de reemplazo · cálculo de PPP extendido a apps | Prueba de PPP en apps de pago; aplicación manual mediante asc_post_app_price_schedule. |
| v0.3.0 ✓ | Compras dentro de la app (v2): lista / obtener / lectura y escritura de programación de precios | La misma superficie de monetización para IAP (consumibles, no consumibles, suscripciones no renovables). Las renovables automáticas permanecen en las herramientas de Suscripciones. |
| v0.4.0 ✓ | ppp_apply_proposal aplicación automática para apps + IAP · PPP para IAP · filtro nearAmount en listados de puntos de precio | Reequilibrio de PPP de una sola vez para todas las superficies de pago, no solo suscripciones. |
| v0.5.0 ✓ | Ofertas introductorias de suscripción (prueba gratuita / pago por uso / pago por adelantado): lista / obtener / publicar / parchear / eliminar · PPP extendido a ofertas introductorias | Promociones de "primer mes" / "primeros tres meses" conscientes de PPP que se adaptan al poder adquisitivo local en lugar de un $0.99 literal en todas partes. |
| v0.6.0 ✓ | Ofertas promocionales de suscripción (suscriptores existentes/vencidos): lista / obtener / publicar / parchear precios / eliminar · PPP extendido a ofertas promocionales (solo creación, POST único atómico) | Campañas de recuperación con precios por territorio conscientes de PPP. |
| v0.7.0 ✓ | Firma de ofertas de suscripción: tres firmantes (ECDSA heredado, JWS v2 promocional, JWS v2 elegibilidad introductoria) que cubren todos los formatos actuales compatibles con Apple | Canje de StoreKit de extremo a extremo: las ofertas promocionales de v0.6 ahora son utilizables en una app de iOS, no solo configurables en ASC. |
| v0.8.0 ✓ | Códigos de oferta de suscripción (CRUD de campaña menos D · precios por territorio · lotes de códigos de un solo uso · exportación de texto/csv mediante /values) · PPP extendido a campañas de códigos de oferta | Campañas de canje de códigos promocionales (App Store Connect → "Códigos de oferta"): generar, desactivar, exportar CSV. |
| v0.8.1 ✓ | Seguimientos de códigos de oferta de suscripción: códigos personalizados (de uso múltiple) (lista/publicar/parchear) · environment: SANDBOX|PRODUCTION en creación de lotes · autoRenewEnabled en creación de campañas · el resumen de campaña ahora muestra recuentos de códigos autoRenew + prod/sbx · la aplicación de PPP reenvía autoRenewEnabled | Cadenas canjeables públicas (una cadena, muchos canjes) + etiquetado de lotes sandbox vs producción + códigos de oferta de un solo uso no renovables. |
| v0.9.0 ✓ | Superficie de TestFlight en 5 subdominios: builds (lista/obtener/expirar/detalle de build beta) · grupos beta (CRUD + vinculación de evaluadores + vinculación de builds) · evaluadores beta (CRUD + envío/reenvío de invitaciones) · localizaciones de builds beta (CRUD por build × locale) · localizaciones de apps beta (CRUD por app × locale) · envíos de revisión de apps beta + detalles · versiones de prelanzamiento (solo lectura). 32 herramientas nuevas. | "Invita a estos 30 evaluadores al nuevo build con esta nota de prueba en EN/ES/JA." |
| v0.10.0 ✓ | Localizaciones de página de producto de App Store en 4 superficies: versiones de App Store (lista/obtener solo lectura) · localizaciones de versiones de App Store (CRUD — notas de versión / descripción / palabras clave / texto promocional / URLs de marketing y soporte) · localizaciones de suscripciones (CRUD — nombre + descripción por locale) · localizaciones de IAP (CRUD — misma forma en superficie IAP v2). 17 herramientas nuevas. | La mayor victoria para LLM. Traduce notas de versión a 35 locales usando localizaciones existentes como referencia de voz, presenta el diff, empuja con aprobación. |
| v0.10.1 ✓ | Corrección: preverificación consciente del estado en asc_patch_app_store_version_localization — rechaza lotes de campos incompatibles en el cliente con {state, allowed, blocked, reason, nextEditablePath} antes del 409 STATE_ERROR de Apple. Descripción de MarketingUrlSchema reescrita para diferenciar página de producto de App Store vs superficies de TestFlight. | Evita PATCH de ida y vuelta desperdiciados contra versiones de READY_FOR_SALE. |
| v0.11.0 ✓ | Superficie de escritura de versión de App Store (crear / parchear / eliminar con eliminación restringida por estado) + flujo de envío de revisión V2 (crear borrador → agregar elementos → enviar/cancelar + lecturas de estado). Cierra el bucle de lanzamiento: envía una nueva versión de extremo a extremo a través del MCP sin abrir ASC. | "Traduce notas de versión a 35 locales y envía la versión 2.5 para revisión." |
| v0.12.0 ✓ | Información de app (lista/obtener + PATCH restringido por estado para relaciones de categoría) · CRUD de AppInfoLocalization (nombre + subtítulo + URLs de privacidad + texto de privacidad por locale) · catálogo de AppCategory (solo lectura con subcategorías incluidas) · AppTag (lista por app + PATCH de visibilidad visibleInAppStore) · superficie de lectura agregada de SearchKeywords (filtro por plataforma + locale). 12 herramientas nuevas. | "Cambia la categoría secundaria de tu app de Viajes a Deportes, luego actualiza el subtítulo en los 13 locales." |
| v0.13.0 ✓ | Carga de activos: capturas de pantalla + vistas previas de app (reserva de tres pasos / PUT por fragmentos / confirmación, expuestos como atajos compuestos (asc_upload_screenshot, asc_upload_app_preview) Y variantes crudas de tres pasos para control manual). Páginas de producto personalizadas: CRUD de página + versión + localización con restricción de estado en la versión. Errores de clave de cable fijados (isUploaded→uploaded, isVisible→visible, videoURL→videoUrl) y omisión de bloque sin atributos en creación de versión CPP. ~25 herramientas nuevas. | "Genera capturas de pantalla de App Store para 12 locales a partir de estos archivos fuente, empújalas a una variante de página de producto personalizada llamada paid-ads-summer." |
| v0.14.0 ✓ | Eventos dentro de la app: CRUD de AppEvent + AppEventLocalization con restricción de estado de 10 valores (rechaza WAITING_FOR_REVIEW / IN_REVIEW), arreglos de TerritorySchedule (ISO 8601), y carga de capturas de evento + clips de video (compuesto + crudo de tres pasos, reutilizando los ayudantes de carga de activos de v0.13). Compras promocionadas: CRUD + vinculación de orden por app (PATCH de arreglo simple; orden del arreglo = orden de tienda). Errores de clave de cable fijados: isUploaded→uploaded, isVisibleForAllUsers→visibleForAllUsers, isEnabled→enabled. ~28 herramientas nuevas. | "Crea un evento dentro de la app 'Comienza la temporada de salmón' para tu app que se ejecute del 2026-06-15 al 2026-07-15." |
| v0.15.0 ✓ | Disponibilidad de app v2 (solo POST de reemplazo completo; los códigos ISO de 3 letras SON los IDs; herramienta final de pedidos anticipados) + Lanzamiento por fases (PATCH de ciclo de vida de 4 estados en AppStoreVersion) + Declaraciones de cifrado (declaraciones solo de agregado + vinculación de builds + carga de documento de respaldo reutilizando carga de activos de v0.13). Errores de clave de cable fijados: isAvailableInNewTerritories→availableInNewTerritories, isAvailableOnFrenchStore→availableOnFrenchStore, isUploaded→uploaded, downloadURL→downloadUrl. ~19 herramientas nuevas. | "Habilita tu app en 3 nuevos territorios y comienza un lanzamiento por fases en la versión 2.5." |
| v0.16 ✓ | Seguimientos de TestFlight: envíos de comentarios beta (capturas de pantalla + listas de comentarios de fallos con filtros de build/evaluador/dispositivo, obtención de texto de registros de fallos, eliminaciones) + notificaciones de builds beta (ping manual de "nuevo build disponible"; POST solo de relaciones, sin bloque de atributos) + criterios de reclutamiento beta (a-UNO por grupo beta; crear/parchear/eliminar + catálogo de opciones válidas + verificación de build compatible). Error de clave de cable fijado: buildBundleID→buildBundleId (eliminación de ID final). DELETEs en comentarios + criterios documentados por Apple pero faltantes en el SDK de Swift — verificado contra el JSON de documentación de Apple. Filtro punteado filter[build.preReleaseVersion]. 14 herramientas nuevas. | "Resume los comentarios beta en el build 132 por frecuencia y gravedad, redacta una lista de triaje." |
| v0.17 ✓ | Webhooks: CRUD por app (5 atributos de creación requeridos incl. HMAC de solo escritura secret; pausa/reanudación mediante enabled; rotación de secreto mediante PATCH) + historial de entrega (filtros de estado/fecha con claves detalladas filter[createdDateGreaterThanOrEqualTo], estado de respuesta + error por intento) + reentrega (POST solo de relaciones con template autorreferencial) + ping de prueba. Catálogo de tipos de evento de 12 valores — BETA_FEEDBACK_*_CREATED se empareja con los lectores de comentarios de v0.16. Errores de clave de cable fijados: isEnabled→enabled, isRedelivery→redelivery, isPing→ping. 8 herramientas nuevas. | "Configura un webhook para que un canal de Slack se entere de cada nuevo build beta que se publique; lista las entregas FALLIDAS desde ayer y reinténtalas." |
| v0.18 ✓ | Informes de ventas + finanzas (NO JSON:API — descargas TSV comprimidas mediante nueva ruta de cliente requestBinary; 10 tipos de informe de ventas × subtipo × frecuencia; vendorNumber con respaldo de entorno ASC_VENDOR_NUMBER; resumen de vista previa TSV + exportación de archivo completo saveTo) + Informes de análisis de cuatro niveles (solicitar ONGOING/ONE_TIME_SNAPSHOT → informes por categoría → instancias por granularidad/fecha de procesamiento → segmentos con URLs pre-firmadas de tiempo limitado + herramienta de descarga CSV gunzip). Errores fijados: isStoppedDueToInactivity→stoppedDueToInactivity, detección de bytes mágicos gzip, URLs de segmento obtenidas SIN el portador ASC. 9 herramientas nuevas. | "¿Por qué cayó el MRR en Brasil la semana pasada? Compáralo con la fecha de activación del reequilibrio." |
| v0.19 ✓ | Reseñas de clientes: listas a nivel de app + con ámbito de versión (filtros de calificación/territorio, filtro de cola sin responder exists[publishedResponse], ordenamientos por calificación/fecha), lecturas de reseñas + respuestas, ⚠️ responder público (una respuesta por reseña, REEMPLAZA al volver a publicar) + eliminación de respuesta, y resúmenes de reseñas de clientes (resumen de página de producto agregado por IA de Apple; filter[platform] requerido). Errores fijados: isExistsPublishedResponse→exists[publishedResponse] (variante de eliminación de parámetro existente), filter[rating] toma cadenas. 6 herramientas nuevas. | "Redacta una respuesta a cada reseña de 1 estrella en la última versión que mencione el error de exportación. Muéstrame antes de publicar." |
| v0.20 ✓ | Experimentos de versión de App Store V2 (pruebas A/B de página de producto, adjuntas a la app — superficie v1 obsoleta omitida): CRUD de experimento con restricción de ciclo de vida de bandera iniciada (⚠️ visible para el cliente una vez iniciado; envía mediante el flujo de envío de revisión de v0.11 primero), tratamientos (+ prueba de ícono alternativo), localizaciones de tratamiento; capturas/vistas previas de variantes usan las herramientas de activos de v0.13 existentes (parentType appStoreVersionExperimentTreatmentLocalizations). Errores fijados: isStarted→started, ruta de lista /v1/apps/{id}/appStoreVersionExperimentsV2 vs CRUD /v2/appStoreVersionExperiments. 12 herramientas nuevas. | "Configura una prueba A/B del ícono azul vs el actual al 30% de tráfico, capturas en inglés + alemán." |
| v0.21 ✓ | Salud de tiempo de ejecución + accesibilidad: firmas de diagnóstico por build (puntos calientes de DISK_WRITES/HANGS/LAUNCHES, ponderados por impacto) + registros de pila de llamadas anonimizados (application/vnd.apple.diagnostic-logs+json) + métricas de rendimiento/energía de Xcode a nivel de app y build (application/vnd.apple.xcode-metrics+json, 8 tipos de métricas) + CRUD de declaraciones de accesibilidad ("Etiquetas de nutrición de accesibilidad": DRAFT → puerta de publicación ⚠️ visible para el cliente → REPLACED). Fijado: la familia de eliminación de "es" más grande hasta ahora (9× isSupports*→supports* + isPublish→publish), dos tipos de contenido no JSON:API mediante anulaciones de Accept. 8 herramientas nuevas. | "¿Qué pilas de llamadas hacen que el build 2.5.0 se cuelgue? Compara sus percentiles de tiempo de inicio con la línea base de la app." |
| v0.22 ✓ | Pedidos anticipados por territorio (PATCH de territoryAvailabilities: disponible ⚠️ / fecha de lanzamiento / preOrderEnabled — completa la superficie de disponibilidad de v0.15) + FX real para territorios con discrepancia de moneda (fxRates en ppp_compute_proposal Y ppp_apply_proposal: tasas USD-por-unidad PROPORCIONADAS POR EL USUARIO rescatan escaparates facturados en USD donde Apple Music cotiza en moneda local; filas ajustadas por FX marcadas *; este servidor nunca obtiene tasas de un tercero — el egreso permanece solo-Apple por diseño). 1 herramienta nueva + mejora del motor PPP. | "Abre pedidos anticipados en Japón para el 1 de septiembre; reequilibra los precios de los territorios del Golfo usando las tasas de hoy de BHD/KWD/OMR." |
| v1.0 ✓ | DMA de la UE / distribución alternativa (restringida por derecho — las herramientas explican el 403 cuando la cuenta no está inscrita): dominios de distribución web (registrar/listar/eliminar ⚠️), claves de firma públicas (la mitad privada nunca va a Apple), paquetes firmados por versión con URLs de descarga pre-firmadas + variantes + deltas, detalles de búsqueda de marketplace (eliminación catalogURL→catalogUrl), webhooks de marketplace (eliminación endpointURL→endpointUrl, secreto de solo escritura). 19 herramientas nuevas. | "Empaqueta la versión 3.0 para distribución web y entrega las URLs firmadas al CDN." |
| v1.1.0 ✓ | Ofertas de recuperación de suscriptores — el tercer tipo de oferta, dirigida a suscriptores caducados (Apple las muestra automáticamente a clientes elegibles que se han dado de baja): listar / obtener / listar precios / publicar / parchear / eliminar. Más enriquecidas que las ofertas promocionales: segmentación por elegibilidad (duración pagada + un rango de tiempo desde la última suscripción {min,max} + espera entre), programación (inicio/fin), prioridad y un recurso automático promotionIntent; PATCH es solo de atributos (identidad y precios inmutables, eliminar y volver a crear para cambiarlos). 6 nuevas herramientas. | "Recupera suscriptores que se dieron de baja hace 1 a 6 meses con una oferta de precio PPP de tres meses, mostrada automáticamente por Apple." |
| v1.2.0 ✓ | Recursos de revisión de IAP + suscripción: la captura de revisión de App Store que Apple requiere antes de que se pueda enviar una IAP/suscripción, además de imágenes promocionales. Cuatro recursos (IAP/suscripción × imagen/captura de revisión) en el flujo de carga de tres pasos de v0.13, controlados desde una tabla de configuración: asc_upload_* compuesto + reserva/confirmación/eliminación sin procesar + lecturas. Imágenes de muchos a uno, capturas de revisión de uno a uno (la carga rechaza un duplicado). Problema de cableado resuelto: la imagen de IAP se relaciona mediante inAppPurchase, la captura de revisión de IAP mediante inAppPurchaseV2. 22 herramientas nuevas. | "Adjunta la captura de revisión a mi nueva suscripción para poder enviarla." |
| v1.4.0 ✓ | Declaraciones de clasificación por edad: lectura + PATCH del cuestionario con el que App Review evalúa una app (13 enumeraciones de frecuencia, 11 booleanos, anulaciones de clasificación, banda de edad para niños). Depende de AppInfo, no de la versión; el id de declaración == id de appInfo (resuelto desde appId). Apple combina en PATCH. 2 herramientas nuevas. | "Responde el cuestionario de clasificación por edad para que la versión 3.0 pueda enviarse." |
| v1.5.0 ✓ | Completitud del ciclo de envío: disponibilidades (disponibilidad por territorio de suscripción / IAP / tipo de plan — vinculación de territorio con código ISO simple, reemplazo completo solo con POST) + detalles de App Review (contacto / cuenta de demostración / notas por versión) con adjuntos de revisión como el quinto recurso de la fábrica de carga + solicitudes de lanzamiento (lanzar una versión aprobada ahora) + envíos de elementos independientes (revisión de IAP / suscripción / grupo sin lanzamiento de versión) + períodos de gracia de facturación. ~25 herramientas nuevas. | "Completa la tarjeta de revisión, adjunta el video de demostración, envía la nueva suscripción y lanza la compilación aprobada." |
La hoja de ruta de v0.1→v1.0 está completa — cada superficie planificada originalmente se ha lanzado. El trabajo posterior a v1.0 sigue los cambios de API de Apple (nuevos recursos, desviación de contrato — ver scripts/audit-fieldsets.py + scripts/audit-required-attributes.py): v1.1.0 añade ofertas de recuperación, v1.2.0 añade recursos de revisión de IAP/suscripción (cerrando la brecha de "no se puede enviar sin una captura de revisión"), v1.4.0 añade declaraciones de clasificación por edad, v1.5.0 cierra el ciclo de preparar→enviar→lanzar (disponibilidades, detalles/adjuntos de revisión, envíos independientes, solicitudes de lanzamiento, períodos de gracia).
Fuera de alcance (Fastlane / Xcode ya hacen esto bien): perfiles de aprovisionamiento, certificados, dispositivos, capacidades, configuración de Game Center.
Piensa en esto como el compañero LLM para operaciones de App Store Connect. Fastlane es para el pipeline de compilación/lanzamiento; esto es para el trabajo de conocimiento posterior al lanzamiento: ciclo de vida de lanzamiento, traducción, precios, ASO, comentarios de clientes, promoción en tienda y análisis.
Cada nuevo dominio es un archivo bajo src/domains/<name>.ts más una llamada a register* en src/index.ts. Las contribuciones son bienvenidas — ver CONTRIBUTING.md.
Desarrollar
git clone https://github.com/akoskomuves/appstoreconnect-mcp.git
cd appstoreconnect-mcp
npm install
npm run dev # tsx watch mode
npm test
npm run build
Ver CONTRIBUTING.md para el flujo de contribuidores (changesets, plantilla de PR, nombres de ramas).
Licencia
MIT © 2026 Akos Komuves