Install
$ agentstack add mcp-atillab1-embedded-mcp ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
embedded-mcp
> Let an AI assistant read, command, and debug your microcontroller — over plain serial.
[](https://github.com/atillab1/embedded-mcp/actions/workflows/ci.yml) [](LICENSE) [](https://www.python.org/) [](https://modelcontextprotocol.io/)
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.
Tools
| Tool | What it does | | --- | --- | | list_serial_ports | Discover available ports (COM5, /dev/ttyACM0, …). | | read_serial | Passively read what the firmware is printing for N seconds. | | send_command | Send a line to the device's UART shell and capture the reply. | | decode_register | Turn a raw value (e.g. 0x4002) into named bit-fields. | | decode_register_svd | Decode a register by name straight from a vendor CMSIS-SVD file. | | list_flashers | Report which flashers are installed (st-flash / probe-rs / openocd). | | flash_firmware | 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 status to 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.py
Flashing
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 pass dry_run=False.
- This talks to whatever board is on the port. Don't point it at something you
don't own.
Roadmap
- [x] Unit tests + GitHub Actions CI
- [x] Load a register map from an SVD file (
decode_register_svd) - [x] 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 -q
License
MIT © Atilla — see [LICENSE](LICENSE).
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: atillab1
- Source: atillab1/embedded-mcp
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.