oh-mcp-dap

oh-mcp-dap

An MCP server that provides a real debugger via the Debug Adapter Protocol, exposing a single 'debug' tool to launch/attach, control execution, and inspect program state across gdb, lldb, debugpy, and more.

Category
访问服务器

README

oh-mcp-dap

An MCP server that gives an AI agent a real debugger. It speaks the Debug Adapter Protocol (DAP) to gdb, lldb, debugpy, delve, and any other adapter you configure — launch or attach to a program, set breakpoints, step, and inspect threads, frames, variables, memory, and disassembly.

It is a thin MCP wrapper around the DAP engine from oh-my-pi (@oh-my-pi/pi-coding-agent), reusing its session manager and adapter-config system rather than reimplementing DAP. See Attribution.

⚗️ Experiment. This is an exploratory project — an experiment in reusing oh-my-pi's DAP engine behind a single-tool MCP server. Interfaces may change, it has not been battle-tested, and it has not yet been run end-to-end against a live client in this form. Feedback and breakage reports welcome.

Runs on Bun (see Requirements).


Why one tool (the design difference)

Most MCP DAP servers expose one MCP tool per DAP operation: set_breakpoint, continue, step_over, evaluate, stack_trace, read_memory, … — twenty-plus separate tools.

oh-mcp-dap exposes a single debug tool with an action field that selects the operation. This is the same shape oh-my-pi uses internally, and it's a deliberate choice:

Tool-per-function Single action tool (this server)
Tools added to the model's context 20–30 1
Token cost of the tool list High, always present Low
Where the operation lives The tool name The action argument
Adding a new DAP op New tool, new registration New action enum value
Discoverability for the model Many shallow tools One tool whose description lists the workflow

Why the single tool wins for a debugger specifically:

  • Context economy. Every registered tool's name + schema sits in the model's context on every turn. A debugger's operations are numerous but individually tiny; paying 25 tool-schemas' worth of tokens to describe them crowds out the tools the agent actually reasons about. One tool keeps the surface flat.
  • The operations are one workflow, not 25 capabilities. launch → set_breakpoint → continue → stack_trace → variables → step is a single stateful conversation with one session. Modeling it as one tool with an action mirrors that: the description teaches the flow, and the shared parameter set (file, line, frame_id, expression, …) is documented once.
  • Coherent state. There is exactly one active session. A single tool makes that constraint obvious instead of spreading it across many tools that all implicitly mutate the same hidden session.
  • Cheap evolution. New adapter capabilities become new action values; no client re-discovery churn.

The tradeoff is honest: a single tool has a broader input schema, and a client UI that renders per-tool affordances sees only one entry. For an agent driving a debugger, the context savings and workflow clarity are worth it. If you want the per-tool model instead, this server isn't that — by design.


What it exposes

One tool, debug. Required field action; the rest are that action's arguments. Actions:

Session: launch, attach, terminate, sessions, output Breakpoints: set_breakpoint, remove_breakpoint, set_instruction_breakpoint, remove_instruction_breakpoint, data_breakpoint_info, set_data_breakpoint, remove_data_breakpoint Execution: continue, step_over, step_in, step_out, pause Inspection: threads, stack_trace, scopes, variables, evaluate, modules, loaded_sources, read_memory, write_memory, disassemble Escape hatch: custom_request (any raw DAP request)

Typical flow:

{ "action": "launch", "program": "./my_app" }
{ "action": "set_breakpoint", "file": "src/main.c", "line": 42 }
{ "action": "continue" }
{ "action": "stack_trace" }
{ "action": "scopes", "frame_id": 0 }
{ "action": "variables", "scope_id": 1001 }
{ "action": "terminate" }

