PlatformIO MCP
Compile, grave e depure firmware embarcado para qualquer placa PlatformIO (ESP32, Arduino, STM32, RP2040): erros de compilador analisados, flash com verificação contra o log de boot serial, decodificação de backtrace de crash para arquivo:linha, relatórios de tamanho de firmware, testes unitários, análise estática. Python, uvx, sem Node.
Documentação
platformio.mcp
Dê ao seu agente de codificação de IA acesso a hardware real.
Um servidor MCP para PlatformIO: compile, grave (serial ou OTA), monitore a serial, execute testes, decodifique crashes e core dumps, verifique tabelas de partição, monitore heap e energia, depure via GDB, reduza o firmware.
Python nativo · sem Node · instalação em uma linha · funciona com Claude Code, Claude Desktop, Cursor, Codex, Windsurf, Cline
⚡ Instalação em 60 segundos
Você precisa do uv (curl -LsSf https://astral.sh/uv/install.sh | sh). Então:
uvx platformio.mcp install --claude-code # or --cursor --claude-desktop --codex --windsurf
Sem PlatformIO nesta máquina? Adicione --with-platformio e o servidor traz o PlatformIO Core junto. Extras opcionais: platformio.mcp[coredump] adiciona o analisador de core dump ESP32, platformio.mcp[power] adiciona o driver Nordic PPK2.
Qualquer outro cliente MCP (Cline, Zed, Continue, ...)
uvx platformio.mcp install --print
{ "mcpServers": { "platformio": { "command": "uvx", "args": ["platformio.mcp"] } } }
Use "args": ["platformio.mcp[platformio]"] para agrupar o PlatformIO Core.
Como plugin (Claude Code, Cursor: servidor + uma skill que ensina o loop)
O repositório segue o layout Open Plugins: .mcp.json, skills/platformio/SKILL.md, rules/platformio.mdc, plugin.json.
claude plugin marketplace add powerdragonfire/platformio.mcp # Claude Code
claude plugin install platformio@platformio.mcp
Já tem PlatformIO?
O servidor encontra platformio / pio no seu PATH ou em ~/.platformio/penv. Substitua com PLATFORMIO_MCP_PIO=/path/to/pio. Execute uvx platformio.mcp doctor para ver o que o agente verá.
🎬 Como funciona
Você: grave o env
viewe garanta que ele inicialize.Agente →
pio_flash_and_verify(env="view", expect="setup done")FAIL: firmware gravado, mas o log de boot correspondeu ao padrão de falha: 'Guru Meditation Error: Core 1 panic'ed (LoadProhibited)'. Causa: LoadProhibited. 3/3 endereços resolvidos: DisplayTask::run() (display_task.cpp:22) <- DisplayTask::run() (display_task.cpp:23) <- vPortTaskWrapper (port.c:143)Agente: ponteiro nulo na linha 22 de
display_task.cpp,tft_é usado antes debegin(). Corrigindo, recompilando, gravando novamente.PASS: env view gravado em 14.2s e 'setup done' visto em /dev/cu.usbserial-0001 após 2.1s de saída de boot.
Sem logs de build de 40 KB na janela de contexto. Sem humano lendo o monitor serial. O agente recebe um veredito, um arquivo e uma linha.
🔁 O loop que o agente executa
flowchart LR
A[pio_project_envs] --> B[edit code]
B --> C[pio_build]
C -- errors with file:line --> B
C -- ok --> D[pio_flash_and_verify]
D -- PASS --> E([done])
D -- FAIL: decoded backtrace --> B
D -- TIMEOUT --> F[pio_monitor_capture]
F --> B
🧰 As 40 ferramentas
| Grupo | Ferramentas | O que o agente recebe de volta |
|---|---|---|
| 🔍 Descobrir | pio_system_info · pio_list_boards · pio_board_info · pio_list_devices | Versão e política do PlatformIO; ~1.700 placas com MCU, clock, RAM e tamanhos de flash; portas seriais com as prováveis placas de desenvolvimento sinalizadas |
| 📁 Projeto | pio_project_init · pio_project_envs · pio_project_metadata | Um pio project init real (nunca um ini escrito à mão); cada env com placa, framework, configurações de monitor e upload; defines e caminhos de include |
| 🔨 Compilar & gravar | pio_build · pio_upload · pio_upload_ota · pio_clean · pio_list_targets · pio_run_target | Status, erros e avisos analisados (arquivo, linha, coluna), % de RAM/Flash, últimas 40 linhas, caminho do log completo. Alvos extras como buildfs, erase. OTA via Wi-Fi para placas ArduinoOTA. Falhas de porta retornam classificadas (ocupada, permissão, ausente, sem resposta) com a correção |
| 📟 Serial | pio_monitor_start / read / write / stop / list · pio_monitor_capture · pio_port_diagnose | Sessões em segundo plano com buffer circular, leituras por cursor e regex wait_for; ou uma captura única sem nada para gerenciar. Diagnóstico de porta: quem a segura (nossa sessão, outro processo), permissões, a correção |
| ✅ Verificar | pio_test · pio_check | Testes Unity com pass/fail por caso e mensagens; defeitos cppcheck / clang-tidy por severidade com IDs CWE |
| 📦 Pacotes | pio_pkg_search / install / uninstall / list / outdated / update · pio_deps_check | Busca no registro e mudanças de dependências que mantêm platformio.ini sincronizado; uma auditoria para colisões de nomes, especificações sem versão fixa, sobras e dependências circulares |
| 🧠 Analisar | pio_flash_and_verify · pio_decode_backtrace · pio_size_report | Pass/fail com hardware no loop; crash dumps resolvidos para arquivo:linha; para onde vai cada byte de flash e RAM |
| 💾 Layout de flash | pio_partition_table · pio_coredump | Verificações do CSV de partição ESP32 (alinhamento, sobreposição, ajuste, slots OTA) e um diff contra a tabela realmente no chip; core dump extraído do flash e decodificado |
| 📈 Runtime | pio_memory_watch · pio_power_profile | Telemetria de heap e pilha analisada da serial com veredito de vazamento e headroom por tarefa; consumo de corrente de um medidor serial ou um Nordic PPK2 com divisão sleep/active e estimativa de bateria |
| 🐞 Depurar | pio_debug_start / cmd / stop / list | Uma sessão GDB ao vivo via pio debug: breakpoints, step, backtrace, variáveis, com registros MI analisados em resultados estruturados |
Cada ferramenta retorna ok, um summary de um parágrafo escrito para o modelo, campos estruturados e um log_path para a saída completa. Saída longa permanece em disco em ~/.platformio-mcp/logs (os 200 arquivos mais recentes são mantidos).
As ferramentas que vão além da CLI
| O que faz | Por baixo dos panos | |
|---|---|---|
🚀 pio_flash_and_verify | Grava, abre a porta, lê até expect corresponder (pass), uma assinatura de crash corresponder (fail, decodificada automaticamente) ou o timeout passar (timeout) | pio run -t upload + pyserial; fail_on padrão para Guru Meditation, HardFault, abort(), assert failed, watchdog, brownout, corrupção de heap |
🩺 pio_decode_backtrace | Transforma um dump Backtrace: 0x400d... ESP32 ou um dump pc/lr Cortex-M em função, arquivo, linha, frames inline, causa, motivo de reset | Toolchain localizado a partir de pio project metadata, depois <target>-addr2line -pfiaC em firmware.elf; corrige bits de janela A0 Xtensa |
📊 pio_size_report | Por que o firmware é tão grande? % de Flash/RAM, seções carregadas, maiores símbolos com file:line, totais por arquivo, regex filter | pio run -t checkprogsize (ciente de partições) + GNU size -A + nm -S -C -l --size-sort |
💾 pio_partition_table | Detecta a corrupção silenciosa do ESP32 onde uma gravação apenas de app deixa uma tabela de partição antiga no chip; verificações de alinhamento, sobreposição, slot OTA e ajuste do app | Analisa o CSV de partição do env; read_device=true lê 0x8000 com esptool read_flash e faz diff |
🧯 pio_coredump | Extrai o core dump da partição coredump após um crash e decodifica tarefa, registradores e backtrace | esptool read_flash + esp-coredump info_corefile opcional (platformio.mcp[coredump]) |
📈 pio_memory_watch | Vereditos de vazamento, fragmentação e headroom de pilha a partir do que o firmware já imprime | Analisa linhas Free heap:, heap_caps_print_heap_info, vTaskList, uxTaskGetStackHighWaterMark; inclinação por mínimos quadrados |
🔋 pio_power_profile | Corrente média/mín/máx/p95, divisão sleep vs active, energia, estimativa de vida da bateria | Um medidor serial (sketch INA219, log de medidor USB) ou um Nordic PPK2 (platformio.mcp[power]) |
🐞 pio_debug_* | Breakpoints, step, backtrace e inspeção de variáveis através da sonda de depuração | pio debug --interface=gdb dirigido via GDB/MI com eventos *stopped analisados |
🌐 pio_upload_ota | Grava via Wi-Fi com falhas mapeadas para a correção (senha errada, sem ArduinoOTA.handle(), firewall, sem slot OTA) | pio run -t upload --upload-port <ip> (troca automática espota) ou espota.py diretamente |
🔌 pio_port_diagnose | Por que o upload não consegue abrir a porta: nossa sessão, outro processo, permissões ou uma placa que não está no modo bootloader | lsof/fuser + pio device list; nunca mata nada |
📚 pio_deps_check | Colisões de nomes de bibliotecas onde a ordem lib_deps escolhe silenciosamente o vencedor, especificações sem versão fixa, sobras, ciclos | Manifestos em .pio/libdeps e lib/, além do grafo de dependências LDF com build=true |
🔒 Política de segurança
Defina PLATFORMIO_MCP_POLICY no env do servidor, ou passe --policy para install:
| Política | Pode compilar | Pode gravar / apagar / escrever serial | Use para |
|---|---|---|---|
full (padrão) | ✅ | ✅ | Sua própria bancada |
build_only | ✅ | ❌ | Laboratórios compartilhados, CI, "olhe mas não toque" |
read_only | ❌ | ❌ | Revisão de código, integração, prompts não confiáveis |
Clientes MCP também solicitam confirmação antes de cada chamada de ferramenta. Políticas são a segunda camada, não a única.
⚙️ Configurações
| Variável | Finalidade | Padrão |
|---|---|---|
PLATFORMIO_MCP_POLICY | full, build_only, read_only | full |
PLATFORMIO_MCP_PROJECT_DIR | Projeto usado quando uma ferramenta é chamada sem project_dir | diretório de trabalho do servidor |
PLATFORMIO_MCP_PIO | Caminho explícito para o executável pio | detecção automática |
PLATFORMIO_MCP_LOG_DIR | Onde os logs completos de comandos vão | ~/.platformio-mcp/logs |
PLATFORMIO_MCP_MAX_LOGS | Quantos arquivos de log manter | 200 |
📝 Notas do monitor serial
As sessões falam com a porta via pyserial diretamente, porque o monitor próprio do PlatformIO precisa de um terminal interativo. Filtros do monitor do PlatformIO, como esp32_exception_decoder, portanto, não se aplicam; pio_decode_backtrace faz esse trabalho. Baud e porta usam padrão de monitor_speed / monitor_port em platformio.ini quando project_dir é passado; caso contrário, a única placa de desenvolvimento detectada a 115200. Abrir a porta redefine a maioria das placas de desenvolvimento, por isso pio_flash_and_verify vê o log de inicialização desde o início.
🛠️ Desenvolvimento
git clone https://github.com/powerdragonfire/platformio.mcp && cd platformio.mcp
uv sync
uv run pytest # unit tests, no hardware or network
uv run pytest -m integration # builds the bundled native fixture with your PlatformIO
uv run platformio-mcp doctor # what the agent's pio_system_info sees
npx @modelcontextprotocol/inspector uv run platformio-mcp # poke tools interactively
Para usar seu checkout no Claude Code em vez do lançamento PyPI:
claude mcp add platformio -- uv run --directory /path/to/platformio.mcp platformio-mcp
As alterações são rastreadas em CHANGELOG.md.
🤝 Contribuindo
Relatórios de bugs de placas reais são a coisa mais útil que você pode enviar. Use os formulários de issue, faça perguntas em Discussions e leia CONTRIBUTING.md antes de abrir um PR. Issues marcadas com good first issue são escopadas para iniciantes.
🔭 Trabalhos anteriores
jl-codes/platformio-mcp é um servidor TypeScript com o mesmo objetivo, um painel web e uma auditoria de pinos GPIO. Este projeto existe para pessoas que querem uma instalação somente Python via uvx, uma que possa incluir o próprio PlatformIO, e decodificação de crash, orçamento de tamanho, verificações de partição, core dumps, OTA, GDB ao vivo e perfil de memória/energia integrados.
Licença
MIT