mobile-mcp-opengl
MCP para desarrollo y automatización de Android con OpenGL
Un servidor MCP para agentes de codificación de IA (Claude Code, Cursor, etc.) que permite probar aplicaciones Android cuya interfaz de usuario completa se dibuja dentro de una única superficie opaca OpenGL/Vulkan/Metal — Cocos2d-x, Unity, Unreal, OpenGL puro, libGDX y motores similares.
El problema que resuelve
adb shell uiautomator dump y todas las herramientas de automatización basadas en el árbol de accesibilidad (incluida la mayoría de los servidores MCP de automatización móvil) funcionan inspeccionando la jerarquía de vistas nativa de Android: botones, etiquetas, su texto y coordenadas. Eso funciona muy bien para una interfaz Android normal construida con vistas nativas.
No funciona para un juego o aplicación que renderiza toda su interfaz como texturas dentro de un único GLSurfaceView. Desde el punto de vista del árbol de accesibilidad, hay exactamente una vista opaca en pantalla sin hijos, sin etiquetas, sin coordenadas para nada dentro de ella. No hay nada que inspeccionar: la pantalla es una caja negra, sin importar cuánta interfaz haya realmente en ella.
El único canal de observación real que queda son las capturas de pantalla. Este servidor está construido en torno a ese hecho como el caso normal, no como un recurso ocasional.
En qué se diferencia de mobile-mcp
mobile-next/mobile-mcp es el servidor MCP de automatización móvil de propósito general, y es una buena opción por defecto para aplicaciones nativas normales: primero el árbol de accesibilidad (rápido, barato, sin modelo de visión, sin tokens de imagen), con respaldo a capturas de pantalla + coordenadas solo cuando el árbol no le da lo que necesita.
Para una aplicación con lienzo OpenGL, ese respaldo no es ocasional: es la única ruta que funciona, cada vez. mobile-mcp-opengl está construido específicamente para ese caso y, como resultado, toma dos decisiones de diseño diferentes:
Sin intento de árbol de accesibilidad en absoluto. No hay nada que ganar intentándolo: siempre vuelve vacío para estas aplicaciones, así que cada herramienta aquí va directamente a captura de pantalla + visión.
El análisis de visión pasa por un proveedor separado y conectable (ver más abajo), no por el modelo que ejecuta el agente llamante. Un bucle de control de calidad funcional sobre un juego puede fácilmente llegar a cientos de comprobaciones de capturas de pantalla por sesión; enrutar todo eso a través de la propia visión de tu agente de codificación principal cuesta tanto dinero real como tokens/contexto que preferirías gastar en el trabajo de codificación real. Aquí los bytes de la captura de pantalla nunca entran en el contexto del agente llamante; solo lo hace la respuesta de texto corta del proveedor.
Related MCP server: Android-MCP
Por qué herramientas combinadas de acción+observación, no primitivas separadas
Un diseño ingenuo expone tap, screenshot y ask como tres herramientas separadas. Eso obliga al agente llamante a orquestar un bucle de varios pasos para cada interacción: tocar → tomar una captura de pantalla → pasarla a un paso de visión → leer el resultado → decidir qué hacer a continuación. Cada uno de esos es una llamada de herramienta separada y un turno separado: quemando tokens en coordinación en lugar de en la lógica de prueba real, y dando más superficie para que el agente omita un paso, los desordene o razone sobre estado obsoleto entre llamadas.
En cambio, este servidor expone herramientas combinadas — tap_and_ask, swipe_and_ask, long_press_and_ask — que realizan la acción, esperan brevemente, toman la captura de pantalla, preguntan al proveedor de visión y devuelven una respuesta corta, todo como una sola llamada de herramienta. Un escenario de prueba de varios pasos termina costando aproximadamente un turno de agente por comprobación significativa, no tres o cuatro.
También están disponibles screenshot_ask simple (solo observación, sin acción) y herramientas baratas sin visión (type_text, press_key, logcat_grep) para las partes de un flujo de prueba que no necesitan este patrón.
Herramientas
Herramienta | Qué hace | ¿Llamada de visión? |
| Captura de pantalla, luego pregunta una pregunta corta sobre ella | Sí |
| Toca (x, y), espera, captura, pregunta | Sí |
| Desliza/arrastra (x1,y1)→(x2,y2), espera, captura, pregunta | Sí |
| Mantén presionado (x, y) durante una duración, espera, captura, pregunta | Sí |
| Acción opcional, luego N capturas de pantalla espaciadas en el tiempo, pregunta lo mismo sobre cada fotograma | Sí (N llamadas) |
| Escribe en el campo actualmente enfocado | No |
| Envía un evento | No |
| Lee logcat reciente, opcionalmente filtrado por regex | No |
| Informa el gasto acumulado de visión de hoy y los umbrales | No |
Prefiere logcat_grep sobre una llamada de visión siempre que lo que necesitas ya esté en una línea de registro (errores, tus propias impresiones de depuración, errores de red) — es gratis y exacto, una llamada de visión no es ninguna de las dos cosas.
Comprobación de animaciones: record_and_ask
Las herramientas de un solo fotograma no pueden decirte si algo anima correctamente (¿el indicador de fuerza pulsa suavemente, una etiqueta vuela hacia arriba y se desvanece, un sprite vuelve a su posición inicial?). record_and_ask realiza una acción opcional (tocar o deslizar, o ninguna), espera waitMs (mismo significado que waitMs en tap_and_ask/swipe_and_ask — tiempo para que la interfaz comience a reaccionar antes del primer fotograma), luego captura frameCount capturas de pantalla espaciadas intervalMs aparte, y devuelve una respuesta corta por fotograma — el agente llamante obtiene una línea de tiempo en una sola llamada de herramienta en lugar de orquestar N viajes de ida y vuelta de captura de pantalla + pregunta por sí mismo.
Por qué una llamada de visión por fotograma, no una llamada con todos los fotogramas juntos. Resulta que imageCaption de Runware acepta un array inputImages (plural) no documentado junto con el inputImage único documentado — probado directamente contra la API. Funciona limpiamente para exactamente 2 imágenes (una comparación antes/después en la misma solicitud volvió correcta y coherente). Con 3+ imágenes en una solicitud, tanto ese parámetro de array como una imagen de "tira de película" compuesta manualmente lado a lado produjeron respuestas truncadas o malformadas en las pruebas — el pequeño modelo de visión de 7B aparentemente pierde coherencia más allá de cierta carga combinada de visual+instrucción en una llamada. Las llamadas secuenciales de imagen única (el enfoque de esta herramienta) fueron confiables en cualquier número de fotogramas probado, y no son significativamente más caras: el costo está dominado por la longitud de la respuesta (ver más abajo) en lugar del número de llamadas, así que N respuestas cortas secuenciales cuestan aproximadamente lo mismo, o menos, que una respuesta larga de múltiples imágenes. Si tu propio proveedor maneja solicitudes de múltiples imágenes de manera más confiable, este es un lugar obvio para optimizar — ver "Trae tu propio modelo".
Configuración
git clone <this repo>
cd mobile-mcp-opengl
npm install
cp .env.example .env
# edit .env: at minimum set RUNWARE_API_KEY (or switch VISION_PROVIDER, see below)Requiere adb en PATH (o ADB_PATH configurado en .env), y un dispositivo o emulador en ejecución/conectado. Si hay más de uno conectado, configura ADB_DEVICE_SERIAL (ver adb devices).
Registrar con Claude Code
Añade un .mcp.json en la raíz de tu proyecto (este archivo suele ser local al proyecto y estar ignorado por git, ya que normalmente apunta a una ruta específica de la máquina o contiene anulaciones de entorno específicas de la máquina):
{
"mcpServers": {
"mobile-opengl": {
"command": "node",
"args": ["/absolute/path/to/mobile-mcp-opengl/src/server.js"]
}
}
}Claude Code lo recoge automáticamente para el proyecto. El servidor lee su propio .env (junto a package.json en este repositorio) para toda la configuración — el agente llamante nunca necesita conocer ni pasar ninguna clave de API por sí mismo.
Modelo de costos — lee esto antes de ejecutar una sesión larga de control de calidad
La longitud de la respuesta impulsa el costo, no el tamaño de la imagen. Esto se midió empíricamente contra el proveedor predeterminado Runware/Qwen2.5-VL-7B-Instruct: la misma pregunta con una respuesta forzada de una palabra costó lo mismo ($0.0006) en tamaños de imagen desde 360×360 hasta 1600×2400 (clase retina). La misma imagen de 1024×1024 con un prompt abierto de "describe esto" costó $0.0013–0.0019 — 2-3 veces más — puramente porque el modelo escribió una respuesta más larga, no porque la imagen fuera más grande.
Implicaciones prácticas:
No te molestes en reducir la resolución de las capturas de pantalla antes de enviarlas — no reduce significativamente el costo para este proveedor, y pierdes detalle que podrías necesitar.
Siempre formula preguntas para forzar respuestas cortas: sí/no, un número, una etiqueta corta, un pequeño objeto JSON con un par de campos. Cada herramienta en este servidor añade automáticamente una instrucción de respuesta corta, pero una pregunta vaga y abierta ("¿qué ves?") aún puede empujar al modelo hacia una respuesta más larga que una específica ("¿es visible el diálogo de error? sí/no").
A ~$0.0006/llamada para preguntas cortas bien formadas, una sesión de control de calidad de 500 llamadas cuesta aproximadamente $0.30. El mismo volumen de preguntas abiertas de "describe la pantalla" puede costar 2-3 veces más.
Salvaguardas de gasto integradas
Cada llamada de visión se registra en .vision-log.jsonl (JSONL, una entrada por llamada: marca de tiempo, pregunta, respuesta, costo). Dos protecciones independientes se asientan sobre ese registro, ambas independientes del proveedor (funcionan con lo que sea que un proveedor reporte como costUsd):
Alerta por llamada (
VISION_ALERT_USD, por defecto$0.0015): si una sola llamada vuelve por encima de esto, la respuesta de la herramienta incluye una nota[COST ALERT]que te dice que el modelo probablemente ignoró la instrucción de respuesta corta — una señal para reformular la pregunta, no algo que tragarse en silencio.Tope diario (
VISION_SESSION_CAP_USD, por defecto$2.00): una vez que el gasto acumulado de hoy alcanza esto, cada llamada de visión adicional es rechazada directamente (antes de llegar al proveedor) hasta que se aumente el tope o cambie el día. Esto es un freno duro contra un bucle descontrolado, no solo una advertencia.
Llama a vision_spend_report en cualquier momento para verificar el total de hoy sin hacer una llamada de dispositivo o visión.
Si un proveedor no puede reportar un costo (ver openai-compatible más abajo), las llamadas de él se registran con costUsd: null y nunca activan la alerta ni cuentan para el tope — las salvaguardas simplemente no pueden proteger un gasto del que no tienen visibilidad.
Trae tu propio modelo
El análisis de visión pasa por src/providers/visionProvider.js, que elige un proveedor por nombre desde VISION_PROVIDER en .env. Hay dos integrados:
runware(predeterminado) — habla directamente con la tareaimageCaptionde Runware.ai, usando Qwen2.5-VL-7B-Instruct (ID AIRrunware:152@2) por defecto. Runware y OpenRouter son dos servicios separados con claves de API y catálogos de modelos separados — esto habla con Runware directamente, no a través de OpenRouter.openai-compatible— un proveedor genérico para cualquier cosa que hable el formato de visión de chat-completions de OpenAI (partes de contenidoimage\_url). Funciona con OpenRouter, un servidor local de Ollama/LM Studio que ejecuta un modelo de visión, Groq, Together.ai o cualquier otro endpoint compatible. ConfiguraOPENAI_COMPATIBLE_BASE_URL,OPENAI_COMPATIBLE_API_KEY,OPENAI_COMPATIBLE_MODELen.env. La mayoría de las APIs compatibles con OpenAI reportan uso de tokens en lugar de un costo en dólares plano; configuraOPENAI_COMPATIBLE_PRICE_PER_1M_INPUT/_OUTPUTsi quieres que este proveedor estimecostUsda partir de eso (de lo contrario, el seguimiento de costos/las salvaguardas son inertes para este proveedor, según la nota anterior).
Para añadir un proveedor completamente personalizado (un modelo autoalojado, una forma de API completamente diferente), copia src/providers/openaiCompatibleProvider.js como punto de partida, implementa:
async function ask(imageBuffer, mimeType, question) {
// return { text: string, costUsd: number | null }
}
module.exports = { ask };y regístralo con un nombre en loadProvider() de src/providers/visionProvider.js.
Licencia
MIT
Desarrollado por Kinect.PRO
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
- AlicenseCqualityBmaintenanceA lightweight bridge enabling AI agents to perform real-world tasks on Android devices such as app navigation, UI interaction, and automated QA testing without requiring computer-vision pipelines or preprogrammed scripts.14807MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to control Android devices and emulators through direct UI interaction, allowing app navigation, automated testing, and real-world task execution via ADB without computer vision or scripts.1MIT
- AlicenseAqualityFmaintenanceProvides AI agents with real-time vision and control over Android devices through screen streaming, UI automation, and fast input control via scrcpy protocol.3317MIT
- AlicenseAqualityDmaintenanceEnables AI agents to fully control Android devices through over 30 tools for app management, UI automation, and vision-based analysis via ADB. It supports multi-device management, action recording, and smart execution strategies ranging from UI hierarchy parsing to coordinate-based interaction.371371MIT
Related MCP Connectors
AI visual generation agent: multi-pipeline rendering, prompt crafting, and image composition.
Browser-backed QA with evidence and fix-ready reports for coding agents.
Codebase intelligence for agents: 152 structured artifacts across 21 programs, one call.
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/antonpinchuk/mobile-mcp-opengl'
If you have feedback or need assistance with the MCP directory API, please join our Discord server