STM32 GDB Debugger について
STM32 GDB Debuggerは、実機上でSTM32ファームウェアをデバッグするMCPサーバーです。組み込み開発者やコーディングエージェント向けに、GDBの生出力ではなく、障害やRTOSの分析を含む構造化されたデバッグ情報を返します。
主な機能
- 01GDBサーバー経由のファームウェア書き込みと実行
- 02実行制御とブレークポイント管理
- 03メモリー、レジスター、周辺機器の確認
- 04HardFault、スタック、FreeRTOSの分析
- 05RTT、SWO、UARTログの取得
活用シーン
- 01接続したSTM32ボードでファームウェアを起動
- 02HardFaultの発生位置をソースコードまで特定
- 03FreeRTOSのタスク、スタック、キューを確認
- 04デバッグシナリオを再生してレポートを出力
MCP 対応
MCPサーバーは、OpenOCD、J-Link GDB Server、st-utilをGDB経由で操作するSTM32デバッグツールをMCPクライアントに提供します。ファームウェア検査、障害分析、ログ取得、再生、レポート作成向けに、デコード結果と次の操作候補を返します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
86掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| probe | string | いいえ | 任意の OpenOCD プローブタイプ:stlink、jlink、cmsis-dap。省略した場合は、プロファイルの値を使い、それがなければ検出された唯一のプローブを使います。 |
| serial | string | いいえ | 特定のボードを選択するためのプローブ/ST-Link のシリアル番号(複数ターゲットの並行実行用)。'adapter serial <serial>' として自動追加されます。 |
| session | string | いいえ | 任意のデバッグセッション名。省略するとデフォルトのターゲットが使われます。 |
| speed_khz | integer | いいえ | server_args を推定する際に使用する OpenOCD アダプタークロック(デフォルトは 4000)。 |
| hub_channel | integer | いいえ | プロファイルの hub.map に記録された usb_location を使い、このハブチャネルのプローブを使用します。指定がない場合は、hub.channel を使い、それもなければラベルがこのセッション名と一致するマップエントリを使います。 |
| server_args | array | いいえ | サーバーに渡す任意の引数。例:['-f', 'interface/stlink.cfg', '-f', 'target/stm32f4x.cfg'] |
| server_type | enum | いいえ | デバッグサーバーバックエンドの種類。openocd | stlink | jlink |
| usb_location | string | いいえ | 物理 USB 位置でプローブを選択します。例:'1-1.4'。シリアル番号を報告しない複数のプローブ(多くのクローン ST-Link)から 1 つを選ぶ方法です。ハブ分離とは異なり、他のデバイスを切断しません。2 つのセッションで同時に 2 枚のボードをデバッグできます。'adapter usb location <value>' として追加されます。通常は、この値を検索する hub_channel を使います。 |
詳細
翻訳後に原文が更新されています。最新の内容は原文をご確認ください。
STM32 GDB MCP Server / STM32 GDB MCP サーバー
AI エージェントが実機で STM32 ファームウェアをデバッグできる MCP サーバーです。GDB と OpenOCD/ST-Link/J-Link を操作して、フラッシュ、ブレークポイントの設定、メモリ/レジスタ/RTOS の調査、HardFault の原因究明、プロファイリングを行い、生の GDB テキストではなくデコード済みの構造化された証拠を取得できます。
AI エージェントが実機で STM32 をデバッグできます。GDB + OpenOCD/ST-Link/J-Link を使って、フラッシュ、ブレークポイントの設定、メモリ/レジスタ/RTOS の調査、HardFault の原因究明、性能サンプリングを行い、生の GDB テキストではなくデコード済みの構造化された証拠を取得できます。
提供機能
| 起動とフラッシュ | detect_probe, suggest_server_args, build_firmware, flash_and_run, self_check, reset_target |
| 実行制御 | run_and_wait(構造化された停止イベント), run_for_duration(実行/サンプリング後に一時停止して取得), breakpoint, step, halt/continue, debug_until |
| 状態の確認(一時停止が必要) | capture_state, read_memory/read_variable, read_registers, frame, read_peripheral_register |
| 障害の診断 | reconstruct_fault_context(障害 PC → ソースコード), diagnose_fault, analyze_stack |
| RTOS/リアルタイム OS | detect_rtos, read_freertos, snapshot(scope=rtos) |
| 観測 | logging(RTT/SWO/UART), setup_swo(追加のデコーダー不要の printf), sample_pc(シンボル化サンプラー) |
| 再現性 | run_scenario(リプレイ), batch, get_session のログ/メトリクス, export_debug_report |
| マルチボード | 任意のツールに session="name" を渡します。list_sessions/close_session で管理します |
全体を通じた目標は、デコード済みの出力と suggested_next_actions による理解コストの低減と、flash_and_run/debug_until などの複合ツールで複数回の呼び出しを一度にまとめることによる再現手順の最小化です。compact モードでは表示される項目を絞ります。すべてのツールは call(tool, args) から呼び出せ、tool_help で非表示のスキーマを確認できます。
インストール
| クライアント | コマンド 1 つでインストール |
|---|---|
| Claude Code(ツール + スキル + 常駐ルール) | /plugin marketplace add Zeraissh/stm32-gdb-mcp を実行し、続けて /plugin install stm32-debug-kit@zeraissh-stm32 を実行します |
| Cursor / VSCode / Codex / Windsurf / Trae | python scripts/deploy.py --project "<firmware dir>" --ide vscode,cursor |
| 手動設定(任意の MCP クライアント) | pip install -e . を実行し、クライアントの接続先を stm32-gdb-mcp に設定します |
deploy.py はサーバーをインストールし、IDE の MCP 設定を書き込み、ファームウェアプロジェクトにプロジェクトに応じたルールファイルを配置します。クライアントごとの設定例とルールのテンプレートは docs/install-ides.md を参照してください。compact モードはデフォルトで有効です。
PyPI/console からインストールすると、stm32-gdb-mcp-check-env、stm32-gdb-mcp-install、stm32-gdb-mcp-deploy も利用できます。
stm32-gdb-mcp-check-env --json は、インポートされたモジュールのバージョン/パス、インストール済みディストリビューションのバージョン、および 4 つの console script も報告します。これらのインストール情報にずれが生じた場合は、stm32-gdb-mcp-deploy --upgrade を使用してください。
要件:PATH に arm-none-eabi-gdb と、少なくとも 1 種類の GDB Server(openocd / JLinkGDBServerCL / st-util)が必要です。python setup_env.py を実行して確認してください。
30秒クイックスタート
detect_probe() # USB evidence; auto-select only one probe
debug_profile(action=set, mcu="STM32L431", probe="stlink", elf_path="build/app.elf", svd_path="STM32L4.svd")
suggest_server_args(mcu="STM32L431") # probe omitted -> use profile probe
start_debug_session(server_type="openocd") # server_args omitted -> infer from profile mcu/probe
self_check() # ALWAYS first: byte order, core, family
flash_and_run(file_path="build/app.elf", run_to="main")
breakpoint(action=set, location="my_func", condition="state == BAD")
run_and_wait() # structured stop event + next actions
run_for_duration(duration_sec=30, capture={"expressions": ["rx_count"]})
run_for_duration(duration_sec=60, sample={"interval_ms": 500, "expressions": ["rx_count", "state"]})
reconstruct_fault_context() # on a crash: faulting PC → file:line
detect_probe は実際の USB デバイスを読み取り、同一のプローブでもシリアル番号ごとに区別して保持し、複数のプローブが接続されている場合に勝手に選択することはありません。
ツールの全リファレンス(action=/what= でまとめた簡潔なツール群)は
skills/stm32-debug/reference/tool-map.md を参照してください。サーバーには常時有効な instructions も含まれているため、どの MCP クライアントでも設定なしでデバッグループを利用できます。
重要なルール(ターゲットの状態確認が必要です)
- 読み取りにはコアが停止している必要があります。 読み取りで
target_unresponsiveが返された場合は、まずhalt_executionを実行してください。 run_for_duration(sample=...)は、ベストエフォートの低速デバッガーポーリングです。ターゲットを自ら停止することはありませんが、一部のプローブ/MCUでは、ターゲットの実行中に式を読み取れないことがあります。より高いサンプリングレート、または確実なキャプチャが必要な場合は、SWO/リングバッファを使ったファームウェアテレメトリーを使用してください。- ブレークポイントのタイムアウトは、該当の実行経路に到達していないことを意味します。 そのまま再試行しないでください。停止して
capture_stateを実行し、breakpoint(action=list)で確認してください(hit_count=0 なら未到達です)。ゲート条件のフラグを読み取り、より手前にブレークポイントを設定するか、前提条件を満たしてください。 - 書き込みにはガードが適用されます。 option bytes/IWDG/WWDG はブロックされています。許可するには
write_guard(action=policy)を実行してください。 - OpenOCD を強制終了しないでください。 ST-Link USB が応答しなくなります。
recover_sessionを使用してください。SWD 接続は排他的です。 - 応答しなくなったプローブを復旧するには、物理的な再列挙が必要です。 オプションの
[hub]エクストラをインストールし、SmartUSBHub を接続すると、hub(action=power)で VBUS を切断し、hub(action=data)で USB データラインを切断できます。これにより、再接続をツール呼び出しで実行できます。Hub がない場合は、人がケーブルを抜き差しする必要があります。
プログラム可能な USB ハブ(任意)
pip install 'stm32-gdb-mcp[hub]'
続いて、セッションをハブのポート(1 から始まる番号。ハブのシルク印刷に対応)に割り当てます。
{"action": "set", "hub": {"channel": 2, "guard": "confirm"}}
hub(action=describe) は読み取り専用で、ADC を搭載したモデルではポートごとの電圧/電流も返します。デフォルトの confirm モードでは、hub(action=power/data/cycle) に confirm=true が必要です。また、どのモードでも(guard: allow を含む)、呼び出し元のセッション自体の GDB サーバーがそのポートで稼働中の場合は必要です。フラッシュ中に電源を切ると、ボードが文鎮化するためです。チェック対象の範囲に注意してください。local モードでは、呼び出しを行ったセッションだけを確認するため、別のセッションがそのチャネルでフラッシュ中でも検知できません。共有ハブデーモンを使用する場合(デフォルト。詳細は後述)、すべてのサーバーに登録されたすべてのセッションを確認します。
3 つのエントリーポイントは、それぞれ独自に確認します。これらを意図的に指定して呼び出すこと自体が確認にあたり、その判断は hub(action=describe) が返す監査ログにも記録されます。reset_target(strategy="cold") と recover_session の段階的な復旧処理では、電源を切る前に GDB セッションを停止するため、稼働中のセッションから VBUS をいきなり引き抜くことはありません。hub(action=discover) は、セッションが稼働中の場合は実行を拒否します。ただし、force=true を指定するとインターロックが完全に無効になるため、このフラグを使う場合は完全に自己責任となります。スクリプト化された CI では guard: allow を設定してください。
Selecting a channel on a multi-board rack / 多板机架下的通道选择
上記の hub: {channel: N} は、1つのセッションを1つのポートに固定します。複数のボードがある場合は、代わりにラック全体を一度にマッピングし、各セッションで個別にチャンネルを選択します。/
上面的 hub: {channel: N} 把一个会话钉在一个端口上。多块板时改为一次性描述整个机架,
让每个会话各自选中自己的通道:
# bench_hub.yaml
hub:
port: COM7 # omit to auto-scan / 省略则自动扫描
guard: confirm
map:
3: {label: TC}
4: {label: AGS}
{"action": "load", "path": "bench_hub.yaml"}
ここで間違えやすい点が3つあります。/ 其中有三点很容易搞错:
labelはデバッグセッション名と完全一致で照合されます。 自由に付けられるニックネームではありません。セッションがsession="TC"として開始された場合にのみ、チャンネルが選択されます。これはシリアル番号のないプローブでチャンネルを選択する唯一の方法です。hub(action=discover, apply=true)は USB ポートをキーとして割り当てます。これでチャンネルを識別できますが、チャンネルを選択することはできません。/label是与调试会话名精确比对的,不是自由昵称:只有会话以session="TC"启动时才会 选中该通道。对于无序列号的探针这是唯一可行的选择方式——hub(action=discover, apply=true)只能按 USB 端口给它们建 key,那能认出通道,却无法选中通道。- デバッグプロファイルはセッションごとに設定されます。 1つのセッションに設定を読み込んでも、別のセッションからそのマップは参照できません。その場合、hub の呼び出しは
hub_unavailable: hub channel unmappedで失敗します。各セッションで設定を読み込んでください。debug_config(action=load, path="bench_hub.yaml", session="TC")。プロファイルはメモリ上にのみ保持されるため、サーバーを再起動するたびに読み込み直す必要があります。/ 调试 profile 是按会话隔离的。 在一个会话里加载配置,另一个会话看不到该映射,此时 hub 调用会以hub_unavailable: hub channel unmapped失败。需要给每个会话都加载一次:debug_config(action=load, path="bench_hub.yaml", session="TC")。profile 还是纯内存的, 因此服务器每次重启后都要重新加载。 setはネストされたブロックをマージせず、丸ごと置き換えます。debug_profile(action=set, hub={...})はそれ以外のプロファイル項目をすべて保持しますが、渡したhubブロックは保存済みの内容全体を置き換えます。そのため、hub(action=discover, apply=true)の後にhub={map: {3: {label: TC}}}を設定すると、discovery が書き込んだプローブの識別情報も失われます(シリアル番号のないプローブには、ほかに識別情報がありません)。保存済みのブロックにディープマージするにはmerge=trueを指定してください。古いチャンネルを削除する場合は、置き換えが唯一の削除方法なので、mergeは指定しないでください。/set对嵌套块是整块替换,不是合并。 顶层其他字段会保留,但传入的hub块会整块覆盖已 存的内容——在hub(action=discover, apply=true)之后再写hub={map: {3: {label: TC}}}, 会把 discovery 写入的探针身份一并丢掉(无序列号探针没有别的身份可用)。需要合并请加merge=true;要删除过期通道则保持默认的替换语义,因为那是唯一的删除方式。
正しく動作すると、結果に channel_source: "map_label" が含まれます。適切なポートが選ばれたと思い込まず、このフィールドを確認してください。/
生效时结果会带 channel_source: "map_label"——请以该字段为准,不要想当然认为选对了端口。
一个机架上的多个 MCP 服务器 / 多个 MCP 服务器共用一个 Hub
Hub 的控制端口同一时间只能由一个进程打开,因此默认情况下,首次调用 hub 时会启动一个小型Hub 守护进程
来独占该端口,所有 MCP 服务器都会与它通信。调用 hub(...) 的方式完全不变。
- 读取操作共享。写操作只锁定涉及的通道:CH1 上的电源循环不会与 CH1 上的其他开关操作交错,但 CH4 上的开关操作可以同时进行。exclusive 隔离会锁定整个机架;
hub(action=discover)在整个运行期间持有全机架租约,因此其他服务器的开关操作不会干扰映射。冲突请求按先来先服务的顺序等待,因此全机架请求不会被饿死。 - 每个服务器的防护模式各自独立(CI 服务器上的
guard: allow不会放宽其他服务器的限制),审计日志会记录每项操作由哪个服务器执行。 - 服务器关闭的电源或数据连接会在它退出时恢复;如果守护进程发现该服务器的进程已不存在,也会恢复。
- **跨服务器互锁。**每个服务器都会登记带有
hub配置块的会话(每次工具调用后登记一次,另有每 2 秒一次的心跳)。如果任一服务器在某个通道上有活跃的 GDB 服务器,切断该通道的电源或数据连接都必须设置confirm=true,无论防护模式如何;拒绝信息会指出对应的会话和服务器。只要机架上有任一服务器处于活跃状态,hub(action=discover)就会拒绝运行。没有hub配置块的会话无法映射到通道,因此不受保护。 - 写操作最多等待其他服务器的写操作 30 秒,之后会被拒绝(不会延迟执行),并指出占用 Hub 的对象;等待过的操作会在结果中报告
queued_ms。每次切换也会使所有服务器的detect_probe缓存失效。 - 守护进程空闲 10 分钟后退出,除非仍有待恢复的通道。
python -m mcp_server.hub_daemon status # URL, version, connected servers
python -m mcp_server.hub_daemon stop # restores what clients switched off
python -m mcp_server.hub_daemon serve --config bench_hub.yaml # run it yourself, foreground
STM32_GDB_MCP_HUB_MODE=auto(默认)会使用守护进程;如果缺少 [hub] extra 或守护进程无法启动,则退回进程内模式;daemon 不会退回;local 为原来的单进程行为。所有服务均绑定到 127.0.0.1;写操作需要使用用户专属状态文件中的 token。
实时看板
hub(action=dashboard) # -> data.url, e.g. http://127.0.0.1:8765/
只读页面:显示各端口的电源和数据连接状态、实时电压/电流/功率及 1/5/15 分钟历史记录(断电时段以阴影标示),以及 Hub 操作时间线。使用守护进程时,该页面由守护进程提供,会显示所有已连接的 MCP 服务器及各服务器仍有待恢复的内容;在 local 模式下,页面由此服务器运行(state=off 会停止页面),并列出该服务器的デバッグセッション。
応答形式
各ツールは、MCP TextContent トランスポート内で次の安定した JSON エンベロープを返します。
{ "ok": true, "data": {}, "error": null, "raw_response": null, "suggested_next_actions": [] }
人間が読めるメッセージは data.message / error.message に格納されます。診断に役立つ場合は、未加工の GDB 出力が raw_response に保持されます。エラーには code(例:target_unresponsive)が含まれます。最新の MCP クライアントには、同じ内容のネイティブな structuredContent も返され、エラー結果では isError=true が設定されます。
エージェント向けガイダンス — 3つのレイヤー
- インライン — ほとんどの結果には、次のループのステップを示す
suggested_next_actionsが含まれます。 - 常時有効 — サーバーの
instructionsによって、デバッグループと重要なルールが自動的に注入されます。 - オンデマンド — スキル:
stm32-debug(立ち上げ、HardFault、ハング、最小再現、再実行可能なシナリオ)とstm32-instrument(書き込み時の SWO/ITM トレース)。他の IDE では、同じガイダンスをルールファイル(AGENTS.md)で提供します。
再現可能な設定
YAML デバッグプロファイルを読み込み、クライアント間でセッションを再現できるようにします:
debug_config(action=load, path="mcp/board.yaml")。
mcu: STM32L431CCUx
probe: stlink
server_type: openocd
server_args: ["-f", "interface/stlink.cfg", "-f", "target/stm32l4x.cfg"]
elf_path: build/app.elf
svd_path: STM32L4.svd
相対パスの elf_path、svd_path、project_root、swo.file の値は、YAML ファイルのディレクトリを基準に解決されます。セッションの開始、ログ記録、リセット、フラッシュの各ツールは、対応する引数が省略された場合、読み込んだプロファイルを使用します。
設定の読み込み、接続、必須の識別情報チェックを、1回の MCP 往復で実行します:
batch(steps=[
{"tool": "debug_config", "args": {"action": "load", "path": "mcp/board.yaml"}},
{"tool": "start_debug_session", "args": {}},
{"tool": "self_check", "args": {}}
], stop_on_error=true)
上記の手順では、「設定の読み込み → 接続 → 自己診断」を1回の MCP 往復で実行し、いずれかのステップが失敗すると停止します。
J-Link、OpenOCD、および書き込みを行わない L151/L431/U535 HIL プロファイルについては、examples/configs/ を参照してください。
開発
pip install -e ".[dev]"
python -m ruff check . && python -m pytest && python -m compileall src tests
python -m build && python scripts/check_dist_contents.py dist/*
docs/install-ides.md— IDE ごとのインストールとルールのテンプレートdocs/TROUBLESHOOTING.md— よくある障害と復旧方法docs/hil-validation.md— HIL 検証(STM32_GDB_MCP_HIL=1)CONTRIBUTING.md、SECURITY.md、docs/release.md
ハードウェア検証は、stm32 ラベルが付いたセルフホストランナーで実行されます。通常の CI ではハードウェアを使用せず、lint、テスト、コンパイル、パッケージングを実行します。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。