Requirements

  • Bun ≥ 1.3.14. The upstream DAP engine is Bun-native (ships TypeScript, uses Bun's YAML). This server runs on Bun; Node is not supported.
  • The debug adapter(s) for your language on PATH (e.g. gdb, lldb-dap, debugpy, dlv). Adapters are external programs — this server only drives them.

Install

git clone <this-repo> oh-mcp-dap
cd oh-mcp-dap
bun install

Smoke-check that it starts (it will wait on stdin for a client — Ctrl-C to exit):

bun run src/server.ts --workspace .

Configure your MCP client

Point your client at the server with Bun. Set the workspace to the project you want to debug — that's where dap.json and root markers are resolved from.

Claude Code / Claude Desktop (mcpServers):

{
  "mcpServers": {
    "dap": {
      "command": "bun",
      "args": ["run", "/absolute/path/to/oh-mcp-dap/src/server.ts"],
      "env": { "OH_MCP_DAP_WORKSPACE": "/absolute/path/to/your/project" }
    }
  }
}

The workspace can be set three ways (first wins): --workspace <dir> / -w <dir> arg, OH_MCP_DAP_WORKSPACE env, else the server's process.cwd(). Any individual call may also override it with a cwd argument.


Adapter configuration (dap.json)

Adapters are configured exactly as in oh-my-pi. A set of built-in adapters ships out of the box and any dap.json you provide is merged over them, so you can add new debuggers or tweak existing ones without redefining everything.

Built-ins include: gdb, lldb-dap, codelldb, debugpy, dlv, js-debug-adapter, netcoredbg, kotlin-debug-adapter, rdbg, php-debug-adapter, bash-debug-adapter, dart, flutter, elixir-ls-debugger.

Add any adapter

Drop a dap.json in your workspace (the file is auto-discovered — see discovery order). Example: a custom 4D adapter that this repo ships in dap.json:

{
  "adapters": {
    "4d": {
      "command": "node",
      "args": ["4d-dap-bridge.js", "${port}"],
      "connectMode": "tcp",
      "languages": ["4d"],
      "fileTypes": [".4dm"],
      "rootMarkers": [".4DProject", "Project"],
      "launchDefaults": { "request": "launch" },
      "attachDefaults": { "request": "attach" }
    }
  }
}

Adapter fields

Field Meaning
command Adapter executable (resolved on PATH, or a relative/absolute path).
args Launch args. ${port} is substituted with a free port for socket/tcp adapters.
connectMode "stdio" (default), "socket", or "tcp". How the server talks to the adapter.
languages Language ids this adapter serves (informational / selection).
fileTypes File extensions (e.g. .py) used to auto-select the adapter for a target.
rootMarkers Files/dirs that mark a project root (e.g. Cargo.toml), used for selection.
launchDefaults / attachDefaults Default DAP request bodies merged into every launch/attach.
acceptsDirectoryProgram true if the adapter accepts a directory as program (e.g. dlv).

Auto-selection: when a call omits adapter, the server picks one by the target's file type and nearest root marker. Pass adapter to force a choice.

Discovery order

dap.json (also .dap.json, dap.yaml, dap.yml) is discovered from, and merged in this precedence (later overrides earlier), all on top of the built-ins:

  1. built-in defaults
  2. ~/dap.json (home)
  3. user config dirs
  4. project config dirs (relative to the workspace)
  5. <workspace>/dap.json

So a workspace-local dap.json has the final say.


How it works

MCP client ──stdio JSON-RPC──▶ src/server.ts        (one "debug" tool)
                                   │
                                   ▼
                              src/dispatch.ts        (action → engine → text)
                                   │
                                   ▼
                              src/dap-core.ts  ──▶  @oh-my-pi/pi-coding-agent/dap
                                                     • dapSessionManager (the real DAP client + session)
                                                     • dap.json config + adapter selection
  • src/server.ts — MCP stdio server; registers the single tool and routes calls.
  • src/schema.ts — the tool's JSON Schema + description.
  • src/dispatch.ts — the action switch (adapted from oh-my-pi's debug tool, agent-framework couplings removed).
  • src/format.ts — plain-text renderers for DAP responses.
  • src/dap-core.ts — the single import seam onto the engine.

Depending vs. vendoring

This server depends on the published @oh-my-pi/pi-coding-agent package and imports its official /dap subpath — no engine code is copied in. That keeps the debugger logic upstream (bug fixes flow in) at the cost of pulling a large dep tree at install time (only DAP-reachable code loads at runtime).

If you ever need to cut that dependency, everything the engine provides is behind src/dap-core.ts. Vendoring packages/coding-agent/src/dap/** (MIT) and its few internal helpers, then rewriting only that one file, is the supported escape hatch.

A note on stdout

The MCP stdio transport owns stdout for JSON-RPC. The server forces the upstream logger's console transport off and mirrors diagnostics to stderr, so adapter/engine logs never corrupt the protocol stream. Watch stderr for [oh-mcp-dap] lines.


Attribution

Built on oh-my-pi by Mario Zechner and Can Bölük (MIT). The DAP engine is used as a dependency; the formatters and dispatch logic are adapted from packages/coding-agent/src/tools/debug.ts. See NOTICE and LICENSE.

This project is MIT-licensed.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选