AI-ready MCP server for cross-vendor embedded bring-up, flashing, diagnostics, and UART capture.
embedded-mcp
MCP server that gives AI agents (GitHub Copilot, Claude Desktop, Cursor, etc.) direct tool access to TI CC26xx and Nordic nRF52/nRF91 embedded hardware.
TI devices are controlled via XDS110 + dslite. Nordic devices are controlled via nrfjprog.
The agent can detect devices, erase flash, program firmware, reset targets, read TI memory/MAC addresses, and capture UART logs — without touching the terminal.
Supported hardware:
- TI: CC2652R7 (and wider CC26xx/CC13xx via
.ccxml) - Nordic: nRF52 and nRF91 (detect/reset/erase/program)
Prerequisites
| Requirement | Notes |
| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ |
| TI UniFlash 8.5.0 | Provides dslite.bat. Install to C:\TI\uniflash_8.5.0\. |
| nRF Command Line Tools | Provides nrfjprog.exe (must be in PATH or set via NRFJPROG_PATH). |
| TI XDS110 debug probe | Any TI LaunchPad includes one. |
| .ccxml target config | Generated by TI UniFlash for your device. A ready-made cc2652r7.ccxml is included. |
| uv | Python package manager. winget install astral-sh.uv or pip install uv. |
| Python 3.10+ | Managed automatically by uv. |
Setup
Option A — From GitHub (no PyPI publish needed)
Add to your mcp.json (VS Code: .vscode/mcp.json, Claude Desktop: claude_desktop_config.json):
{
"servers": {
"embedded-mcp": {
"type": "stdio",
"command": "uvx",
"args": [
"--from",
"git+https://github.com/Umer-Mahmood/embedded-mcp",
"embedded-mcp"
],
"env": {
"DSLITE_PATH": "C:\\TI\\uniflash_8.5.0\\dslite.bat",
"CCXML_PATH": "C:\\path\\to\\cc2652r7.ccxml",
"NRFJPROG_PATH": "nrfjprog.exe"
}
}
}
}
uvx fetches and caches the package automatically on first use. No manual install needed.
Option B — From PyPI (once published)
{
"servers": {
"embedded-mcp": {
"type": "stdio",
"command": "uvx",
"args": ["embedded-mcp"],
"env": {
"DSLITE_PATH": "C:\\TI\\uniflash_8.5.0\\dslite.bat",
"CCXML_PATH": "C:\\path\\to\\cc2652r7.ccxml",
"NRFJPROG_PATH": "nrfjprog.exe"
}
}
}
}
Option C — Local repo (for development)
{
"servers": {
"embedded-mcp": {
"type": "stdio",
"command": "uv",
"args": [
"--directory",
"C:\\path\\to\\embedded-mcp",
"run",
"embedded-mcp"
],
"env": {
"DSLITE_PATH": "C:\\TI\\uniflash_8.5.0\\dslite.bat",
"CCXML_PATH": "C:\\path\\to\\cc2652r7.ccxml",
"NRFJPROG_PATH": "nrfjprog.exe"
}
}
}
}
Environment Variables
| Variable | Required | Default | Description |
| ------------------- | -------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------- |
| DSLITE_PATH | Yes | TI default install path | Full path to dslite.bat |
| CCXML_PATH | Yes | cc2652r7.ccxml in CWD | Target configuration file for your device |
| NRFJPROG_PATH | No | nrfjprog.exe | Path or command name for nrfjprog |
| DEFAULT_UART_PORT | No | (unset) | Default COM port for uart_read/uart_write. If unset, pass port explicitly or call list_serial_ports first. |
| DEFAULT_UART_BAUD | No | 115200 | Default UART baud rate |
For Nordic tools, pass snr only when multiple J-Link probes are connected. With a single connected probe, omit snr and auto-selection is used.
Tools
| Tool | Description |
| ------------------- | ----------------------------------------------------------------------------- |
| get_config | Show active TI/Nordic paths and defaults |
| detect_device | Detect target=CC26XX \| NRF52 \| NRF91 (optional snr for Nordic) |
| mass_erase | Erase selected target (TI mass erase or Nordic --eraseall) |
| flash_binary | Program selected target. Nordic uses --program --chiperase --verify --reset |
| verify_binary | Verify device flash matches a firmware file (TI only) |
| reset_device | Reset selected target (TI board reset or Nordic --reset) |
| read_memory | Read bytes from any address, returns hex dump |
| read_ble_mac | Read primary BLE MAC from FCFG1 (non-destructive) |
| read_ieee_mac | Read primary IEEE 802.15.4 MAC from FCFG1 (non-destructive) |
| list_serial_ports | List all available COM ports with descriptions |
| uart_read | Capture serial output for N seconds |
| uart_write | Send string over serial, return response |
TI-only tools: verify_binary, read_memory, read_ble_mac, read_ieee_mac, uart_read, uart_write.
CC2652R7 Memory Map
| Region | Address | Notes |
| -------------------- | ----------------- | ---------------------------------------------- |
| Application firmware | 0x00000000 | Main flash start |
| CCFG (device config) | 0x57FA8–0x57FFF | Protection flags, bootloader config |
| FCFG1 (factory cal.) | 0x50001000 | Read-only factory calibration, always readable |
| BLE MAC address | 0x500012E8 | 6 bytes, little-endian (reverse for display) |
| IEEE 802.15.4 MAC | 0x500012F0 | 8 bytes, little-endian (reverse for display) |
Test with MCP Inspector
npx @modelcontextprotocol/inspector uvx --from . embedded-mcp
Example Copilot session
"Is the device connected? If yes, erase it, flash firmware.bin to 0x0, then reset and show me boot logs."
Copilot will chain detect_device → mass_erase → flash_binary → reset_device → uart_read autonomously.
⚠️ Warnings
mass_eraseerases all user flash. Confirm before calling on a production device.- Some devices include a bootloader that, once flashed, permanently disables JTAG. Mass erase is the only recovery path in that case (if the bootloader permits it).
- The CCFG region at
0x57FA8controls device protection flags. Writing incorrect values here can brick the device.