Saltar al contenido principal

Servidor MCP de control de Android de OmniWeb

Un servidor MCP que envuelve el "middleware de Android" de OmniWeb (el servicio Flask omniweb-android, /api/android/*) para que un cliente MCP — Claude Code, Claude Desktop, o un cliente personalizado — pueda controlar los teléfonos Android y módems USB del laboratorio.

Es un cliente HTTP delgado sobre la API REST existente (no importa ningún interno de Flask), por lo que funciona contra cualquier instancia omniweb-android accesible.

Herramientas expuestas

HerramientaFirmaQué hace
list_devices()Todos los dispositivos conocidos (teléfonos + módems), en línea y fuera de línea.
device_info(serial)Detalles completos de un dispositivo.
screenshot(serial) → imagen PNGPantalla actual (universal: teléfonos scrcpy Y dispositivos de captura de pantalla antiguos).
tap(serial, x, y)Toca en las coordenadas de píxeles.
swipe(serial, x1, y1, x2, y2, ms=200)Deslizar/arrastrar/lanzar.
input_text(serial, text)Escribir en el campo enfocado.
key(serial, name)Presionar atrás/inicio/recent/enter/borrar/poder/menu/subir_volumen/bajar_volumen.
adb_shell(serial, command, timeout=30){stdout, stderr, return_code}Comando adb shell arbitrario (herramienta de poder).
list_scripts()La biblioteca de scripts de prueba del dispositivo.
run_script(serials, file, params={})Ejecutar un script en varios dispositivos; devuelve identificadores de ejecución.
get_run(run_id)Resultado de una ejecución de script (estado/stdout/código_de_retorno).
at_command(serial, command, read_ms=0, timeout_ms=0)Comando AT en bruto a un módem USB.
send_sms(serial, number, text)Enviar un SMS desde un módem.

Configuración (variables de entorno)

Objetivo del backend:

  • OMNIWEB_API_BASE — URL base del servicio de Android. Por defecto http://127.0.0.1:5002. El prefijo /api/android se agrega automáticamente.

Autenticación del backend (elija UNO):

  • OMNIWEB_JWT — un token de acceso al backend preemitido (Bearer), O
  • OMNIWEB_JWT_SECRET — la JWT_SECRET_KEY del backend. El servidor entonces emite un JWT de administrador de corta duración y lo actualiza automáticamente. OMNIWEB_JWT_TTL (segundos, por defecto 3600) controla su duración.

La propia puerta de entrada de este servidor MCP:

  • MCP_TRANSPORThttp (por defecto, HTTP transmitible para clientes remotos) o stdio (local claude mcp add).
  • MCP_HOST / MCP_PORT — dirección de enlace para el transporte http. Por defecto 127.0.0.1:5005.
  • MCP_AUTH_TOKEN — token bearer que un cliente MCP remoto debe presentar. Requerido para enlazar a algo diferente de localhost — el servidor rechaza un enlace no de bucle sin él (fallo cerrado). En /mcp el token es verificado por middleware; / y /health están abiertos para chequeos de salud.

Ejecútalo

venv (autocontenido)

cd /opt/omniweb-mcp           # o donde sea que hayas puesto server.py + requirements.txt
python3 -m venv venv
venv/bin/pip install -r requirements.txt

export OMNIWEB_API_BASE=http://127.0.0.1:5002
export OMNIWEB_JWT_SECRET=<la JWT_SECRET_KEY del backend>
export MCP_TRANSPORT=http
export MCP_HOST=0.0.0.0
export MCP_PORT=5005
export MCP_AUTH_TOKEN=<un token aleatorio largo>
venv/bin/python server.py

systemd (producción)

Se proporciona una unidad en packaging/omniweb-android-mcp.service. Lee /etc/omniweb/omniweb.env (para JWT_SECRET_KEY → se vuelve a exportar como OMNIWEB_JWT_SECRET, ver más abajo) además de /etc/omniweb/android-mcp.env para los secretos específicos de MCP. Crea ese archivo de configuración (chmod 600):

# /etc/omniweb/android-mcp.env
OMNIWEB_JWT_SECRET=<mismo valor que JWT_SECRET_KEY en omniweb.env>
MCP_AUTH_TOKEN=<un token aleatorio largo>

Luego:

sudo cp packaging/omniweb-android-mcp.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now omniweb-android-mcp

El archivo de entorno del backend nombra el secreto JWT como JWT_SECRET_KEY; este servidor lee OMNIWEB_JWT_SECRET. Establece OMNIWEB_JWT_SECRET explícitamente en android-mcp.env (copia el valor) para que los nombres coincidan.

Conectar desde Claude Code

Remoto (HTTP transmitible), con autenticación:

claude mcp add --transport http android-control http://<host>:5005/mcp \
--header "Authorization: Bearer <MCP_AUTH_TOKEN>"

Local (stdio), apuntando el servidor a un backend y emitiendo su propio JWT:

claude mcp add android-control \
-e OMNIWEB_API_BASE=http://127.0.0.1:5002 \
-e OMNIWEB_JWT_SECRET=<backend JWT_SECRET_KEY> \
-e MCP_TRANSPORT=stdio \
-- /opt/omniweb-mcp/venv/bin/python /opt/omniweb-mcp/server.py

Luego en Claude Code: /mcp para confirmar que se conectó, y prueba list_devices.

Conectar desde Claude Desktop

claude_desktop_config.json — lanzamiento stdio:

{
"mcpServers": {
"android-control": {
"command": "/opt/omniweb-mcp/venv/bin/python",
"args": ["/opt/omniweb-mcp/server.py"],
"env": {
"OMNIWEB_API_BASE": "http://127.0.0.1:5002",
"OMNIWEB_JWT_SECRET": "<backend JWT_SECRET_KEY>",
"MCP_TRANSPORT": "stdio"
}
}
}
}

Para un servidor remoto HTTP transmitible desde Claude Desktop, utiliza un puente mcp-remote o la configuración del servidor HTTP soportada por tu versión de Desktop, apuntando a http://<host>:5005/mcp con el encabezado Authorization: Bearer &lt;MCP_AUTH_TOKEN>.

Notas de seguridad

  • El control de dispositivos requiere el MCP_AUTH_TOKEN configurado en el transporte HTTP. Sin un token, el servidor solo permite un enlace de bucle y muestra una advertencia; un enlace no de bucle sin un token es rechazado.
  • El servidor se autentica con el backend como un administrador (JWT emitido o token proporcionado), por lo que cualquier persona que pueda acceder a /mcp con el token bearer tiene control total sobre los dispositivos. Trata MCP_AUTH_TOKEN como una contraseña y protégelo con TLS (por ejemplo, a trav��s de nginx) para acceso fuera del host.