npx pio-mcp dashboard
That's the install. Open a terminal anywhere — your laptop, a fresh VM, a coworker's machine — type one line, and you get a React dashboard wired to PlatformIO Core. From there an LLM can compile firmware, flash it to a real board, and stream serial back to the same browser tab.
platformio-mcp v2.0.0 shipped to npm. Here's why and how.
The gap
LLMs are stupidly good at writing firmware. Hand Claude a datasheet and it'll spit out C++ that compiles. Hand it the FreeRTOS docs and it'll wire up a queue without breaking a sweat.
The next step always falls apart.
"Great, now flash it to the ESP32 sitting on my desk."
You get back a markdown wall of "first install pyenv, then bootstrap a venv, then pip install platformio, then check your USB-C cable supports data, then make sure the right udev rule is in place on Linux, then..." It's a setup-doc generator. The agent has read every PlatformIO tutorial ever written. It still can't push bytes to flash memory because it has no hands.
MCP is the hands. The agent calls a tool, the tool runs on your machine, the result comes back. PlatformIO Core is already a CLI that knows how to talk to ~1,000 boards across 30+ platforms (ESP32-S3, RP2040, STM32H7, nRF52840, ATmega328P, Teensy 4.1, SAMD21, ATtiny85, and so on). I exposed it through MCP. That's the whole product.
What v2.0.0 actually does
Nine MCP tools. Each one is a thin wrapper around a pio subcommand:
list_boards → pio boards <filter>
init_project → pio project init
build_project → pio run (background mode + status polling)
upload_firmware → pio run --target upload (optional start_monitor)
list_devices → pio device list
serial_monitor → pio device monitor (non-blocking, streamed)
search_libraries → pio pkg search
install_library → pio pkg install
list_libraries → pio pkg list
get_dashboard_url → returns localhost URL with bound auth token
Plus init_project, the unsung hero. PlatformIO project scaffolding is the thing agents got wrong every single time before this — they'd hand-write a platformio.ini with three subtle bugs in the board_build section. The MCP tool just shells out to pio project init and the bugs vanish.
The demo that closes the deal
Real prompt, real ESP32, real flash:
> Initialize a new Arduino project for an ESP32 Dev Board in /tmp/esp32-blink.
Build it, flash it, and start the serial monitor.
The agent's tool calls, in order:
list_boards { filter: "esp32" } → esp32dev
init_project { board: "esp32dev", framework: "arduino",
projectDir: "/tmp/esp32-blink" }
build_project { projectDir: "/tmp/esp32-blink" } → SUCCESS
upload_firmware { projectDir: "/tmp/esp32-blink",
start_monitor: true } → flashed
End-to-end on a clean machine: ~90 seconds. Most of that is the PlatformIO toolchain pulling esptool and the Espressif SDK on first run. Subsequent flashes are sub-10s.
Install in one command
We make it easy to integrate PIO MCP into your choice of coding agent. v2.0.0 ships a one-shot installer:
npx platformio-mcp install --cline # Cline (VS Code extension or CLI)
npx platformio-mcp install --claude # Claude Desktop
npx platformio-mcp install --vscode # VS Code native MCP support
npx platformio-mcp install --antigravity # Google Antigravity
Each installer:
- Resolves the host's config path per OS. macOS goes to
~/Library/Application Support, Windows reads%APPDATA%, Linux falls back to~/.config. There's a 9-lineappDataDir()helper that does the dispatch. - Reads the existing config if one's already there.
- If the JSON is corrupted, copies it to
<path>.bakbefore rewriting. I learned this the hard way. - Idempotently merges an
mcpServers.platformioblock. Re-running the installer is a no-op. - Prints the path it touched so you can grep for it later.
For any other MCP host, this is the manual config block:
{
"mcpServers": {
"platformio": {
"command": "npx",
"args": ["-y", "platformio-mcp", "--open-dashboard-on-start"]
}
}
}
The dashboard
The dashboard is the part nobody asks for and everybody uses once they have it.
Reason: build output is the worst possible thing to feed back to an LLM. A clean pio run for an ESP32 project is 40+ kilobytes of toolchain noise — arm-none-eabi-gcc flags, linker incantations, every single .o file. Pour that into the agent's context and you've spent a third of your token budget on text the agent doesn't need.
So the MCP tools return short, structured summaries to the LLM. The full output streams over Socket.io to a React dashboard the human can watch:
A per-process random UUID is injected as PORTAL_AUTH_TOKEN at boot. Every HTTP request and every Socket.io connection requires it. The dashboard URL looks like http://localhost:8080?token=<uuid> and that token isn't in any config file or env var the LLM has access to. If you launch the dashboard, only you (and the agent that spawned it) can hit the API.
The auto-launch is gated behind --open-dashboard-on-start (or the PIO_MCP_OPEN_DASH_ON_START=true env var). Browser launch goes through the open package, so the same call works on macOS, Linux, and Windows. The previous version had a hardcoded exec('open ...') that only fired on macOS — patched in v2.0.0.
Things I'm proud of that nobody will notice
- The tarball is 499 kB. 114 files.
build/+web/dist/+scripts/installers/+ LICENSE + README. Nonode_modules, no tests, noweb/src/. The minified UI bundle is 921 kB / 291 kB gzip on its own; everything else is rounding error. -
prepublishOnlyruns the full TypeScript build, the Vite UI build, and a smoke check that assertsbuild/index.js,web/dist/index.html, andscripts/installers/index.jsexist before npm allows the publish to proceed. Hard to ship a broken artifact. - Workspace state is mediated through
proper-lockfile. Two agent processes can't race each other on the same project. If you've ever had two MCP servers fight over the same serial port, you know why this matters. - The
pio-mcpalias package is 842 bytes. Three files: a 283-bytebin.jsthat doesimport("platformio-mcp"), apackage.jsonwith one dependency, a README. Same binary, shorter to type. - The default
npx platformio-mcp(no subcommand) still boots the MCP stdio server. Existing configs that point atbuild/index.jskeep working unchanged. v2 is additive.
Get started in five seconds
# Open the dashboard right now. No clone, no build, no install.
npx pio-mcp dashboard
# Wire it into your AI agent of choice.
npx platformio-mcp install --cline
npx platformio-mcp install --claude
npx platformio-mcp install --vscode
npx platformio-mcp install --antigravity
Repo: github.com/jl-codes/platformio-mcp
npm: platformio-mcp · pio-mcp
Release notes: v2.0.0
I'm @forkbombETH on X. Issues and PRs welcome on GitHub. If you build something cool with this, lmk.
npx pio-mcp dashboard
A huge warm thank you to Matt Mcneill for being an amazing collaborator and pushing for the features that make v2 amazing!
Top comments (0)