PlatformIO MCP
Compila, flashea y depura firmware embebido para cualquier placa PlatformIO (ESP32, Arduino, STM32, RP2040): errores de compilador analizados, flash y verificación contra el registro de arranque serial, decodificación de backtraces de fallos a archivo:línea, informes de tamaño de firmware, pruebas unitarias, análisis estático. Python, uvx, sin Node.
Documentación
platformio.mcp
Dale a tu agente de codificación IA manos sobre hardware real.
Un servidor MCP para PlatformIO: compila, flashea (serial u OTA), observa el serial, ejecuta pruebas, decodifica fallos y volcados de núcleo, revisa tablas de particiones, observa heap y energía, depura con GDB, reduce firmware.
Python nativo · sin Node · una línea para instalar · funciona con Claude Code, Claude Desktop, Cursor, Codex, Windsurf, Cline
⚡ Instalación en 60 segundos
Necesitas uv (curl -LsSf https://astral.sh/uv/install.sh | sh). Luego:
uvx platformio.mcp install --claude-code # or --cursor --claude-desktop --codex --windsurf
¿No tienes PlatformIO en esta máquina? Añade --with-platformio y el servidor trae PlatformIO Core consigo. Extras opcionales: platformio.mcp[coredump] añade el analizador de volcados de núcleo ESP32, platformio.mcp[power] añade el controlador Nordic PPK2.
Cualquier otro cliente MCP (Cline, Zed, Continue, ...)
uvx platformio.mcp install --print
{ "mcpServers": { "platformio": { "command": "uvx", "args": ["platformio.mcp"] } } }
Usa "args": ["platformio.mcp[platformio]"] para agrupar PlatformIO Core.
Como plugin (Claude Code, Cursor: servidor + una habilidad que enseña el bucle)
El repositorio sigue el diseño de 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
¿Ya tienes PlatformIO?
El servidor encuentra platformio / pio en tu PATH o en ~/.platformio/penv. Anula con PLATFORMIO_MCP_PIO=/path/to/pio. Ejecuta uvx platformio.mcp doctor para ver lo que verá el agente.
🎬 Cómo se ve
Tú: flashea el entorno
viewy asegúrate de que arranque.Agente →
pio_flash_and_verify(env="view", expect="setup done")FALLO: firmware flasheado pero el registro de arranque coincidió con el patrón de fallo: 'Guru Meditation Error: Core 1 panic'ed (LoadProhibited)'. Causa: LoadProhibited. 3/3 direcciones resueltas: DisplayTask::run() (display_task.cpp:22) <- DisplayTask::run() (display_task.cpp:23) <- vPortTaskWrapper (port.c:143)Agente: puntero nulo en la línea 22 de
display_task.cpp,tft_se usa antes debegin(). Corrigiendo, recompilando, flasheando de nuevo.ÉXITO: entorno flasheado en 14.2s y se vio 'setup done' en /dev/cu.usbserial-0001 después de 2.1s de salida de arranque.
Sin registros de compilación de 40 KB en la ventana de contexto. Sin humanos leyendo el monitor serial. El agente obtiene un veredicto, un archivo y una línea.
🔁 El bucle que ejecuta el agente
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
🧰 Las 40 herramientas
| Grupo | Herramientas | Lo que el agente recibe |
|---|---|---|
| 🔍 Descubrir | pio_system_info · pio_list_boards · pio_board_info · pio_list_devices | Versión y política de PlatformIO; ~1,700 placas con MCU, reloj, RAM y tamaños de flash; puertos seriales con las placas de desarrollo probables marcadas |
| 📁 Proyecto | pio_project_init · pio_project_envs · pio_project_metadata | Un pio project init real (nunca un ini escrito a mano); cada entorno con placa, framework, configuración de monitor y subida; definiciones y rutas de inclusión |
| 🔨 Compilar y flashear | pio_build · pio_upload · pio_upload_ota · pio_clean · pio_list_targets · pio_run_target | Estado, errores y advertencias analizados (archivo, línea, columna), % de RAM/Flash, últimas 40 líneas, ruta del registro completo. Objetivos extra como buildfs, erase. OTA por Wi-Fi a placas ArduinoOTA. Los fallos de puerto se devuelven clasificados (ocupado, permiso, faltante, sin respuesta) con la solución |
| 📟 Serial | pio_monitor_start / read / write / stop / list · pio_monitor_capture · pio_port_diagnose | Sesiones en segundo plano con un búfer circular, lecturas con cursor y regex wait_for; o una captura de una sola vez sin nada que gestionar. Diagnóstico de puerto: quién lo tiene (nuestra sesión, otro proceso), permisos, la solución |
| ✅ Verificar | pio_test · pio_check | Pruebas Unity con aprobado/fallo por caso y mensajes; defectos de cppcheck / clang-tidy por severidad con IDs CWE |
| 📦 Paquetes | pio_pkg_search / install / uninstall / list / outdated / update · pio_deps_check | Búsqueda en el registro y cambios de dependencias que mantienen platformio.ini sincronizado; una auditoría de colisiones de nombres, especificaciones sin fijar, sobras y dependencias circulares |
| 🧠 Analizar | pio_flash_and_verify · pio_decode_backtrace · pio_size_report | Aprobado/fallo con hardware en el bucle; volcados de fallo resueltos a archivo:línea; a dónde va cada byte de flash y RAM |
| 💾 Diseño de flash | pio_partition_table · pio_coredump | Comprobaciones CSV de particiones ESP32 (alineación, solapamiento, ajuste, ranuras OTA) y un diff contra la tabla realmente en el chip; volcado de núcleo extraído del flash y decodificado |
| 📈 Tiempo de ejecución | pio_memory_watch · pio_power_profile | Telemetría de heap y pila analizada desde el serial con un veredicto de fuga y margen por tarea; consumo de corriente desde un medidor serial o un Nordic PPK2 con división sueño/activo y estimación de batería |
| 🐞 Depurar | pio_debug_start / cmd / stop / list | Una sesión GDB en vivo a través de pio debug: puntos de interrupción, paso, backtrace, variables, con registros MI analizados en resultados estructurados |
Cada herramienta devuelve ok, un summary de un párrafo escrito para el modelo, campos estructurados y un log_path a la salida completa. La salida larga permanece en disco bajo ~/.platformio-mcp/logs (se conservan los 200 archivos más recientes).
Las herramientas que van más allá de la CLI
| Qué hace | Bajo el capó | |
|---|---|---|
🚀 pio_flash_and_verify | Flashea, abre el puerto, lee hasta que expect coincide (aprobado), una firma de fallo coincide (fallo, auto-decodificado), o el tiempo de espera pasa (tiempo agotado) | pio run -t upload + pyserial; fail_on por defecto a Guru Meditation, HardFault, abort(), assert failed, watchdog, brownout, corrupción de heap |
🩺 pio_decode_backtrace | Convierte un volcado Backtrace: 0x400d... ESP32 o un volcado pc/lr Cortex-M en función, archivo, línea, marcos inline, causa, motivo de reinicio | Toolchain localizado desde pio project metadata, luego <target>-addr2line -pfiaC en firmware.elf; corrige bits de ventana A0 Xtensa |
📊 pio_size_report | ¿Por qué el firmware es tan grande? % de Flash/RAM, secciones cargadas, símbolos más grandes con file:line, totales por archivo, regex filter | pio run -t checkprogsize (consciente de particiones) + GNU size -A + nm -S -C -l --size-sort |
💾 pio_partition_table | Detecta la corrupción silenciosa de ESP32 donde un flash solo de aplicación deja una tabla de particiones antigua en el chip; comprobaciones de alineación, solapamiento, ranura OTA y ajuste de aplicación | Analiza el CSV de particiones del entorno; read_device=true lee 0x8000 con esptool read_flash y hace diff |
🧯 pio_coredump | Extrae el volcado de núcleo de la partición coredump después de un fallo y decodifica tarea, registros y backtrace | esptool read_flash + esp-coredump info_corefile opcional (platformio.mcp[coredump]) |
📈 pio_memory_watch | Veredictos de fuga, fragmentación y margen de pila desde lo que el firmware ya imprime | Analiza líneas Free heap:, heap_caps_print_heap_info, vTaskList, uxTaskGetStackHighWaterMark; pendiente de mínimos cuadrados |
🔋 pio_power_profile | Corriente promedio/mín/máx/p95, división sueño vs activo, energía, estimación de vida de batería | Un medidor serial (sketch INA219, registro de medidor USB) o un Nordic PPK2 (platformio.mcp[power]) |
🐞 pio_debug_* | Puntos de interrupción, paso, backtrace e inspección de variables a través de la sonda de depuración | pio debug --interface=gdb controlado sobre GDB/MI con eventos *stopped analizados |
🌐 pio_upload_ota | Flashea por Wi-Fi con fallos mapeados a la solución (contraseña incorrecta, sin ArduinoOTA.handle(), firewall, sin ranura OTA) | pio run -t upload --upload-port <ip> (auto-cambio espota) o espota.py directamente |
🔌 pio_port_diagnose | Por qué la subida no puede abrir el puerto: nuestra sesión, otro proceso, permisos, o una placa que no está en modo bootloader | lsof/fuser + pio device list; nunca mata nada |
📚 pio_deps_check | Colisiones de nombres de librerías donde el orden lib_deps elige silenciosamente al ganador, especificaciones sin fijar, sobras, ciclos | Manifiestos en .pio/libdeps y lib/, más el grafo de dependencias LDF con build=true |
🔒 Política de seguridad
Establece PLATFORMIO_MCP_POLICY en el env del servidor, o pasa --policy a install:
| Política | Puede compilar | Puede flashear / borrar / escribir en serie | Úsalo para |
|---|---|---|---|
full (predeterminada) | ✅ | ✅ | Tu propio banco de trabajo |
build_only | ✅ | ❌ | Laboratorios compartidos, CI, "mira pero no toques" |
read_only | ❌ | ❌ | Revisión de código, incorporación, prompts no confiables |
Los clientes MCP también solicitan confirmación antes de cada llamada a herramienta. Las políticas son la segunda capa, no la única.
⚙️ Configuración
| Variable | Propósito | Predeterminado |
|---|---|---|
PLATFORMIO_MCP_POLICY | full, build_only, read_only | full |
PLATFORMIO_MCP_PROJECT_DIR | Proyecto utilizado cuando se llama a una herramienta sin project_dir | cwd del servidor |
PLATFORMIO_MCP_PIO | Ruta explícita al ejecutable de pio | detección automática |
PLATFORMIO_MCP_LOG_DIR | Dónde van los registros completos de comandos | ~/.platformio-mcp/logs |
PLATFORMIO_MCP_MAX_LOGS | Cuántos archivos de registro conservar | 200 |
📝 Notas del monitor serie
Las sesiones hablan con el puerto usando pyserial directamente, porque el monitor propio de PlatformIO necesita una terminal interactiva. Por lo tanto, los filtros del monitor de PlatformIO como esp32_exception_decoder no se aplican; pio_decode_backtrace hace ese trabajo. El baud y el puerto se toman por defecto de monitor_speed / monitor_port en platformio.ini cuando se pasa project_dir, de lo contrario, la única placa de desarrollo detectada a 115200. Abrir el puerto reinicia la mayoría de las placas de desarrollo, por eso pio_flash_and_verify ve el registro de arranque desde el principio.
🛠️ Desarrollo
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 tu copia local en Claude Code en lugar de la versión de PyPI:
claude mcp add platformio -- uv run --directory /path/to/platformio.mcp platformio-mcp
Los cambios se registran en CHANGELOG.md.
🤝 Contribuciones
Los informes de errores de placas reales son lo más útil que puedes enviar. Usa los formularios de problemas, haz preguntas en Discussions y lee CONTRIBUTING.md antes de abrir un PR. Los problemas etiquetados como good first issue están pensados para principiantes.
🔭 Trabajo previo
jl-codes/platformio-mcp es un servidor TypeScript con el mismo objetivo, un panel web y una auditoría de pines GPIO. Este proyecto existe para personas que quieren una instalación solo con Python a través de uvx, una que pueda incluir PlatformIO en sí mismo, y decodificación de fallos, presupuesto de tamaño, comprobaciones de particiones, volcados de núcleo, OTA, GDB en vivo y perfiles de memoria/energía integrados.
Licencia
MIT