Keil5 MCP Server
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., "@Keil5 MCP Server Build the project and fix any compile errors it reports."
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.
Keil5 MCP Server
English | 中文
A Model Context Protocol (MCP) server that gives deepseek harness a edit code → flash → debug → read feedback → fix code closed loop for STM32 development with Keil MDK.
Instead of manually switching between the IDE, the programmer and the terminal, an agent can:
Build a Keil project and watch real-time compile progress
Get structured errors from UV4 logs (file / line / column / code / message)
Explain error codes with causes and suggested fixes
Edit source files safely (every edit is auto-backed up)
Flash firmware via the official UV4 channel or pyOCD
Debug on hardware through pyOCD: breakpoints, stepping, registers, memory, RTT logs
Run the official Keil debug channel (UV4
-d+.iniscripts)
Table of Contents
Related MCP server: mcp-stm32cubeide-server
Features
27 MCP tools registered as
mcp__<serverName>__<tool>(e.g.mcp__keil__build_project)Real-time build progress: tail-based monitor with percent / current file / phase, capped at 95% until link finishes
Structured UV4 log parsing: compile errors (
main.c(25:1): error C2065: ...), link errors (L6218E), Program Size, build timeError-code knowledge base: built-in explanations and fixes for common armcc/armclang codes (C2065, L6218E, L6406E, ...)
Safe source editing: automatic
.keil-mcp-backups/before every edit, line-range replace, regex searchOfficial flash path:
UV4 -fuses the project's configured Flash algorithm; pyOCD fallback accepts.axfdirectlyHardware debug: pyOCD probe control (connect / halt / resume / step / breakpoint / registers / memory / RTT)
Probe lease: per-probe exclusive access (asyncio lock + file lock) so UV4 and pyOCD never fight over the debug port
Execution boundary: read-only tools run concurrently; mutating tools serialize on a session lock; cancellation-safe via
asyncio.shieldWorks without Keil installed:
keil_doctorreports missing components clearly; the server still starts
Requirements
Component | Version / Notes |
Python | 3.10+ (tested on 3.12) |
Keil MDK |
|
pyOCD | installed automatically via pip; needs a probe driver (ST-Link / J-Link / CMSIS-DAP) |
Probe | ST-Link V2/V3, J-Link, CMSIS-DAP, Keil ULINKplus |
Target pack | e.g. |
Installation
From PyPI
python -m venv .venv
.venv/Scripts/activate # Windows
# source .venv/bin/activate # Linux / macOS
pip install keil-mcp-serverPackage is PyPI-ready (
pyproject.toml+LICENSE+server.jsonincluded). If the package is not yet published, use the source install below.
From source (GitHub)
git clone https://github.com/ZMC1011/dsh-keil-mcp.git
cd ds-keil-mcp
python -m venv .venv
.venv/Scripts/activate # Windows
# source .venv/bin/activate # Linux / macOS
pip install -e ".[dev]"Verify the install
# Environment self-check (UV4.exe, pyocd, connected probes)
python -m keil_mcp_server --check
# List all registered tools
python -m keil_mcp_server --tools
# Run the unit tests
pytest tests -qQuick Start
# 1. Start the MCP server (stdio transport — the MCP client will spawn this)
python -m keil_mcp_server
# 2. In your MCP client, call e.g.:
# keil_doctor
# discover_keil_projects { directory: "D:/STM32Projects" }
# configure_keil_project { project: "D:/STM32Projects/app/app.uvprojx" }
# build_project { project: "...", target: "Target 1", stream_progress: true }
# flash_firmware { project: "...", confirm: true }MCP Client Configuration
DeepSeek Harness (DSH)
Per the official DSH MCP docs: one plugin instance = one MCP server, wired through the official bridge plugin @deepseek-ai/dsh-mcp-client. Add this to your profile's cordis.patch.yml (or cordis.yml):
- insert:
- id: mcp-keil
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: keil # tools appear as mcp__keil__build_project etc.
transport: stdio
command: D:/000_Environment/mcp-servers/ds-keil-mcp/.venv/Scripts/python.exe
args: ['-m', 'keil_mcp_server']
env:
KEIL_UV4_PATH: D:/002_software/Keil5/UV4/UV4.exe
KEIL_PROJECT_DIR: D:/STM32Projects
# optional: toolCallTimeoutMs: 60000, failOnStartupError: falseVerify with:
dsh web --dump-config | grep -A3 mcp
# or check session logs for mcp__keil__* callsNote: serverName must match
[A-Za-z0-9_-]{1,32}and be unique among live instances.
Claude Desktop / other stdio MCP clients
Most MCP clients use the mcpServers JSON convention:
{
"mcpServers": {
"keil": {
"command": "D:/000_Environment/mcp-servers/ds-keil-mcp/.venv/Scripts/python.exe",
"args": ["-m", "keil_mcp_server"],
"env": {
"KEIL_UV4_PATH": "D:/002_software/Keil5/UV4/UV4.exe",
"KEIL_PROJECT_DIR": "D:/STM32Projects"
}
}
}
}For a source checkout without a venv, uv also works:
{
"mcpServers": {
"keil": {
"command": "uv",
"args": ["--directory", "D:/path/to/ds-keil-mcp", "run", "keil_mcp_server"]
}
}
}Tools
All 27 tools return structured JSON. Destructive operations (flash / erase) require confirm=True.
Build & Errors
Tool | Description | Key params → Result |
| Compile with UV4 |
|
| Query in-flight build progress |
|
| Request build cancellation |
|
| Parse UV4 log into structured errors |
|
| Error code → explanation + causes + fixes |
|
Source Editing
Tool | Description | Key params → Result |
| Read source with line numbers |
|
| Replace a line range; auto-backup first |
|
| Search source files (text or regex) |
|
Official Debug Channel
Tool | Description | Key params → Result |
| Run UV4 |
|
| Read session output by id |
|
Project & Environment
Tool | Description | Key params → Result |
| Environment check: UV4.exe, pyocd, packs, connected probes | — → |
| Find |
|
| Parse project: targets, device, pack, groups, source files |
|
Flash
Tool | Description | Key params → Result |
| Flash via UV4 |
|
| Erase chip flash (pyOCD |
|
| Verify chip against image (pyOCD |
|
Probe Debugging
Tool | Description |
| Connect / release a pyOCD probe (disconnect frees the port for UV4 |
| Core control |
| Breakpoint by symbol or address, continue |
| Read r0-r15, sp, lr, pc, xpsr |
| Read memory at address (hex bytes) |
| Read SEGGER RTT output (if running) |
Architecture
┌──────────────────────────────────────────────────────────────┐
│ MCP Client (DeepSeek Harness / Claude Desktop / ...) │
│ → tools registered as mcp__keil__* │
└──────────────────────────────┬───────────────────────────────┘
│ stdio (JSON-RPC 2.0)
┌──────────────────────────────▼───────────────────────────────┐
│ keil-mcp-server (Python, FastMCP) │
│ │
│ server.py — tool registration + Execution Boundary │
│ (read-only whitelist → concurrent; │
│ mutating tools → session lock + │
│ asyncio.to_thread + asyncio.shield) │
│ │
│ tools/ — MCP tool layer (27 tools) │
│ │
│ core/ — deliverable layer │
│ uv4_runner.py UV4 -b/-r/-c/-f/-d process runner │
│ build_progress.py realtime log tail monitor │
│ error_parser.py UV4 log → structured errors + KB │
│ source_editor.py read/edit/search + auto-backup │
│ uv4_debug.py UV4 -d + .ini script engine │
│ probe_lease.py per-probe exclusive lease │
│ project_utils.py .uvprojx parser (namespace-tolerant) │
│ │
│ models.py / config.py / config.yaml │
└───────────────┬──────────────────────────────┬───────────────┘
│ │
┌─────────▼─────────┐ ┌─────────▼─────────┐
│ Keil MDK (UV4.exe)│ │ pyOCD + probe │
│ build/flash/debug │ │ ST-Link/J-Link/ │
│ │ │ CMSIS-DAP → chip │
└───────────────────┘ └───────────────────┘Dependency direction: MCP layer → tools → core → Keil MDK / pyOCD → target chip.
Key design points:
Execution boundary (inspired by McuBuddy): read-only tools run concurrently; everything else serializes on a per-session
asyncio.Lock, runs in a worker thread (asyncio.to_thread) and is cancellation-protected (asyncio.shield).Probe lease: UV4
-fand pyOCD cannot share the debug port.ProbeLease(asyncio lock +filelock) serializes access; the flash flow disconnects pyOCD before UV4 takes over.Realtime progress: a daemon thread tails the UV4 log, counting
compilinglines against the source-file count parsed from.uvprojx(percent capped at 95% until theBuild Time Elapsedmarker).Malformed-XML tolerance: older Keil projects contain mismatched tags (e.g.
<b498tele498>...</bUseTDR>); the project parser repairs them before parsing.
Configuration
config.yaml (bundled) + environment variable overrides:
keil:
uv4_path: "C:/Keil_v5/UV4/UV4.exe" # or env KEIL_UV4_PATH
default_project_dir: "" # or env KEIL_PROJECT_DIR
build:
build_timeout: 300
stream_progress: true
tail_flush_wait: 3 # seconds to wait for UV4 log tail flush after exit
error:
max_errors: 200
source:
backup_dir: ".keil-mcp-backups"
probe_lease:
lock_dir: ".keil-mcp-locks"
server:
transport: "stdio"
log_level: "INFO"End-to-End Workflow Example
A typical agent session (tool names shown with DSH prefix mcp__keil__):
1. mcp__keil__keil_doctor # environment + probe OK?
2. mcp__keil__discover_keil_projects # find .uvprojx files
3. mcp__keil__configure_keil_project # parse targets/device/sources
4. mcp__keil__build_project (stream_progress) # compile; on failure:
5. mcp__keil__parse_build_errors # structured errors[]
6. mcp__keil__explain_build_error # causes + fixes
7. mcp__keil__source_edit # fix code (auto-backup)
→ back to 4 until 0 errors
8. mcp__keil__flash_firmware (confirm=true) # UV4 -f → "Verify OK"
9. mcp__keil__probe_connect + set_breakpoint # attach debugger
10. mcp__keil__probe_read_registers / _memory # observe chip state
11. mcp__keil__read_rtt_log # firmware logs
→ if logic bug found: source_edit → rebuild → reflashSafety Rules
Level | Operations | Default |
Read-only | chip match, register/memory/symbol reads, logs | no confirmation |
Execute | halt / resume / step / reset | prompt |
State write | memory/register writes, breakpoints, watchpoints | confirm |
Persistent destructive | flash erase / programming | explicit confirm + recovery plan |
Host process | Keil build, GDB server | prompt |
Principles: gather evidence before acting; identify the target chip first; confirm target / range / image / recovery before flashing.
Testing
pytest tests -q # 11 unit tests: log parsing, source editing, progress, project parsingManual smoke tests (in tests/):
python tests/raw_handshake.py # bare JSON-RPC initialize + tools/list over stdio
python tests/func_test.py # end-to-end tool calls through the MCP client SDKTroubleshooting
Symptom | Cause / Fix |
| pyOCD still owns the probe. Call |
| Set |
| The venv's editable install points at an old path — reinstall from the current checkout: |
| Check probe wiring / driver; |
| e.g. |
Roadmap
Publish to PyPI and register in the MCP registry
MCUBUDDY_TOOLSETS-style domain toggles
ELF symbol resolution for
set_breakpointby nameRTOS task awareness (FreeRTOS)
GitHub Actions CI for unit tests
Linux/macOS support notes (Keil is Windows-only; pyOCD parts are cross-platform)
Contributing
Contributions are welcome! Please open an issue first to discuss changes, then submit a PR.
License
MIT — free to use, modify and distribute with attribution.
Available Tools
27 toolsbuild_cancelC
Request cancellation of a running build.
Inputs: build_id (required).
build_progress_statusB
Query the live progress of a running build.
Inputs: build_id (required).
build_projectA
Build a Keil project with UV4 -b (or -r rebuild / -c clean).
Args: project: path to .uvprojx (absolute or relative to default_project_dir) target: target name (default: first target in project) timeout_seconds: build timeout (default 120) stream_progress: tail the log for realtime progress (percent/phase) clean: run UV4 -c instead of -b rebuild: run UV4 -r (full rebuild) instead of -b Returns: {status: ok|error|canceled|not_found, returncode, build_log, errors[], summary, progress?}
Inputs: project (required), clean, target, rebuild, +2 more.
configure_keil_projectA
Parse a Keil project: targets, device, pack, groups, source files.
Use before building to pick the right target / confirm the device.
Inputs: project (required), target.
continue_targetB
Continue the target until the next breakpoint.
Inputs: probe_id.
discover_keil_projectsB
Discover *.uvprojx Keil projects under a directory.
Inputs: directory, recursive.
erase_flashA
Erase the target chip flash (pyocd erase -c). Requires confirm=True.
Inputs: chip, confirm, probe_id, timeout_seconds.
explain_build_errorB
Map a Keil/armclang error code to explanation, causes and fixes.
Inputs: error_code (required), file, line, message.
flash_firmwareA
Flash firmware to the target chip.
Preferred path: UV4 -f (Keil official flash download, uses the project's configured Flash algorithm). Fallback: pyocd load . Requires confirm=True (persistent destructive operation).
Args: project: .uvprojx path (for UV4 -f) — required unless image is given target: target name for UV4 -f image: firmware image (axf/hex/bin) for the pyocd path backend: "uv4" | "pyocd" | "auto" probe_id: pyOCD probe unique id (optional) confirm: MUST be True to actually flash
Inputs: project (required), image, target, backend, +3 more.
keil_doctorB
Check the Keil environment: UV4.exe, pyocd, packs, config.
Inputs: no named parameters.
keil_versionA
Return the keil5-mcp server version and available tool count.
Inputs: no named parameters.
parse_build_errorsA
Parse a UV4 build log into structured errors/warnings (blueprint §7.2).
Args: log_path: path to build log file, OR log_content: raw log text Returns: {errors[], warnings[], summary{success, errors, warnings, code_size, ...}}
Inputs: log_path, log_content.
probe_connectC
Connect to a debug probe via pyOCD (auto-detect or by unique id).
Inputs: chip, probe_id.
probe_disconnectA
Disconnect the probe (releases it for UV4 -f flash path).
Inputs: probe_id.
probe_haltC
Halt the target.
Inputs: probe_id.
probe_read_memoryC
Read memory at address (bytes).
Inputs: address (required), length, probe_id.
probe_read_registersB
Read core registers (r0-r15, xpsr, sp, lr, pc).
Inputs: probe_id.
probe_resumeC
Resume the target.
Inputs: probe_id.
probe_stepC
Single-step the target.
Inputs: probe_id.
read_rtt_logA
Read recent SEGGER RTT log output from the target (if RTT is running).
Inputs: probe_id, timeout_seconds.
set_breakpointC
Set a hardware breakpoint by symbol name or address.
Inputs: symbol, address, probe_id.
source_editA
Edit a source file; original is automatically backed up to .keil-mcp-backups/.
Args: file: path to source file start_line / end_line: 1-based inclusive line range to replace new_content: replacement text (can be multi-line)
Inputs: file (required), end_line (required), start_line (required), new_content (required).
source_readA
Read a source file with line numbers (auto backup not needed; read-only).
Inputs: file (required), end_line, start_line.
source_searchA
Search source files in the project directory.
Args: pattern: text or regex pattern path: directory to search (default: default_project_dir or cwd) files: optional explicit file list (relative to path) regex: treat pattern as a regular expression
Inputs: pattern (required), path, files, regex, +2 more.
uv4_debug_ddeC
Read the output of a UV4 -d debug session (session output channel).
Inputs: session_id (required).
uv4_debug_sessionA
Run an official Keil debug session via UV4 -d + a generated .ini script.
The debugger runs headless: sets a breakpoint, resets, runs, optionally steps, and prints variable values. Output is captured from the session log.
Args: project: path to .uvprojx target: target name (default first target) ini_path: custom .ini script path (overrides generated script) reset: reset target before running breakpoint: symbol/line to break at ("" = none) steps: extra single-step count after hitting the breakpoint dump_vars: variable names to print (e.g. ["i", "adc_value"]) timeout_seconds: session timeout
Inputs: project (required), reset, steps, target, +4 more.
verify_flashB
Verify firmware on chip against an image (pyocd verify).
Inputs: image (required), probe_id, timeout_seconds.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 27 tools
Most tools target clearly distinct operations (build, source, flash, probe control), and the descriptions help separate them. Minor ambiguity exists between 'probe_resume' and 'continue_target' and between 'parse_build_errors' and 'explain_build_error', but these are usable with the provided docs.
The majority follow a verb_noun pattern like 'build_project', 'source_edit', and 'probe_halt', but there are notable deviations such as 'uv4_debug_dde', 'keil_doctor', and 'build_progress_status'. Names are generally readable but the mixed styles prevent a higher score.
With 27 tools, the server exceeds the 25+ threshold where tool count becomes heavy for an agent to navigate. The tools cover many subdomains, but several low-level probe primitives and debug-session helpers could be consolidated or omitted.
The server covers build, source editing, flashing, and basic debugging well. However, obvious lifecycle gaps exist: breakpoints can be set but not listed/deleted, memory/registers are read-only, and there is no standalone reset target operation or project creation/configuration update capability.
Maintenance
Related MCP Connectors
Design circuits, simulate and verify embedded firmware, and lay out PCBs with AI agents.
Run, build, and validate firmware on virtual hardware from your AI agent. Hardware knowledge corpus.
Adaptive plan/build/review cycles for AI coding assistants, persisted across sessions.
Debug, build, and manage Power Automate cloud flows with AI agents
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI assistants to flash firmware, program memory, modify option bytes, erase chips, reset boards, and capture SWO printf traces for STM32 microcontrollers via STM32CubeCLT.12MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that lets AI coding agents drive the full STM32 development loop—code generation, build, flash, debug, serial monitoring, and fault diagnosis—end to end via CubeIDE, CubeMX, CubeProgrammer, OpenOCD, and GDB.1MIT
- AlicenseAqualityBmaintenanceEnables AI coding assistants to perform complete headless STM32 embedded firmware development, including project creation, pin configuration, code generation, building, and flashing, by driving the official STM32 command-line toolchain.49MIT
- AlicenseCqualityCmaintenanceEnables AI agents to build, flash, and debug STM32 projects compiled with Keil MDK-ARM on Windows, returning structured UV4 build diagnostics and evidence-based results. It also provides pyOCD/ST-Link debugging operations such as run control, breakpoints, register/PC reads, and global/static variable inspection.29MIT