pymcuprog-mcp
# pymcuprog-mcp
MCP server wrapping [pymcuprog](https://github.com/microchip-pic-avr-tools/pymcuprog) so AI tools (Claude Code, Claude Desktop, etc.) can program Microchip AVR microcontrollers via natural language.
Supports USB HID debuggers (nEDBG, PICkit 4, Atmel-ICE, MPLAB Snap, …) and serial UART UPDI adapters.
## Installation
No installation needed if you use `uvx` — it runs the server directly from PyPI on demand (see `.mcp.json` examples below).
To install as a persistent tool:
```bash
uv tool install pymcuprog-mcp
```
Or with pip:
```bash
pip install pymcuprog-mcp
```
From source:
```bash
git clone https://github.com/lucasgerads/pymcuprog-mcp
cd pymcuprog-mcp
pip install -e .
```
## Configuration
The server is configured via environment variables. The two most important ones are `PYMCUPROG_DEVICE` (target MCU name, e.g. `atmega4808`) and `PYMCUPROG_TOOL` (debugger type, e.g. `nedbg`).
| Variable | Description | Default |
|---|---|---|
| `PYMCUPROG_DEVICE` | Target device name (e.g. `atmega4808`, `attiny416`) | — |
| `PYMCUPROG_TOOL` | Debugger type (`nedbg`, `pickit4`, `atmelice`, `snap`, …) | any connected |
| `PYMCUPROG_SERIALNUMBER` | USB serial number substring (to pick a specific tool) | — |
| `PYMCUPROG_SERIALPORT` | Serial port for UART UPDI mode (e.g. `/dev/ttyUSB0`, `COM3`) | — |
| `PYMCUPROG_BAUDRATE` | Baud rate for serial UPDI mode | `115200` |
| `PYMCUPROG_PROJECT_DIR` | Default project directory for the `build_and_flash` tool | — |
Setting `PYMCUPROG_SERIALPORT` switches the server into serial UPDI mode (uses a plain USB-serial adapter instead of a Microchip debugger).
## `.mcp.json` examples
All examples use `uvx`, which downloads and runs the server directly from PyPI with no prior installation step.
### USB HID debugger (nEDBG / Curiosity Nano)
```json
{
"mcpServers": {
"pymcuprog": {
"command": "uvx",
"args": ["pymcuprog-mcp"],
"env": {
"PYMCUPROG_DEVICE": "atmega4808",
"PYMCUPROG_TOOL": "nedbg"
}
}
}
}
```
### PICkit 4 or MPLAB Snap
```json
{
"mcpServers": {
"pymcuprog": {
"command": "uvx",
"args": ["pymcuprog-mcp"],
"env": {
"PYMCUPROG_DEVICE": "attiny416",
"PYMCUPROG_TOOL": "pickit4"
}
}
}
}
```
### Serial UART UPDI (cheap USB-serial adapter)
```json
{
"mcpServers": {
"pymcuprog": {
"command": "uvx",
"args": ["pymcuprog-mcp"],
"env": {
"PYMCUPROG_DEVICE": "avr128da48",
"PYMCUPROG_SERIALPORT": "/dev/ttyUSB0",
"PYMCUPROG_BAUDRATE": "115200"
}
}
}
}
```
### Multiple tools on the same machine (select by serial number)
```json
{
"mcpServers": {
"pymcuprog-board-a": {
"command": "uvx",
"args": ["pymcuprog-mcp"],
"env": {
"PYMCUPROG_DEVICE": "atmega4808",
"PYMCUPROG_TOOL": "nedbg",
"PYMCUPROG_SERIALNUMBER": "MCHP0001"
}
},
"pymcuprog-board-b": {
"command": "uvx",
"args": ["pymcuprog-mcp"],
"env": {
"PYMCUPROG_DEVICE": "atmega4808",
"PYMCUPROG_TOOL": "nedbg",
"PYMCUPROG_SERIALNUMBER": "MCHP0002"
}
}
}
}
```
### Claude Code (via CLI)
```bash
claude mcp add pymcuprog -e PYMCUPROG_DEVICE=atmega4808 -e PYMCUPROG_TOOL=nedbg -- uvx pymcuprog-mcp
```
## Available tools
| Tool | Description |
|---|---|
| `list_supported_devices` | All device names pymcuprog knows (no hardware needed) |
| `list_connected_tools` | USB HID debuggers currently attached |
| `ping` | Read device ID bytes to verify connectivity |
| `erase` | Chip erase or erase a specific memory area |
| `flash` | Erase + write + verify + release in one call (recommended) |
| `build_and_flash` | Run `make` in a project directory, then flash the resulting `.hex` |
| `write_hex` | Program a `.hex` file with manual control over erase/verify steps |
| `verify_hex` | Compare target memory to a `.hex` file |
| `read_memory` | Read raw bytes from flash, EEPROM, fuses, etc. |
| `write_memory` | Write raw hex bytes to fuses, EEPROM, user_row, etc. |
| `hold_in_reset` | Hold target in reset |
| `release_from_reset` | Release target from reset |
| `disconnect` | Close the persistent debugger session |
| `read_target_voltage` | Measure target VCC |
| `read_supply_voltage` | Read debugger supply setpoint |
| `set_supply_voltage` | Set debugger supply voltage output |
| `read_tool_info` | Read debugger firmware/hardware info |
Typical workflow: **`ping` → `flash`** or **`ping` → `build_and_flash`**
All programming tools accept optional `device`, `tool`, `serialport`, etc. parameters to override the environment variables on a per-call basis.
TDQS
Scored across 18 tools
Most tools have distinct purposes with clear descriptions, but there is some overlap between flash, write_hex, write_memory, and build_and_flash. The descriptions clarify differences, so agents can generally choose correctly.
Tool names predominantly use snake_case with a verb_noun pattern, but some are single verbs (erase, flash, ping) and a few combine verb_verb (build_and_flash) or verb_prep_noun (hold_in_reset), creating minor inconsistencies.
18 tools cover the full programming workflow—connection, programming, memory ops, voltage control, info—without being excessive. Each tool serves a distinct need for the domain.
The tool set covers build, erase, write, verify, read, reset, voltage control, and tool info. Missing specialized fuse/lockbit tools are mitigated by write_memory/read_memory, making the surface complete for typical use.