embedded-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@embedded-mcp Read serial output from COM5 for 5 seconds"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
embedded-mcp
Let an AI assistant read, command, and debug your microcontroller — over plain serial.
embedded-mcp is a Model Context Protocol server. It gives an MCP-capable client (Claude Desktop, Claude Code, …) a small set of tools to talk to a real board over a serial port.
When you debug firmware, your AI pair can now see what the board prints and poke it back — instead of you copy-pasting the serial monitor by hand.
┌─────────────┐ MCP (stdio) ┌───────────────┐ UART / USB-serial ┌──────────────┐
│ AI client │ ◄────────────────► │ embedded-mcp │ ◄────────────────────► │ your board │
│ (Claude) │ │ (this repo) │ (pyserial) │ STM32 / ... │
└─────────────┘ └───────────────┘ └──────────────┘Why
Embedded debugging is a loop of flash → watch the serial monitor → send a command → read the dump → decode a register against the datasheet. That loop is exactly the kind of tedious, context-heavy work an AI is good at — if you give it eyes and hands on the hardware. This server is those eyes and hands.
Related MCP server: mcp-serial-bridge
Tools
Tool | What it does |
| Discover available ports (COM5, /dev/ttyACM0, …). |
| Passively read what the firmware is printing for N seconds. |
| Send a line to the device's UART shell and capture the reply. |
| Turn a raw value (e.g. |
| Decode a register by name straight from a vendor CMSIS-SVD file. |
| Report which flashers are installed (st-flash / probe-rs / openocd). |
| Flash a firmware image to the board (dry-run by default). |
Install
git clone https://github.com/atillab1/embedded-mcp.git
cd embedded-mcp
pip install -e .Use with Claude Desktop
Add this to your claude_desktop_config.json:
{
"mcpServers": {
"embedded-mcp": {
"command": "embedded-mcp"
}
}
}Restart Claude Desktop. Then just ask:
"List my serial ports, then read whatever COM5 is printing at 115200 for 5 seconds."
"Send
statusto the board on COM5 and tell me what it replies."
"Register RCC->CR read back as 0x4002. Decode it: bit 0 is HSION, bit 17 is HSEON, bit 25 is PLLRDY."
Example: decode a register
decode_register(value=0x4002, fields=[{"name":"HSION","bit":0},{"name":"HSEON","bit":17}], width=32)
{
"value": 16386,
"hex": "0x00004002",
"binary": "00000000000000000100000000000010",
"fields": [
{ "name": "HSION", "bits": "[0]", "value": 0 },
{ "name": "HSEON", "bits": "[17]", "value": 0 }
]
}Try it now (no hardware needed)
The register decoders work entirely offline — give them a quick spin:
python examples/demo.pyFlashing
flash_firmware shells out to a real flasher and is dry-run by default — it
returns the exact command it would run, so you can review it before anything
touches your board:
"Dry-run flashing build/app.bin to my STM32 with st-flash."
Flip dry_run=False to actually flash. Supported: st-flash (.bin),
probe-rs (.elf, needs chip), openocd (.elf, needs openocd_target).
Safety notes
Tools open the port only for the duration of the call, then close it — they do not hold the port, so your normal IDE serial monitor can share it (one at a time).
Read durations are capped at 30s so a call can never hang the client.
flash_firmwareis destructive; it defaults to a dry run and never flashes unless you explicitly passdry_run=False.This talks to whatever board is on the port. Don't point it at something you don't own.
Roadmap
Unit tests + GitHub Actions CI
Load a register map from an SVD file (
decode_register_svd)Flashing hook (
flash_firmwarevia st-flash / probe-rs / openocd)Streaming/continuous monitor (notifications instead of fixed windows)
SVD auto-discovery from the connected chip id
Contributions welcome — open an issue or PR.
Development
pip install -e .
pip install pytest
pytest -qLicense
MIT © Atilla — see LICENSE.
Available Tools
7 toolsdecode_registerA
Decode a raw register value into its named bit-fields.
A constant pain in embedded work: you read a register as 0x4002 and have
to mentally line it up against the datasheet bit map. This does it for you.
Args: value: The raw register value (e.g. 0x4002). fields: A list of field descriptors. Each is either: {"name": "EN", "bit": 0} -> single bit {"name": "PRESC", "msb": 5, "lsb": 2} -> bit range [msb:lsb] width: Register width in bits (8, 16, 32...). Used only for display.
Returns the binary view plus each field's extracted value.
Inputs: value (required), fields (required), width. Returns: object
decode_register_svdA
Decode a register by name using a CMSIS-SVD chip description file.
Instead of typing out the bit map by hand (as decode_register needs), point
this at the vendor's .svd file and name the peripheral + register. It reads
the real bit-fields from the SVD and decodes your value against them.
Example: decode_register_svd(0x4002, "STM32F407.svd", "RCC", "CR")
Args: value: The raw register value you read back. svd_path: Path to a CMSIS-SVD file on this machine. peripheral: Peripheral name as in the SVD, e.g. "RCC". register: Register name as in the SVD, e.g. "CR". width: Register width in bits for display (default 32).
Inputs: value (required), register (required), svd_path (required), peripheral (required), +1 more. Returns: object
flash_firmwareA
Flash a firmware image onto the connected board.
DESTRUCTIVE: this overwrites the flash of whatever board is connected. For
safety it defaults to dry_run=True, which only returns the exact command
it would run without executing it. Set dry_run=False to actually flash.
Args: firmware_path: Path to the firmware (.bin for st-flash; .elf for probe-rs/openocd). tool: "auto" (pick the first installed) or "st-flash" / "probe-rs" / "openocd". address: Flash address for st-flash (default STM32 0x08000000). chip: Chip name for probe-rs, e.g. "STM32F407VG". openocd_target: OpenOCD target cfg, e.g. "target/stm32f4x.cfg". dry_run: If True (default), return the command instead of running it. timeout_seconds: Max time to wait when actually flashing (capped at 600s).
Inputs: firmware_path (required), chip, tool, address, +3 more. Returns: object
list_flashersA
Report which firmware-flashing tools are installed on this machine.
Call this before flash_firmware to see what's available
(st-flash, probe-rs, openocd).
Inputs: no named parameters. Returns: object
list_serial_portsA
List the serial ports currently available on this machine.
Use this first to find out which port your board is on (e.g. "COM5" on
Windows, "/dev/ttyACM0" on Linux). The other tools all take a port.
Returns one entry per port with its device name and a human description.
Inputs: no named parameters. Returns: result
read_serialA
Read whatever the device prints on port for seconds, then return it.
This opens the port, listens passively, and gives back everything it saw. Great for "what is my firmware logging right now?".
Args: port: Serial port name, e.g. "COM5" or "/dev/ttyACM0". baudrate: Bits per second. Must match your firmware (default 115200). seconds: How long to listen. Capped at 30s.
Inputs: port (required), seconds, baudrate. Returns: object
send_commandA
Send command to the device and capture its reply.
Writes the command (plus a line ending) to the port, then listens for the
response for reply_seconds. Use this to drive a firmware's command shell
(CLI over UART) — e.g. send "status" and read what comes back.
Args: port: Serial port name. command: The text to send (line ending added automatically). baudrate: Bits per second (default 115200). reply_seconds: How long to wait for the reply. Capped at 30s. line_ending: Appended to the command. "\n", "\r\n" or "" .
Inputs: port (required), command (required), baudrate, line_ending, +1 more. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
Each tool has a clearly distinct purpose. Register decoding splits into two tools for different input methods (manual vs SVD), but they are unambiguous in their usage. Other tools cover flashing, serial interaction, and listing, with no overlapping functionalities.
All tool names follow a consistent verb_noun pattern in lowercase snake_case (e.g., decode_register, list_flashers). No mix of styles or vague verbs, making the set predictable and easy to navigate.
With 7 tools, the server is well-scoped for embedded development workflows. It covers register decoding, firmware flashing, flasher detection, serial port listing, and serial communication without being overly numerous or sparse.
The tool set covers core embedded tasks (register decoding, flashing, serial interaction) but misses a few common operations like direct memory read/write or chip reset. These gaps are minor and the surface is largely complete for typical debugging.
Maintenance
Related MCP Connectors
Your org's AI agents, tasks, runs, search, and brain files as MCP tools and resources.
Connect ChatGPT and Claude to your Mac, Windows or Linux with secure MCP remote access.
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to communicate with UART/serial devices, offering tools for port management, data read/write, and protocol handling.MIT
- AlicenseAqualityDmaintenanceEnables AI agents to control serial port devices (modems, instruments, embedded boards) via MCP tools for listing ports, connecting, and sending/receiving commands.31MIT

sbl-probeofficial
AlicenseNot gradedqualityDmaintenanceSerial communication and protocol analysis MCP server that gives AI coding assistants direct access to serial ports for reading, writing, decoding, and capturing embedded device output.MIT- AlicenseAqualityCmaintenanceEnables AI agents to communicate with serial devices such as Arduinos, ESP32s, USB-UART adapters, and RS-232 instruments by discovering ports, opening connections, sending commands, reading responses, and controlling reset lines.121MIT