App Store Operator
Investigación competitiva de la App Store para desarrolladores independientes de iOS: búsqueda de palabras clave clasificadas, estimaciones de descargas e ingresos de competidores, y copia de eventos dentro de la aplicación de iOS. Gratuito, sin clave API.
Documentación
App Store Operator
Inteligencia competitiva de la App Store, dentro de Claude.
App Store Operator es un servidor MCP que lleva la investigación de la App Store directamente a tu asistente de IA. En lugar de cambiar a un panel de control, le pides a Claude resultados de palabras clave clasificados, estimaciones de descargas e ingresos de competidores, o texto listo para App Store Connect de In-App Events — y obtienes la respuesta en la misma conversación donde estás tomando la decisión.
Diseñado para desarrolladores independientes de iOS que quieren investigación dentro de su flujo de trabajo en lugar de en otra pestaña del navegador. Gratis y de código abierto (MIT). Una alternativa ligera a SensorTower, AppTweak y AppFollow para investigación competitiva solo de iOS.
claude mcp add --transport stdio app-store-operator -- npx -y app-store-operator@latest
→ app-store-operator.com · Guía de configuración
Qué hace
Busca en la App Store aplicaciones competidoras para una palabra clave dada y extrae análisis detallados de SensorTower: descargas, ingresos, calificaciones, principales mercados, información del editor y más.
search_app_store y prepare_iae funcionan sin ninguna cuenta. research_rivals y get_app_details abren un navegador una vez para un inicio de sesión gratuito de SensorTower, y luego reutilizan esa sesión guardada — sin plan de pago, sin clave API.
Todo lo que expone el servidor — cuatro herramientas, seis prompts, siete recursos — es de solo lectura. Nada escribe en tu cuenta de App Store Connect, en SensorTower, ni en ningún otro lugar excepto un archivo de caché local.
Herramientas
research_rivals
Encuentra las 3 mejores aplicaciones para una palabra clave y devuelve un informe completo de métricas para cada una.
| Parámetro | Tipo | Descripción |
|---|---|---|
keyword | string | Término de búsqueda a consultar (p. ej. meditation, psikoloji) |
country | string | Código de país de dos letras (p. ej. us, tr, gb) |
Devuelve para cada competidor:
- URLs de App Store y SensorTower
- Descargas e ingresos mundiales y del último mes
- Puntuación de calificación y número de calificaciones
- Editor, categorías, principales mercados
- Fecha de lanzamiento, última actualización, idiomas compatibles
- Compras dentro de la aplicación y presencia de redes publicitarias
Se almacena en caché durante 24 horas, por lo que preguntar de nuevo sobre la misma palabra clave y país no cuesta nada y no abre ningún navegador.
search_app_store
Busca en la App Store una palabra clave y devuelve resultados clasificados como tabla de markdown — al instante, sin necesidad de SensorTower.
| Parámetro | Tipo | Descripción |
|---|---|---|
keyword | string | Término de búsqueda a consultar |
country | string | Código de país de dos letras |
limit | number | Número de resultados a devolver (1–25, por defecto 3) |
Úsalo para descubrir qué aplicaciones se clasifican antes de decidir cuáles analizar. Continúa con get_app_details para obtener análisis de aplicaciones específicas.
get_app_details
Obtiene análisis de SensorTower para uno o más IDs de aplicación que ya tengas.
| Parámetro | Tipo | Descripción |
|---|---|---|
app_ids | array | IDs numéricos de App Store (p. ej. de search_app_store) |
country | string | Código de país de dos letras |
Devuelve para cada aplicación:
- Descargas e ingresos (mundiales + último mes)
- Puntuación de calificación y número de calificaciones
- Editor, categorías, principales mercados
- Fecha de lanzamiento, última actualización, idiomas compatibles
- Compras dentro de la aplicación y presencia de redes publicitarias
Nunca se almacena en caché — cada llamada extrae datos nuevos, aproximadamente 10–20 segundos por ID de aplicación.
prepare_iae
Genera texto para In-App Events (IAE) de iOS App Store — 3 variaciones en el idioma objetivo, y luego un informe final.
| Parámetro | Tipo | Descripción |
|---|---|---|
keywords | array | Palabras clave ordenadas por prioridad (índice 0–2 = Nivel 1, 3–6 = Nivel 2, 7–9 = Nivel 3) |
locale | string | Locale objetivo (p. ej. en-us, en-gb, de-de, tr, ja, ko) |
event_purpose | string | De qué trata el evento y por qué los usuarios deberían importarle |
audience | string | Audiencia objetivo (p. ej. estudiantes, profesionales, padres) |
event_context | string | Gancho del mundo real que conecta el evento con un momento (p. ej. una festividad, una temporada) |
goal | string | Objetivo principal de conversión (p. ej. atraer nuevos usuarios, aumentar la participación) |
tone | string | Tono del texto: Engaging, Playful, Motivational, Authoritative, Calm, o Urgent |
Devuelve: un brief estructurado utilizado para generar 3 variaciones de texto, cada una con nombre del evento (≤30 caracteres), descripción corta (≤50 caracteres) y descripción larga (≤120 caracteres).
Cualquier campo que SensorTower no exponga, o que mantenga detrás de su muro de pago, se devuelve como N/A. El servidor informa la brecha en lugar de rellenarla, y los prompts a continuación le indican al asistente que haga lo mismo.
Prompts
Seis flujos de trabajo listos que ya encadenan las herramientas anteriores, para que no tengas que describir la secuencia tú mismo. En Claude Code aparecen como comandos de barra; otros clientes los muestran en un selector de prompts.
| Prompt | Argumentos | Qué hace |
|---|---|---|
competitor_snapshot | keyword, country | Extrae análisis de rivales para una palabra clave, y luego explica quién la domina y qué tan disputada está |
keyword_shortlist | seed_keyword, country, count? | Expande una palabra clave semilla en candidatos, prueba cada uno contra resultados de búsqueda en vivo, y los clasifica atacar / vigilar / omitir |
app_teardown | app_ids, country | Desglose de aplicaciones conocidas: escala, posición, monetización, alcance, impulso, adquisición |
positioning_gap | keyword, country, my_app_id | Pone tu aplicación en la misma vara de medir que los incumbentes y separa detrás de atacable |
metadata_rewrite | app_name, keyword, country, must_keep? | Tres variaciones de nombre / subtítulo / campo de palabras clave, con conteo de caracteres contra los límites de Apple |
in_app_event | event_context, locale, keywords?, audience?, tone? | Ejecuta el flujo completo de In-App Event, pidiendo lo que prepare_iae aún necesite |
Los argumentos marcados como ? son opcionales. Cada prompt le indica al asistente que no invente cifras y, cuando SensorTower está involucrado, que no recurra silenciosamente a una herramienta más débil cuando se requiere inicio de sesión.
Recursos
Datos de referencia y estado local que un cliente puede adjuntar como contexto sin gastar una llamada de herramienta.
| URI | Tipo | Contenido |
|---|---|---|
asops://guide/tool-selection | markdown | Qué herramienta usar, cuánto cuesta cada una, cómo funciona el inicio de sesión de SensorTower |
asops://reference/country-codes | markdown | Códigos de tienda de dos letras por región |
asops://reference/aso-fields | JSON | Límites de caracteres de App Store Connect y qué campos están indexados para búsqueda |
asops://reference/iae-fields | JSON | Límites de In-App Event, tamaños de arte, reglas de texto, niveles de palabras clave |
asops://reference/iae-locales | JSON | Cada locale que acepta prepare_iae — generado desde la misma tabla que la herramienta valida |
asops://cache/research | JSON | Lo que ya se ha investigado en esta máquina, y si sigue siendo reciente |
asops://cache/research/{country}/{keyword} | JSON | Un resultado de research_rivals en caché, sin volver a extraer datos |
Nada de esto sale de tu máquina: los recursos de referencia son estáticos, y los dos recursos de caché leen ~/.app-store-operator/cache.json.
Requisitos
- Node.js v18+
- Una sesión de escritorio para
research_rivalsyget_app_details. Conducen una ventana real y visible de Chromium para que puedas iniciar sesión en SensorTower, por lo que necesitan una pantalla — no funcionan sobre SSH simple ni dentro de un contenedor. Las otras dos herramientas no tienen ese requisito. - Espacio en disco para Chromium. Instalar el paquete descarga una compilación de Playwright Chromium (unos cientos de MB) mediante un paso posterior a la instalación. Si ese paso falla, el servidor lo instala en el primer uso; también puedes ejecutar
npx playwright install chromiumtú mismo.
Uso
Como servidor MCP (Claude Code / Claude Desktop / OpenAI Codex)
Claude Code — ejecuta este comando una vez:
claude mcp add --transport stdio app-store-operator -- npx -y app-store-operator@latest
Claude Desktop — agrega a tu configuración MCP:
{
"mcpServers": {
"app-store-operator": {
"command": "npx",
"args": ["app-store-operator@latest"]
}
}
}
OpenAI Codex — ejecuta este comando una vez:
codex mcp add app-store-operator -- npx -y app-store-operator@latest
Codex almacena los servidores MCP en ~/.codex/config.toml. Si prefieres editarlo directamente:
[mcp_servers.app-store-operator]
command = "npx"
args = ["-y", "app-store-operator@latest"]
# Optional but useful for SensorTower scraping flows
startup_timeout_sec = 20
tool_timeout_sec = 180
Luego reinicia Codex o inicia un nuevo hilo, y pregunta cosas como:
Research rivals for "hairstyle" in the GB App StoreSearch the App Store for "beard style" in FrancePrepare an in-app event for a summer hairstyle campaign in en-gb
No se necesita paso de instalación — npx obtiene y ejecuta el paquete automáticamente.
El servidor se comunica a través de stdio y está diseñado para ser invocado por un cliente MCP. Anuncia instructions a nivel de servidor durante initialize para que los clientes enruten correctamente entre las herramientas, y devuelve un error de herramienta MCP cuando se requiere inicio de sesión en SensorTower.
Configuración
Ambos ajustes son variables de entorno opcionales en el proceso del servidor.
| Variable | Predeterminado | Qué hace |
|---|---|---|
ASO_CACHE_TTL_HOURS | 24 | Cuánto tiempo un resultado de research_rivals permanece fresco en la caché local antes de volver a extraerse |
ASO_DEBUG_RATINGS | sin definir | Establecer a 1 para imprimir el panel de calificaciones de SensorTower en stderr cuando una puntuación o recuento de calificaciones vuelva como N/A — útil al reportar un error de extracción |
En un contenedor
El repositorio incluye un Dockerfile basado en la imagen oficial de Playwright:
docker build -t app-store-operator .
docker run -i --rm app-store-operator
El servidor habla JSON-RPC sobre stdio, por lo que no se expone ningún puerto — apunta tu cliente MCP a la entrada/salida estándar del contenedor. Ten en cuenta que un contenedor no tiene pantalla: search_app_store y prepare_iae funcionan allí, pero las dos herramientas de SensorTower no pueden abrir una ventana de inicio de sesión y fallarán en lugar de pedirte que inicies sesión.
Cómo funciona
- Busca en la App Store la palabra clave y el país, y consulta cualquier ID de aplicación que hayas pasado directamente contra la API pública de iTunes Lookup de Apple
- Para cada aplicación, conduce un navegador Chromium para extraer análisis de SensorTower
- Extrae las métricas y devuelve un informe compilado
Los datos de SensorTower se extraen mediante Playwright porque se renderizan en el lado del cliente.
Se abrirá una ventana del navegador. Esto es deliberado, no un error: SensorTower requiere inicio de sesión, por lo que la primera ejecución abre una ventana visible para que inicies sesión. La sesión se guarda en ~/.app-store-operator/profile y se reutiliza en cada llamada posterior, por lo que solo inicias sesión una vez. Si una herramienta reporta not_logged_in, termina de iniciar sesión en esa ventana y ejecuta la herramienta de nuevo.
Los resultados de research_rivals se almacenan en caché durante 24 horas en ~/.app-store-operator/cache.json — anula el TTL con la variable de entorno ASO_CACHE_TTL_HOURS.
Limitaciones
- Solo iOS. Nada aquí cubre Google Play o Android.
- Solo lectura. Ninguna herramienta cambia nada en App Store Connect ni en SensorTower.
research_rivalsestá fijado a los 3 mejores resultados. Usasearch_app_store(hasta 25) y luegoget_app_detailscuando necesites un conjunto más amplio.- La extracción es frágil por naturaleza. SensorTower renderiza su panel en el lado del cliente y cambia su marcado sin aviso; cuando lo hace, los campos afectados devuelven
N/Ahasta que se actualicen los selectores. Que una aplicación falle nunca hace fallar toda la llamada. - El nivel gratuito de SensorTower decide lo que ves. Las cifras detrás del muro de pago se devuelven como
N/A.
Política de privacidad
Política completa: https://app-store-operator.com/privacy
App Store Operator se ejecuta completamente en tu máquina. No hay backend, ni telemetría, ni análisis — el autor no recopila, recibe ni almacena nada sobre ti o tu uso.
Qué envía cada herramienta, y a dónde:
| Herramienta | Cuenta | Qué sale de tu máquina |
|---|---|---|
search_app_store | Ninguna | Palabra clave y código de país → búsqueda pública del App Store de Apple |
prepare_iae | Ninguna | Nada — cálculo puramente local, no contacta ningún servicio externo |
research_rivals | SensorTower gratuito | Palabra clave y código de país → Apple, luego SensorTower a través de tu propia sesión de navegador |
get_app_details | SensorTower gratuito | IDs de apps del App Store → API pública de consulta de Apple y SensorTower |
Qué se almacena localmente:
~/.app-store-operator/cache.json— resultados en caché, que expiran después de 24 horas por defecto (ASO_CACHE_TTL_HOURS)~/.app-store-operator/profile— el perfil de Chromium que contiene tu sesión de SensorTower
Escribes tus credenciales de SensorTower en la propia página de SensorTower en una ventana del navegador en tu máquina. El servidor nunca lee ni almacena tu contraseña, y el autor nunca la recibe.
Eliminar todo — sin solicitud al autor, nada que esperar:
rm -rf ~/.app-store-operator
Apple y SensorTower son terceros independientes con sus propias políticas. Este proyecto no está afiliado con ninguno de ellos.
Estructura del proyecto
src/
├── index.js # MCP server setup and request handlers
├── shared.js # App Store lookup + SensorTower scraping
├── cache.js # 24h local cache (research_rivals only)
├── prompts.js # the six prompt workflows
├── resources.js # reference data + cache resources
└── tools/
├── research-rivals.js # research_rivals tool
├── search-app-store.js # search_app_store tool
├── get-app-details.js # get_app_details tool
└── prepare-iae.js # prepare_iae tool
scripts/postinstall.js # installs Playwright Chromium on install
scripts/sync-version.js # syncs server.json, manifest.json and CHANGELOG.md on release
test/smoke-test-mcp.js # stdio smoke test
server.json # MCP registry manifest
manifest.json # Claude Desktop / MCPB bundle manifest
Dockerfile # container build (no display: search + IAE tools only)
Desarrollo
Sin paso de compilación ni linter — clónalo, npm install, y ejecuta npm start para iniciar el
servidor a través de stdio.
La prueba de humo verifica que el servidor arranca y expone todo lo que debería. Comprueba
initialize (incluyendo las instrucciones del servidor y la versión anunciada), tools/list,
prompts/list, prompts/get, resources/list, resources/templates/list, y lee
cada recurso, fallando si uno declarado como JSON no se analiza. No realiza llamadas de red
ni abre ningún navegador:
npm run smoke
Los lanzamientos se basan en etiquetas: escribe las notas bajo ## Unreleased en CHANGELOG.md, ejecuta
npm version <patch|minor|major> — que sincroniza la versión en server.json y
manifest.json y renombra ese encabezado a la nueva versión por ti — luego haz push con
--follow-tags. GitHub Actions ejecuta la prueba de humo, publica en npm y el registro
de MCP, y crea el lanzamiento desde esa sección del registro de cambios. El incremento se niega a ejecutarse
mientras ## Unreleased esté vacío.
Las contribuciones son bienvenidas — abre un problema o una solicitud de extracción en github.com/meyusufdemirci/app-store-operator.
Licencia
MIT © Yusuf Demirci