arduino-app-lab-mcp-micropy
v0.1.1
Published
MCP server for MicroPython boards — direct serial REPL via micropython.js (the same library Arduino Lab IDE uses internally), no mpremote required
Maintainers
Readme
arduino-app-lab-mcp-micropy
MCP server for MicroPython boards using micropython.js — the same serial REPL library that Arduino Lab for MicroPython IDE uses internally.
No mpremote required. Connects directly to the board's serial REPL over serialport, keeps the connection alive across calls, and exposes a full REST API for running code, managing files, and controlling the board.
Ecosystem: Use alongside arduino-app-lab-mcp (mpremote + arduino-cli bridge, port 3095) and optionally arduino-mcp (Arduino CLI / IDE 2.0). This package is the native REPL path — no external Python tooling needed.
Install & run
npm install -g arduino-app-lab-mcp-micropy
arduino-app-lab-mcp-micropy
# → http://127.0.0.1:3096Or run without installing:
npx arduino-app-lab-mcp-micropyAPI
All responses: { "ok": true, "requestId": "…", "action": "…", … } or { "ok": false, "error": "…" }.
| Method | Path | Body / Params | Description |
|--------|------|---------------|-------------|
| GET | /health | — | Service status + detected boards |
| GET | /actions | — | List all 17 actions |
| GET | /boards | — | List connected MicroPython boards |
| POST | /connect | { "device": "COM4" } | Open serial connection to board |
| POST | /disconnect | { "device": "COM4" } | Close serial connection |
| POST | /run | { "code": "print(42)" } or { "file": "main.py" } | Run code or workspace file on board |
| POST | /exec | { "file": "main.py" } | Execute file from workspace or board FS |
| POST | /eval | { "expression": "1+1" } | Evaluate expression, return result |
| POST | /stop | { "device": "auto" } | Keyboard interrupt (Ctrl+C) |
| POST | /reset | { "device": "auto" } | Hard reset the board |
| POST | /upload | { "file": "main.py", "dest": "main.py" } | Copy workspace file → board |
| POST | /save_file | { "dest": "main.py", "content": "print(1)" } | Write string content directly to board file |
| POST | /download | { "file": "main.py" } | Copy board file → workspace |
| GET | /ls | ?dir=/&device=auto | List board filesystem |
| DELETE | /rm | { "file": "old.py" } | Remove file from board |
| POST | /mkdir | { "dir": "/lib" } | Create directory on board |
| DELETE | /rmdir | { "dir": "/lib" } | Remove directory from board |
| POST | /rename | { "from": "old.py", "to": "new.py" } | Rename file on board |
| GET | /file_exists | ?file=main.py&device=auto | Check if file exists on board |
Device path
"device": "auto" picks the first board with a vendorId/productId. Or specify explicitly:
- Windows:
"device": "COM4" - Linux/Pi:
"device": "/dev/ttyACM0" - macOS:
"device": "/dev/cu.usbmodem14101"
Connections are kept alive between calls — no reconnect overhead per request.
Examples
# List detected boards
curl http://127.0.0.1:3096/boards
# Connect
curl -X POST http://127.0.0.1:3096/connect \
-H "Content-Type: application/json" \
-d '{"device":"COM4"}'
# Run code
curl -X POST http://127.0.0.1:3096/run \
-H "Content-Type: application/json" \
-d '{"code":"import sys; print(sys.version)","device":"COM4"}'
# Write main.py directly to board
curl -X POST http://127.0.0.1:3096/save_file \
-H "Content-Type: application/json" \
-d '{"dest":"main.py","content":"from machine import Pin\nled=Pin(13,Pin.OUT)\nled.on()","device":"COM4"}'
# List files
curl "http://127.0.0.1:3096/ls?dir=/&device=COM4"Environment
| Variable | Default | Description |
|----------|---------|-------------|
| PORT | 3096 | HTTP port |
| APPLAB_DEVICE | auto | Default serial port |
| APPLAB_WORKSPACE | ./workspace | Local workspace for file operations |
| APPLAB_RUN_TIMEOUT_MS | 30000 | Timeout for run/upload/download (ms) |
| APPLAB_EXEC_TIMEOUT_MS | 10000 | Timeout for eval/ls/exec (ms) |
| LOG_REQUESTS | 0 | Set 1 to log every request |
Copy .env.example to .env to configure locally.
Docker
docker build -t arduino-app-lab-mcp-micropy:latest .
docker run --rm --network host \
-e PORT=3096 \
--device /dev/ttyACM0 \
-v $(pwd)/workspace:/workspace \
arduino-app-lab-mcp-micropy:latestHow it works
Agent → HTTP POST → arduino-app-lab-mcp-micropy → micropython.js
↓
serialport (115200 baud)
↓
MicroPython Raw REPL
↓
Board (Pico, ESP32, UNO R4…)Uses the same micropython.js library bundled inside the Arduino Lab for MicroPython Electron IDE — vendored from Arduino.Lab.for.MicroPython/resources/app.asar.
Boards supported
Arduino UNO R4 Minima/WiFi (with MicroPython firmware), Nano RP2040 Connect, Portenta H7, GIGA R1, Raspberry Pi Pico/W, ESP32, ESP8266 — any board with a MicroPython REPL accessible over serial.
Related
- arduino-app-lab-mcp — Sister package: mpremote + arduino-cli bridge (port 3095). Use for UNO Q sketch upload and mpremote workflows.
- arduino-mcp — Arduino CLI / IDE 2.0 MCP server. Install alongside for extended CLI functionality.
Author
Eoin Jordan — eoinjordan.github.io — for more projects, related work, or suggestions.
License
MIT © Eoin Jordan
