LLM usando ferramentas (MCP)
tools/war3_mcp.py é um servidor MCP. Conecte-o ao Claude Code, ao Claude Desktop ou a qualquer cliente com suporte a MCP, e o LLM passa a ver a partida, dar comandos, falar com o jogador na tela, perguntar ao jogador com cartões e tirar capturas de tela diretamente, sem escrever código antes.
tools/war3_mcp.py é um servidor MCP (stdio). Claude Code, Claude Desktop, frameworks de agentes para modelos locais — conecte-o a qualquer cliente com suporte a MCP, e o LLM passa a diretamente ver a partida, dar comandos, falar com o jogador na tela do jogo, fazer perguntas ao jogador e tirar capturas de tela, sem escrever código antes.
Além de escrever Bots, aconselhar e dar voz às unidades, esta é mais uma forma de conexão: o próprio LLM é quem usa as ferramentas.
Conectando
claude mcp add war3 -- python <repositório>\tools\war3_mcp.py --inst 9 # Claude Code; troque <repositório> pela sua pasta do openwar3
Em outros clientes, escreva a configuração neste formato:
{"mcpServers": {"war3": {"command": "python", "args": ["<repositório>\\tools\\war3_mcp.py", "--inst", "9"]}}}
A conexão com o jogo só acontece na primeira chamada de ferramenta, então o jogo pode ser aberto depois; se o jogo for fechado e aberto de novo, a próxima chamada reconecta sozinha. Acrescente --role para limitar o que o LLM pode fazer:
| Papel | O que pode usar |
|---|---|
dev (padrão) | Todas as ferramentas, inclusive war3_jass |
player --player N | Só comanda as unidades do jogador N e só enxerga a visão dele (modo justo); sem JASS |
observer | Só leitura; não pode desenhar na tela nem fazer unidades falarem; o runtime rejeita direto os comandos que ele enviar |
O papel player tem as mesmas limitações do gateway: não pode encerrar a partida, mudar a velocidade nem pausar, não tem acesso às APIs que mostram as cartas dos outros, e consultas que levam número de jogador só podem consultar o próprio jogador.
Alguns limites: o resultado de uma ferramenta tem no máximo 200 mil caracteres; o que passar disso é cortado, com uma dica de como restringir a consulta; war3_ask_player espera no máximo 120 segundos; o scale da captura de tela fica entre 0.1 e 1.
Ferramentas
| Ferramenta | O que faz |
|---|---|
war3_overview | Resumo da partida numa página: tempo, recursos, comida, contagem de cada tipo de unidade nossa, heróis (vida, mana, nível, recargas), tipos de unidades inimigas visíveis, produção. Chame esta primeiro |
war3_units | Lista de unidades (owner aceita me / enemy / creep / all, types filtra); o addr serve para dar comandos |
war3_events | O que aconteceu desde a última chamada: mortes, subidas de nível, feitiços, produção concluída, chat, o jogador clicou num botão… (por padrão, remove alguns tipos que inundam o log) |
war3_call | Chama qualquer API pública (move, attack_move, train, build, cast, learn, ui.button, canvas.text…); unidades são escritas como {"unit": addr} |
war3_api | Consulta a API: busca nomes e descrições por palavra-chave |
war3_toast / war3_say | Uma linha de texto no alto da tela / uma frase sobre a cabeça de uma unidade |
war3_ask_player | Mostra alguns cartões de escolha no meio da tela, espera o jogador clicar e retorna qual foi escolhido (pode pausar o jogo) |
war3_screenshot | Captura da tela do jogo (PNG; funciona mesmo com a janela coberta, sem roubar o foco) |
war3_jass | Executa um trecho de JASS (só para dev; alterações no mundo só em partida solo) |
O que dá para fazer:
- Parceiro de jogo / coach:
war3_overviewpara ver a partida,war3_toastpara dar conselhos na tela; - Perguntar ao jogador durante a partida:
war3_ask_playermostra três cartões, e o que o jogador clicar é o que vale; - Narração:
war3_eventspara ler o que aconteceu,war3_saypara as próprias unidades contarem; - Comandar uma tropa diretamente: papel
player+war3_call, só com as próprias unidades; - Ajustar a interface olhando a imagem:
war3_screenshottira uma captura, e o modelo confere se os botões que desenhou estão no lugar certo.
Uma conversa típica
Você: Veja como está a partida e depois me pergunte na tela: próximo passo é expandir, fazer mais tropas ou subir de tier?
→ war3_overview {}
← Resumo da partida: tempo de jogo, ouro 500, comida 10/12, nossas htow 1 · hpea 5 · Hpal 1, nenhum inimigo visível, nada em produção
→ war3_ask_player {"question": "Próximo passo?", "options": ["Mais tropas", "Expandir", "Subir de tier"], "pause": true}
← {"picked": 1, "option": "Expandir"}
Modelo: Você escolheu expandir. Primeiro vou usar war3_units para achar um camponês ocioso e depois ver onde fica a mina de ouro mais próxima…
Medições
2026-09-25:
- Nosso próprio cliente MCP conectado a uma partida real, 7/7: handshake → listar ferramentas (10) →
war3_overview(htow1,hpea5) →war3_units→war3_toast→war3_screenshot(PNG de cerca de 200 mil bytes) →war3_ask_player(três cartões, clique simulado no segundo →{"picked": 1, "option": "开矿"}, ou seja, “expandir”). - Conectado de verdade no Claude Code 2.1: ele mesmo iniciou o servidor e fez o handshake, com status
connected, e as 10 ferramentas apareceram na lista de ferramentas dele comomcp__war3__*.
Implementação
- JSON-RPC 2.0 separado por quebras de linha (
initialize/tools/list/tools/call/ping), versão do protocolo 2025-06-18, compatível com 2025-03-26 e 2024-11-05. - Erros de ferramenta vão no resultado, como manda o MCP (
isError: true), sem desconectar. - Usa a mesma lista de permissões por papel, o mesmo formato de parâmetros de unidade e o mesmo “resumo da partida” do gateway.
- Os logs vão para stderr; stdout só tem o protocolo.