JLink MCP Server
Click on "Install 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., "@JLink MCP ServerConnect to STM32F407VG via SWD"
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.
JLink MCP Server
A powerful Model Context Protocol (MCP) server for J-Link debuggers
J-Link调试器的强大模型上下文协议(MCP)服务器
English Documentation
🚀 Overview
JLink MCP Server is a comprehensive debugging tool that integrates J-Link debugger capabilities with AI assistants through the Model Context Protocol. It provides seamless access to hardware debugging features including memory operations, flash programming, register access, and real-time data transfer.
✨ Key Features
Feature | Description |
🔌 Device Connection | Connect via SWD/JTAG with auto-detect support ( |
🔍 Smart Chip Matching | Intelligent chip name matching (e.g., |
💾 Memory Operations | Read/write memory with configurable access widths (8/16/32-bit) |
🔥 Flash Programming | Program, erase, and verify flash memory |
🎯 Debug Control | Halt, run, single-step execution with breakpoints |
📊 Register Access | Read/write CPU registers with SVD field parsing |
📡 RTT Support | Real-time data transfer via Segger RTT |
🔧 SVD Integration | Access peripheral registers via SVD files with pickle cache |
🧩 Plugin Architecture | Extensible device-specific patch system |
🌐 GDB Server | Integrated GDB server support |
📚 Usage Guidance | Built-in help tools for best practices and scenarios |
📋 Prerequisites
Python: 3.8 or higher
J-Link Software: Latest version from Segger
J-Link Hardware: Any supported J-Link debugger
Operating System: Windows, Linux, or macOS
🛠️ Installation
Method 1: Install from PyPI
pip install jlink-mcpMethod 2: Install from Source
# Clone the repository
git clone https://github.com/cyj0920/jlink_mcp.git
cd jlink_mcp
# Install in development mode
pip install -e .Method 3: Install with UV (Recommended for better performance)
# Install UV
pip install uv
# Install with UV
uv pip install jlink-mcp⚙️ Configuration
Environment Variables
Create a .env file or set environment variables:
# Optional: External SVD directory for peripheral register definitions
JLINK_SVD_DIR=/path/to/svd/files
# Optional: External device patch directory for vendor-specific support
JLINK_PATCH_DIR=/path/to/patches
# Optional: Default interface type (SWD or JTAG)
JLINK_DEFAULT_INTERFACE=JTAGMCP Configuration
Add to your MCP configuration file (typically ~/.config/mcp/settings.json or C:\Users\<username>\.iflow\settings.json):
{
"mcpServers": {
"jlink": {
"command": "python",
"args": ["-m", "jlink_mcp"],
"env": {
"JLINK_SVD_DIR": "C:\\path\\to\\svd\\files",
"JLINK_PATCH_DIR": "C:\\path\\to\\patches",
"JLINK_DEFAULT_INTERFACE": "JTAG"
}
}
}
}📖 Usage Guide
Connecting to Devices
# Automatic chip detection (recommended)
# Both chip_name=None and chip_name="auto" trigger the same autodetect flow
connect_device(chip_name="auto", interface="JTAG")
connect_device(chip_name=None, interface="JTAG")
# Connect with specific chip name
connect_device(chip_name="STM32F407VG", interface="SWD")
# Connect with specific J-Link serial number
connect_device(
chip_name="STM32F407VG",
interface="JTAG",
serial_number="12345678"
)Memory Operations
# Read 64 bytes from address 0x20000000 (32-bit access)
read_memory(address=0x20000000, size=64, width=32)
# Write a 32-bit value to memory
write_memory(address=0x20000000, data="0x12345678", width=32)
# Read a single byte
read_memory(address=0x20000000, size=1, width=8)
# Write 16-bit value
write_memory(address=0x20000000, data="0xABCD", width=16)Flash Programming
# Erase a range of flash memory
erase_flash(
start_address=0x08000000,
end_address=0x08020000
)
# Erase entire chip
erase_flash(chip_erase=True)
# Program flash with verification
program_flash(
address=0x08000000,
data="binary_hex_data",
verify=True
)
# Verify flash content
verify_flash(
address=0x08000000,
data="expected_data"
)Debug Control
# Halt the CPU
halt_cpu()
# Resume execution from a halted CPU without resetting the target
run_cpu()
# Single step execution
step_instruction()
# Get current CPU state
get_cpu_state()
# Reset the device
reset_target(reset_type="normal")
# Reset and halt
reset_target(reset_type="halt")Register Access
# Read all general-purpose registers
read_registers()
# Read specific registers
read_registers(register_names=["R0", "R1", "PC"])
# Write to a register
write_register(register_name="R0", value=0x12345678)
# Read with custom list
read_registers(["R0", "SP", "LR", "PC"])SVD Register Access
# List available SVD files
list_svd_devices()
# Get peripherals for a device
get_svd_peripherals(device_name="STM32F407VG")
# Get registers for a peripheral
get_svd_registers(
device_name="STM32F407VG",
peripheral_name="GPIOA"
)
# Read register with field parsing
result = read_register_with_fields(
device_name="STM32F407VG",
peripheral_name="GPIOA",
register_name="MODER"
)
print(f"Raw value: {result['value']}")
print(f"Fields: {result['fields']}")Breakpoints and Debugging
# Set a breakpoint
set_breakpoint(address=0x08000100)
# Clear a breakpoint
clear_breakpoint(address=0x08000100)RTT (Real-Time Transfer)
# Start RTT with buffer index 0
rtt_start(buffer_index=0)
# Read RTT data
data = rtt_read(buffer_index=0, size=1024)
print(data)
# Write data to RTT
rtt_write(data="test_message", buffer_index=0)
# Stop RTT
rtt_stop()
# Get RTT status
status = rtt_get_status()🏗️ Architecture
The server follows a modular, plugin-based architecture:
┌─────────────────────────────────────────────────┐
│ JLink MCP Server │
├─────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌────────────────────┐ │
│ │ Server │ │ Tool Layer │ │
│ │ Manager │ │ │ │
│ └──────┬───────┘ │ • Connection │ │
│ │ │ • Debug │ │
│ │ │ • Memory │ │
│ │ │ • Flash │ │
│ │ │ • Registers │ │
│ │ │ • SVD │ │
│ │ │ • RTT │ │
│ │ └────────────────────┘ │
│ │ │
│ ┌──────▼────────────────────────────────┐ │
│ │ Manager Layer │ │
│ ├────────────┬────────────┬─────────────┤ │
│ │ JLink │ SVD │ Patch │ │
│ │ Manager │ Manager │ Manager │ │
│ └────────────┴────────────┴─────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ Plugin Layer │ │
│ │ • DevicePatchInterface │ │
│ │ • Vendor-specific patches │ │
│ └──────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ Hardware Layer │ │
│ │ • pylink-square │ │
│ │ • J-Link SDK │ │
│ └──────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘🧩 Plugin System
The server supports a flexible plugin architecture for device-specific functionality:
Creating a Custom Patch
from typing import Optional, List, Dict, Any
from jlink_mcp.device_patch_interface import DevicePatchInterface
class CustomDevicePatch(DevicePatchInterface):
"""Custom device patch implementation."""
@property
def vendor_name(self) -> str:
"""Return the vendor name."""
return "CustomVendor"
@property
def patch_version(self) -> str:
"""Return the patch version."""
return "v1.0.0"
def is_available(self) -> bool:
"""Check if the patch is available."""
return True
def match_device_name(self, chip_name: str) -> Optional[str]:
"""
Match and return the full device name.
Args:
chip_name: Partial or simplified device name
Returns:
Full device name or None if no match
"""
# Implement your matching logic
device_map = {
"CUSTOM": "CustomDevice1",
"CUST1": "CustomDevice1",
}
return device_map.get(chip_name.upper())
@property
def device_names(self) -> List[str]:
"""Return list of supported devices."""
return ["CustomDevice1", "CustomDevice2"]
def get_device_info(self, device_name: str) -> Optional[Dict[str, Any]]:
"""
Get detailed information about a device.
Args:
device_name: Full device name
Returns:
Device information dictionary
"""
return {
"name": device_name,
"vendor": self.vendor_name,
"core": "ARM Cortex-M4",
"flash_size": 512 * 1024,
"ram_size": 128 * 1024,
}Registering a Custom Patch
from jlink_mcp.device_patch_manager import device_patch_manager
# Create and register your custom patch
custom_patch = CustomDevicePatch()
device_patch_manager.register_patch(custom_patch)📚 API Reference
The server provides 41 MCP tools across 9 categories:
Connection API (5 tools)
Function | Parameters | Description |
| - | List connected J-Link devices |
|
| Connect to J-Link device |
| - | Disconnect from current device |
| - | Get connection status |
|
| Smart chip name matching |
Device Info API (4 tools)
Function | Parameters | Description |
| - | Get target device information |
| - | Get target voltage |
| - | Scan for devices on the bus |
| - | List loaded device patches |
Memory API (4 tools)
Function | Parameters | Description |
|
| Read memory (max 64KB) |
|
| Write memory |
|
| Read CPU registers |
|
| Write single register |
Flash API (3 tools)
Function | Parameters | Description |
|
| Erase flash |
|
| Program flash |
|
| Verify flash |
Debug API (7 tools)
Function | Parameters | Description |
|
| Reset target (normal/halt/core) |
| - | Halt CPU |
| - | Resume CPU execution without resetting the target |
| - | Single step execution |
| - | Get CPU state |
|
| Set breakpoint |
|
| Clear breakpoint |
RTT API (5 tools)
Function | Parameters | Description |
|
| Start RTT |
| - | Stop RTT |
|
| Read RTT data |
|
| Write RTT data |
| - | Get RTT status |
GDB Server API (3 tools)
Function | Parameters | Description |
|
| Start GDB server |
| - | Stop GDB server |
| - | Get GDB server status |
SVD API (5 tools)
Function | Parameters | Description |
| - | List available SVD devices |
|
| Get device peripherals |
|
| Get peripheral registers |
|
| Read register with field parsing |
|
| Parse register value only |
Guidance API (5 tools)
Function | Parameters | Description |
|
| Get tool usage guide |
|
| Get best practices |
| - | List usage scenarios |
| - | Get forbidden operations |
|
| Get system/custom prompt |
🐛 Troubleshooting
Common Issues
Problem: Cannot connect to J-Link device
Solutions:
Check if J-Link is properly connected via USB
Verify J-Link software is installed
Try running JLinkExe to verify device detection
Check interface type (SWD vs JTAG)
Verify target device is powered
# Test J-Link connection
JLinkExe -device STM32F407VG -if JTAG -speed 4000Problem: Memory read/write fails
Solutions:
Verify target is halted before memory access
Check memory address is valid and accessible
Ensure correct access width for target memory region
Verify target is powered and not in low-power mode
Problem: Flash programming fails
Solutions:
Erase flash before programming
Verify target device is not write-protected
Check flash algorithm matches target device
Ensure sufficient power supply during programming
🤝 Contributing
Contributions are welcome! Please follow these guidelines:
Fork the repository
Create a feature branch (
git checkout -b feature/AmazingFeature)Commit your changes (
git commit -m 'Add some AmazingFeature')Push to the branch (
git push origin feature/AmazingFeature)Open a Pull Request
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
Segger for J-Link hardware and software
pylink-square for the Python J-Link library
Model Context Protocol for the MCP specification
Related MCP server: gdb_mcp
中文文档
🚀 概述
JLink MCP Server 是一个功能强大的调试工具,通过模型上下文协议将J-Link调试器功能与AI助手集成。它提供无缝的硬件调试功能访问,包括内存操作、Flash编程、寄存器访问和实时数据传输。
✨ 核心特性
特性 | 描述 |
🔌 设备连接 | 通过SWD/JTAG连接,支持自动检测( |
🔍 智能芯片匹配 | 智能芯片名称匹配(如 |
💾 内存操作 | 支持可配置访问宽度(8/16/32位)的内存读写 |
🔥 Flash编程 | 程序烧录、擦除和验证 |
🎯 调试控制 | 暂停、运行、单步执行及断点设置 |
📊 寄存器访问 | 读写CPU寄存器,支持SVD字段解析 |
📡 RTT支持 | 通过Segger RTT进行实时数据传输 |
🔧 SVD集成 | 通过SVD文件访问外设寄存器,支持Pickle缓存 |
🧩 插件架构 | 可扩展的设备特定补丁系统 |
🌐 GDB服务器 | 集成GDB服务器支持 |
📚 使用指南 | 内置帮助工具,提供最佳实践和使用场景 |
📋 前置要求
Python: 3.8 或更高版本
J-Link软件: 从 Segger 获取最新版本
J-Link硬件: 任何支持的J-Link调试器
操作系统: Windows、Linux 或 macOS
🛠️ 安装
方法1:从PyPI安装
pip install jlink-mcp方法2:从源码安装
# 克隆仓库
git clone https://github.com/cyj0920/jlink_mcp.git
cd jlink_mcp
# 开发模式安装
pip install -e .方法3:使用UV安装(推荐,性能更好)
# 安装UV
pip install uv
# 使用UV安装
uv pip install jlink-mcp⚙️ 配置
环境变量
创建 .env 文件或设置环境变量:
# 可选:外部SVD目录,用于外设寄存器定义
JLINK_SVD_DIR=/path/to/svd/files
# 可选:外部设备补丁目录,用于厂商特定支持
JLINK_PATCH_DIR=/path/to/patches
# 可选:默认接口类型(SWD或JTAG)
JLINK_DEFAULT_INTERFACE=JTAGMCP配置
添加到你的MCP配置文件(通常在 ~/.config/mcp/settings.json 或 C:\Users\<用户名>\.iflow\settings.json):
{
"mcpServers": {
"jlink": {
"command": "python",
"args": ["-m", "jlink_mcp"],
"env": {
"JLINK_SVD_DIR": "C:\\path\\to\\svd\\files",
"JLINK_PATCH_DIR": "C:\\path\\to\\patches",
"JLINK_DEFAULT_INTERFACE": "JTAG"
}
}
}
}📖 使用指南
连接设备
# 自动芯片检测(推荐)
# chip_name=None 和 chip_name="auto" 都会触发同一套自动检测流程
connect_device(chip_name="auto", interface="JTAG")
connect_device(chip_name=None, interface="JTAG")
# 指定芯片名称连接
connect_device(chip_name="STM32F407VG", interface="SWD")
# 使用特定J-Link序列号连接
connect_device(
chip_name="STM32F407VG",
interface="JTAG",
serial_number="12345678"
)内存操作
# 从地址0x20000000读取64字节(32位访问)
read_memory(address=0x20000000, size=64, width=32)
# 向内存写入32位值
write_memory(address=0x20000000, data="0x12345678", width=32)
# 读取单个字节
read_memory(address=0x20000000, size=1, width=8)
# 写入16位值
write_memory(address=0x20000000, data="0xABCD", width=16)Flash编程
# 擦除Flash的一个区域
erase_flash(
start_address=0x08000000,
end_address=0x08020000
)
# 擦除整个芯片
erase_flash(chip_erase=True)
# 烧录Flash并验证
program_flash(
address=0x08000000,
data="binary_hex_data",
verify=True
)
# 验证Flash内容
verify_flash(
address=0x08000000,
data="expected_data"
)调试控制
# 暂停CPU
halt_cpu()
# 从暂停状态恢复执行,不会复位目标
run_cpu()
# 单步执行
step_instruction()
# 获取当前CPU状态
get_cpu_state()
# 复位设备
reset_target(reset_type="normal")
# 复位并暂停
reset_target(reset_type="halt")寄存器访问
# 读取所有通用寄存器
read_registers()
# 读取特定寄存器
read_registers(register_names=["R0", "R1", "PC"])
# 写入寄存器
write_register(register_name="R0", value=0x12345678)
# 使用自定义列表读取
read_registers(["R0", "SP", "LR", "PC"])SVD寄存器访问
# 列出可用的SVD文件
list_svd_devices()
# 获取设备的外设
get_svd_peripherals(device_name="STM32F407VG")
# 获取外设的寄存器
get_svd_registers(
device_name="STM32F407VG",
peripheral_name="GPIOA"
)
# 读取寄存器并解析字段
result = read_register_with_fields(
device_name="STM32F407VG",
peripheral_name="GPIOA",
register_name="MODER"
)
print(f"原始值: {result['value']}")
print(f"字段: {result['fields']}")断点和调试
# 设置断点
set_breakpoint(address=0x08000100)
# 清除断点
clear_breakpoint(address=0x08000100)RTT(实时传输)
# 启动RTT,使用缓冲区索引0
rtt_start(buffer_index=0)
# 读取RTT数据
data = rtt_read(buffer_index=0, size=1024)
print(data)
# 向RTT写入数据
rtt_write(data="test_message", buffer_index=0)
# 停止RTT
rtt_stop()
# 获取RTT状态
status = rtt_get_status()🏗️ 架构
服务器采用模块化、基于插件的架构:
┌─────────────────────────────────────────────────┐
│ JLink MCP Server │
├─────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌────────────────────┐ │
│ │ Server │ │ 工具层 │ │
│ │ Manager │ │ │ │
│ └──────┬───────┘ │ • 连接 │ │
│ │ │ • 调试 │ │
│ │ │ • 内存 │ │
│ │ │ • Flash │ │
│ │ │ • 寄存器 │ │
│ │ │ • SVD │ │
│ │ │ • RTT │ │
│ │ └────────────────────┘ │
│ │ │
│ ┌──────▼────────────────────────────────┐ │
│ │ 管理器层 │ │
│ ├────────────┬────────────┬─────────────┤ │
│ │ JLink │ SVD │ 补丁 │ │
│ │ 管理器 │ 管理器 │ 管理器 │ │
│ └────────────┴────────────┴─────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ 插件层 │ │
│ │ • DevicePatchInterface │ │
│ │ • 厂商特定补丁 │ │
│ └──────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ 硬件层 │ │
│ │ • pylink-square │ │
│ │ • J-Link SDK │ │
│ └──────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘🧩 插件系统
服务器支持灵活的插件架构,用于设备特定功能:
创建自定义补丁
from typing import Optional, List, Dict, Any
from jlink_mcp.device_patch_interface import DevicePatchInterface
class CustomDevicePatch(DevicePatchInterface):
"""自定义设备补丁实现。"""
@property
def vendor_name(self) -> str:
"""返回厂商名称。"""
return "CustomVendor"
@property
def patch_version(self) -> str:
"""返回补丁版本。"""
return "v1.0.0"
def is_available(self) -> bool:
"""检查补丁是否可用。"""
return True
def match_device_name(self, chip_name: str) -> Optional[str]:
"""
匹配并返回完整的设备名称。
Args:
chip_name: 部分或简化的设备名称
Returns:
完整的设备名称或None(如果不匹配)
"""
# 实现你的匹配逻辑
device_map = {
"CUSTOM": "CustomDevice1",
"CUST1": "CustomDevice1",
}
return device_map.get(chip_name.upper())
@property
def device_names(self) -> List[str]:
"""返回支持的设备列表。"""
return ["CustomDevice1", "CustomDevice2"]
def get_device_info(self, device_name: str) -> Optional[Dict[str, Any]]:
"""
获取设备的详细信息。
Args:
device_name: 完整的设备名称
Returns:
设备信息字典
"""
return {
"name": device_name,
"vendor": self.vendor_name,
"core": "ARM Cortex-M4",
"flash_size": 512 * 1024,
"ram_size": 128 * 1024,
}注册自定义补丁
from jlink_mcp.device_patch_manager import device_patch_manager
# 创建并注册你的自定义补丁
custom_patch = CustomDevicePatch()
device_patch_manager.register_patch(custom_patch)📚 API参考
核心函数
函数 | 参数 | 描述 |
|
| 连接到J-Link设备 |
| - | 断开当前设备连接 |
| - | 获取连接状态 |
| - | 列出连接的J-Link设备 |
| - | 扫描总线上的设备 |
| - | 获取目标设备信息 |
| - | 获取目标电压 |
函数 | 参数 | 描述 |
|
| 读取内存 |
|
| 写入内存 |
函数 | 参数 | 描述 |
|
| 擦除Flash |
|
| 烧录Flash |
|
| 验证Flash |
函数 | 参数 | 描述 |
|
| 复位目标 |
| - | 暂停CPU |
| - | 在不复位目标的情况下恢复 CPU 运行 |
| - | 单步执行 |
| - | 获取CPU状态 |
|
| 设置断点 |
|
| 清除断点 |
🐛 故障排除
常见问题
问题: 无法连接到J-Link设备
解决方案:
检查J-Link是否通过USB正确连接
验证J-Link软件已安装
尝试运行JLinkExe验证设备检测
检查接口类型(SWD vs JTAG)
验证目标设备已上电
# 测试J-Link连接
JLinkExe -device STM32F407VG -if JTAG -speed 4000问题: 内存读写失败
解决方案:
内存访问前确保目标已暂停
检查内存地址有效且可访问
确保目标内存区域使用正确的访问宽度
验证目标已上电且未处于低功耗模式
问题: Flash编程失败
解决方案:
编程前擦除Flash
验证目标设备未写保护
检查Flash算法与目标设备匹配
确保编程期间有足够的电源供应
🤝 贡献
欢迎贡献!请遵循以下准则:
Fork 本仓库
创建功能分支 (
git checkout -b feature/AmazingFeature)提交更改 (
git commit -m 'Add some AmazingFeature')推送到分支 (
git push origin feature/AmazingFeature)开启 Pull Request
📝 许可证
本项目采用MIT许可证 - 详见 LICENSE 文件。
🙏 致谢
Segger 提供J-Link硬件和软件
pylink-square 提供Python J-Link库
Model Context Protocol 提供MCP规范
Made with ❤️ for the embedded development community
为嵌入式开发社区用❤️打造
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/cyj0920/jlink_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server