Pular para o conteúdo principal

Servidor MCP de controle Android do OmniWeb

Um servidor MCP que envolve o "middleware Android" do OmniWeb (o serviço Flask omniweb-android, /api/android/*) para que um cliente MCP — Claude Code, Claude Desktop ou um cliente personalizado — possa controlar os telefones Android e modems USB do laboratório.

É um cliente HTTP fino sobre a API REST existente (não importa internals do Flask), portanto, funciona contra qualquer instância omniweb-android acessível.

Ferramentas expostas

FerramentaAssinaturaO que faz
list_devices()Todos os dispositivos conhecidos (telefones + modems), online e offline.
device_info(serial)Detalhes completos de um dispositivo.
screenshot(serial) → imagem PNGTela atual (universal: telefones scrcpy E dispositivos de captura de tela antigos).
tap(serial, x, y)Toque nas coordenadas de pixel.
swipe(serial, x1, y1, x2, y2, ms=200)Deslizar/arrastar/largar.
input_text(serial, text)Digitar no campo focado.
key(serial, name)Pressionar voltar/início/recentes/enter/excluir/poder/menu/aumentar_volume/diminuir_volume.
adb_shell(serial, command, timeout=30){stdout, stderr, return_code}Comando adb shell arbitrário (ferramenta poderosa).
list_scripts()A biblioteca de scripts de teste do dispositivo.
run_script(serials, file, params={})Executar um script em vários dispositivos; retorna identificadores de execução.
get_run(run_id)Resultado de uma execução de script (status/stdout/código_de_retorno).
at_command(serial, command, read_ms=0, timeout_ms=0)Comando AT bruto para um modem USB.
send_sms(serial, number, text)Enviar um SMS de um modem.

Configuração (variáveis de ambiente)

Alvo do backend:

  • OMNIWEB_API_BASE — URL base do serviço android. Padrão http://127.0.0.1:5002. O prefixo /api/android é adicionado automaticamente.

Autenticação do backend (escolha UM):

  • OMNIWEB_JWT — um token de acesso de backend pré-mintado (Bearer), OU
  • OMNIWEB_JWT_SECRET — a JWT_SECRET_KEY do backend. O servidor então cria um JWT de admin de curta duração e o atualiza automaticamente. OMNIWEB_JWT_TTL (segundos, padrão 3600) controla sua duraç��o.

A própria porta de entrada deste servidor MCP:

  • MCP_TRANSPORThttp (padrão, HTTP transmitível para clientes remotos) ou stdio (local claude mcp add).
  • MCP_HOST / MCP_PORT — endereço de ligação para o transporte http. Padrão 127.0.0.1:5005.
  • MCP_AUTH_TOKEN — token bearer que um cliente MCP remoto deve apresentar. Necessário para se ligar a qualquer coisa além de localhost — o servidor recusa uma ligação não-loopback sem ele (falha fechada). No /mcp, o token é verificado pelo middleware; / e /health estão abertos para verificações de saúde.

Execute

venv (autônomo)

cd /opt/omniweb-mcp           # ou onde quer que você coloque 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=<a chave JWT_SECRET_KEY do backend>
export MCP_TRANSPORT=http
export MCP_HOST=0.0.0.0
export MCP_PORT=5005
export MCP_AUTH_TOKEN=<um token longo e aleatório>
venv/bin/python server.py

systemd (produção)

Uma unidade é fornecida em packaging/omniweb-android-mcp.service. Ela lê /etc/omniweb/omniweb.env (para JWT_SECRET_KEY → é re-exportada como OMNIWEB_JWT_SECRET, veja abaixo) além de /etc/omniweb/android-mcp.env para os segredos específicos do MCP. Crie esse drop-in (chmod 600):

# /etc/omniweb/android-mcp.env
OMNIWEB_JWT_SECRET=<mesmo valor que JWT_SECRET_KEY em omniweb.env>
MCP_AUTH_TOKEN=<um token longo e aleatório>

Então:

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

O arquivo de ambiente do backend nomeia o segredo JWT como JWT_SECRET_KEY; este servidor lê OMNIWEB_JWT_SECRET. Defina OMNIWEB_JWT_SECRET explicitamente em android-mcp.env (copie o valor) para que os nomes se alinhem.

Conectar do Claude Code

Remoto (HTTP transmitível), com autenticação:

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

Local (stdio), apontando o servidor para um backend e criando seu próprio 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

Então no Claude Code: /mcp para confirmar que se conectou e tente list_devices.

Conectar do Claude Desktop

claude_desktop_config.json ��� lançamento 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 um servidor remoto HTTP transmitível do Claude Desktop, use uma ponte mcp-remote ou a configuração do servidor HTTP suportada pela sua versão do Desktop, apontando para http://<host>:5005/mcp com o cabeçalho Authorization: Bearer &lt;MCP_AUTH_TOKEN>.

Notas de segurança

  • O controle do dispositivo requer o MCP_AUTH_TOKEN configurado no transporte HTTP. Sem token, o servidor apenas permite uma ligação de loopback e imprime um aviso; uma ligação não-loopback sem um token é recusada.
  • O servidor se autentica no backend como um admin (JWT criado ou token fornecido), então qualquer um que puder acessar /mcp com o token bearer tem controle total do dispositivo. Trate MCP_AUTH_TOKEN como uma senha e proteja-o com TLS (por exemplo, via nginx) para acesso fora do host.