dap-mcp-server 0.1.12 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +25 -7
  2. package/SKILL.md +37 -186
  3. package/build/adapters/detect.d.ts +12 -0
  4. package/build/adapters/detect.js +91 -0
  5. package/build/adapters/detect.js.map +1 -1
  6. package/build/adapters/registry.js +35 -12
  7. package/build/adapters/registry.js.map +1 -1
  8. package/build/diagnostics/doctor.d.ts +64 -0
  9. package/build/diagnostics/doctor.js +209 -0
  10. package/build/diagnostics/doctor.js.map +1 -0
  11. package/build/server.js +305 -83
  12. package/build/server.js.map +1 -1
  13. package/build/session/inspect.d.ts +6 -2
  14. package/build/session/inspect.js +24 -8
  15. package/build/session/inspect.js.map +1 -1
  16. package/build/session/run.js +2 -9
  17. package/build/session/run.js.map +1 -1
  18. package/build/session/session.d.ts +16 -0
  19. package/build/session/session.js +63 -8
  20. package/build/session/session.js.map +1 -1
  21. package/integrations/claude/dap-debugging/.claude-plugin/plugin.json +9 -0
  22. package/integrations/claude/dap-debugging/.mcp.json +8 -0
  23. package/integrations/claude/dap-debugging/skills/dap-debugging/SKILL.md +49 -0
  24. package/package.json +8 -3
  25. package/.forgejo/workflows/publish.yml +0 -63
  26. package/CLAUDE.md +0 -71
  27. package/TODO.md +0 -32
  28. package/docs/plans/2026-03-05-dap-wrapper-mcp-design.md +0 -326
  29. package/docs/plans/2026-03-05-dap-wrapper-mcp-implementation.md +0 -2815
  30. package/src/adapters/builtin.ts +0 -75
  31. package/src/adapters/detect.test.ts +0 -36
  32. package/src/adapters/detect.ts +0 -36
  33. package/src/adapters/registry.test.ts +0 -74
  34. package/src/adapters/registry.ts +0 -86
  35. package/src/dap/dap-client.test.ts +0 -118
  36. package/src/dap/dap-client.ts +0 -588
  37. package/src/dap/protocol.test.ts +0 -82
  38. package/src/dap/protocol.ts +0 -78
  39. package/src/dap/ring-buffer.test.ts +0 -82
  40. package/src/dap/ring-buffer.ts +0 -64
  41. package/src/dap/types.ts +0 -115
  42. package/src/index.ts +0 -30
  43. package/src/integration/debug-lifecycle.test.ts +0 -131
  44. package/src/server.ts +0 -1096
  45. package/src/session/inspect.test.ts +0 -126
  46. package/src/session/inspect.ts +0 -160
  47. package/src/session/run.test.ts +0 -74
  48. package/src/session/run.ts +0 -144
  49. package/src/session/session-manager.test.ts +0 -74
  50. package/src/session/session-manager.ts +0 -67
  51. package/src/session/session.test.ts +0 -126
  52. package/src/session/session.ts +0 -482
  53. package/src/test-fixtures/crash-adapter.js +0 -23
  54. package/src/test-fixtures/mock-adapter.js +0 -164
  55. package/src/test-fixtures/no-stop-adapter.js +0 -77
  56. package/src/test-fixtures/silent-adapter.js +0 -24
  57. package/src/test-fixtures/tcp-mock-adapter.js +0 -87
  58. package/tsconfig.json +0 -16
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: dap-debugging
3
+ description: Use a real debugger for opaque test failures, crashes, swallowed exceptions, incorrect runtime state, or a bug that remains unexplained after static inspection or a failed fix. Prefer this over adding multiple print statements when actual values, branches, or call stacks are needed.
4
+ ---
5
+
6
+ # Debug Code with DAP
7
+
8
+ Use the `dap` MCP server when static inspection cannot explain a runtime failure. Debugging executes local code and can trigger its normal side effects, so do not run untrusted targets.
9
+
10
+ ## Preferred Workflow
11
+
12
+ 1. Call `debug_doctor` with the project `cwd`. Follow its remediation when `ready` is false.
13
+ 2. Choose an executable line near the first observable bad state.
14
+ 3. Call `debug_at` with `file`, `line`, and a small set of hypothesis-driven `expressions`. It detects the adapter, launches, inspects, and cleans up in one call.
15
+
16
+ ```json
17
+ {
18
+ "cwd": "/workspace/project",
19
+ "program": "/workspace/project/app.py",
20
+ "file": "/workspace/project/app.py",
21
+ "line": 42,
22
+ "expressions": ["request.user", "result"]
23
+ }
24
+ ```
25
+
26
+ Read the outcome precisely:
27
+
28
+ - `hit: true`: use the location and values as evidence.
29
+ - `status: terminated`: execution finished before the breakpoint; verify path, arguments, and branch.
30
+ - `timedOut: true`: inspect captured output and narrow the target.
31
+ - With `hit: false`, `breakpoint.verified: false` means the adapter could not bind the source location.
32
+
33
+ Pass adapter-specific fields through `launchConfig`. Use absolute program and source paths.
34
+
35
+ ## Failing Tests
36
+
37
+ Debug the smallest failing test. Supply its runner as `program` or through `launchConfig`, and its selector in `args`. Launch conventions differ across adapters; retain known-good fields from `.vscode/launch.json`. Put the breakpoint in application code before the assertion or exception boundary.
38
+
39
+ ## Interactive Exploration
40
+
41
+ Use `debug_launch` only for multiple stops or stepping. A launch with breakpoints waits by default and reports stopped, terminated, or timeout.
42
+
43
+ 1. Inspect the state returned by `debug_launch`.
44
+ 2. Use `evaluate` for focused questions.
45
+ 3. Prefer `step` with `next`; use `stepIn` only when the callee is suspect.
46
+ 4. Move breakpoints with `set_breakpoints` as the hypothesis changes.
47
+ 5. Finish with `debug_disconnect`.
48
+
49
+ Omit `sessionId` when one session is active. Use `debug_run` when output and termination are sufficient. For repeated observations, use logpoints (`logMessage`) and read them with `get_output` instead of editing source to add prints.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dap-mcp-server",
3
- "version": "0.1.12",
3
+ "version": "0.1.16",
4
4
  "description": "MCP server wrapping the Debug Adapter Protocol for AI-driven debugging",
5
5
  "keywords": [
6
6
  "LLM",
@@ -19,6 +19,11 @@
19
19
  "bin": {
20
20
  "dap-mcp-server": "build/index.js"
21
21
  },
22
+ "files": [
23
+ "build",
24
+ "SKILL.md",
25
+ "integrations/claude/dap-debugging"
26
+ ],
22
27
  "directories": {
23
28
  "doc": "docs"
24
29
  },
@@ -31,7 +36,7 @@
31
36
  "typecheck": "tsc --noEmit"
32
37
  },
33
38
  "dependencies": {
34
- "@modelcontextprotocol/sdk": "^1.27.1",
39
+ "@modelcontextprotocol/sdk": "^1.30.0",
35
40
  "@vscode/debugprotocol": "^1.68.0"
36
41
  },
37
42
  "peerDependencies": {
@@ -40,6 +45,6 @@
40
45
  "devDependencies": {
41
46
  "@types/node": "^25.3.3",
42
47
  "typescript": "^5.9.3",
43
- "vitest": "^4.0.18"
48
+ "vitest": "^4.1.11"
44
49
  }
45
50
  }
@@ -1,63 +0,0 @@
1
- name: Publish to npm
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
-
8
- jobs:
9
- publish:
10
- runs-on: docker
11
- steps:
12
- - name: Checkout
13
- uses: actions/checkout@v4
14
- with:
15
- fetch-depth: 0
16
- token: ${{ secrets.REPO_TOKEN }}
17
-
18
- - name: Setup Node.js
19
- uses: actions/setup-node@v4
20
- with:
21
- node-version: '20'
22
- registry-url: 'https://registry.npmjs.org'
23
-
24
- - name: Install dependencies
25
- run: npm ci
26
-
27
- - name: Run tests
28
- run: npm test
29
-
30
- - name: Run typecheck
31
- run: npm run typecheck
32
-
33
- - name: Build
34
- run: npm run build
35
-
36
- - name: Configure git
37
- run: |
38
- git config user.name "Forgejo Actions"
39
- git config user.email "actions@forgejo.local"
40
-
41
- - name: Bump version and publish
42
- env:
43
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
44
- run: |
45
- # Get current version
46
- CURRENT_VERSION=$(node -p "require('./package.json').version")
47
- echo "Current version: $CURRENT_VERSION"
48
-
49
- # Bump patch version
50
- npm version patch --no-git-tag-version
51
- NEW_VERSION=$(node -p "require('./package.json').version")
52
- echo "New version: $NEW_VERSION"
53
-
54
- # Commit version bump
55
- git add package.json package-lock.json
56
- git commit -m "chore: bump version to $NEW_VERSION [skip ci]"
57
- git tag "v$NEW_VERSION"
58
-
59
- # Push changes back to repository
60
- git push origin main --tags
61
-
62
- # Publish to npm
63
- npm publish --access public
package/CLAUDE.md DELETED
@@ -1,71 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Project Overview
6
-
7
- MCP server wrapping the Debug Adapter Protocol (DAP) for AI agent-driven debugging. TypeScript, Node.js, ESM modules. Published to npm as `dap-mcp-server`.
8
-
9
- ## Commands
10
-
11
- ```bash
12
- npm run build # TypeScript compilation → build/
13
- npm run typecheck # Type-check without emitting (tsc --noEmit)
14
- npm test # vitest run (all tests)
15
- npm run test:watch # vitest in watch mode
16
- npm run dev # tsc --watch
17
- npm start # Run the MCP server (stdio transport)
18
- npx vitest run src/path/to/file.test.ts # Run a single test file
19
- ```
20
-
21
- ## Architecture
22
-
23
- Three layers, top to bottom:
24
-
25
- 1. **MCP Layer** (`src/server.ts`, `src/index.ts`) — `McpServer` with 12 tools + 1 resource (`dap://sessions`). All tool handlers return `{ content: [{ type: "text", text: JSON.stringify(...) }] }` with `isError: true` on failure. Entry point connects via `StdioServerTransport`.
26
-
27
- 2. **Session Layer** (`src/session/`) — `DebugSession` wraps a `DAPClient` with state machine (`idle → configuring → running ↔ stopped → terminated`), output buffering (`RingBuffer<OutputEntry>`), and composite state collection (`collectState()` fetches threads + stack + scopes + variables in one call). `SessionManager` handles multi-session tracking with auto-resolution (single active session doesn't need explicit ID).
28
-
29
- 3. **DAP Layer** (`src/dap/`) — `DAPClient` spawns adapter as child process, communicates via stdin/stdout using DAP wire protocol (Content-Length headers + JSON bodies, same framing as LSP). `MessageParser` handles incremental parsing. `DAPClient` extends `EventEmitter`, emitting DAP events and tracking pending request/response correlation by sequence number.
30
-
31
- 4. **Adapters** (`src/adapters/`) — `AdapterRegistry` with three tiers: builtins (`builtin.ts`) < global (`~/.dap-mcp/adapters.json`) < project (`./.dap-mcp/adapters.json`). Higher tiers override lower. `detect.ts` checks adapter binary availability via `which`/`where`.
32
-
33
- ### Request Lifecycle
34
-
35
- `MCP tool call → server.ts handler → SessionManager.resolve(sessionId) → DebugSession method → DAPClient.sendRequest(command, args) → serialize to DAP wire format → adapter stdin → adapter stdout → MessageParser → response correlation by seq number → resolve Promise`
36
-
37
- Events flow the reverse direction: adapter emits events → `DAPClient` re-emits → `DebugSession.handleEvent()` updates state machine, resolves waiters, buffers output.
38
-
39
- ## Code Conventions
40
-
41
- - ESM modules (`"type": "module"` in package.json)
42
- - Import paths use `.js` extension (e.g., `import { Foo } from "./foo.js"`)
43
- - Never `console.log()` in server code — stdout is MCP wire protocol; use `console.error()` for diagnostics
44
- - All tool execution errors use `isError: true` in MCP results, not JSON-RPC protocol errors
45
- - Types from `@vscode/debugprotocol` for DAP message types
46
- - Internal/MCP-facing types in `src/dap/types.ts`
47
- - All source files carry an MIT license header comment — preserve it when creating new files
48
-
49
- ## Testing
50
-
51
- - Framework: vitest (no config file — uses defaults)
52
- - Unit tests: co-located with source (`*.test.ts`)
53
- - Integration tests: `src/integration/` — test full DAP lifecycle against mock adapters
54
- - Test fixtures: `src/test-fixtures/` — mock DAP adapters written in **plain JS** (not TypeScript), implementing enough of the DAP protocol to test against. `mock-adapter.js` is the full-featured one; `crash-adapter.js` and `silent-adapter.js` test error cases.
55
-
56
- ## Key Design Decisions
57
-
58
- 1. **Coarse-grained tools**: `get_state` returns threads+stack+scopes+variables in one call to minimize AI agent round-trips
59
- 2. **Synchronous stepping**: `step` blocks until stopped, returns new state
60
- 3. **Auto-session resolution**: `sessionId` optional when single session active
61
- 4. **Output ring buffer**: 10K lines max, oldest dropped
62
- 5. **Own DAP client**: Custom implementation (not `@vscode/debugadapter-testsupport`) for full control over event buffering and crash detection
63
-
64
- ## CI/CD
65
-
66
- Forgejo Actions workflow (`.forgejo/workflows/publish.yml`) runs on push to `main`: tests → typecheck → build → bump patch version → publish to npm. Version bumps are auto-committed with `[skip ci]`.
67
-
68
- ## Design Documents
69
-
70
- - Design: `docs/plans/2026-03-05-dap-wrapper-mcp-design.md`
71
- - Implementation plan: `docs/plans/2026-03-05-dap-wrapper-mcp-implementation.md`
package/TODO.md DELETED
@@ -1,32 +0,0 @@
1
- # DAP MCP Server — Improvement TODO
2
-
3
- Findings from a self-review of how usable this MCP is for an AI agent. Ordered by priority (descending). Check items off as completed.
4
-
5
- ## Tier 1 — Documentation (SKILL.md). High leverage, low risk.
6
-
7
- - [x] **P1 — Logpoints section.** `breakpoints[].logMessage` is already wired through (session.ts:138) but is invisible in SKILL.md. It is the closest thing to a drop-in replacement for `print()` debugging: no code edits, captures every hit, no execution pause. Should have its own headline section with an example.
8
- - [x] **P2 — "Debug a failing test" section.** Most real bugs surface inside test runners (pytest, vitest, jest, go test, cargo test). Currently zero guidance. Add a per-framework template for launching a single test under the debugger.
9
- - [x] **P3 — "Switch from print() to debugger" triggers.** Concrete rules an AI agent will actually follow: "if first fix attempt was wrong, stop guessing"; "if about to add 3+ prints, use logpoints"; "if reasoning about iteration N, use `hitCondition`"; "if traceback is non-obvious, launch test under debugger".
10
- - [x] **P4 — Stepping strategy.** Default to `next`. Use `stepIn` only when you suspect the bug is *inside* the called function. Otherwise agents get lost in library internals.
11
- - [x] **P5 — Full worked example.** Real bug → real `debug_launch` call → real returned state → identified fix. Replaces all the abstract advice with one concrete walkthrough.
12
- - [x] **P5b — Node.js adapter recipe.** Builtin was removed; add a ready-to-paste `configure_adapter` snippet for `js-debug-dap`.
13
-
14
- ## Tier 2 — Code changes that materially improve UX.
15
-
16
- - [x] **P6 — `debug_inspect` macro tool.** One call: launch, run to a breakpoint, evaluate a list of expressions, disconnect. Collapses a 5–7 round-trip workflow into 1. Most likely change to make me reach for the debugger reflexively.
17
- - [x] **P7 — Flip `stopOnEntry` default to `false` when breakpoints are provided.** Today defaults to `true` regardless (server.ts:206). Doing the right thing automatically is better than relying on the agent reading the SKILL.md.
18
- - [x] **P8 — Structured deep variables.** `getVariables` with `depth > 1` flattens children into the value string (session.ts:271–278). Hard for the AI to consume. Return nested `children: [...]` instead.
19
- - [x] **P9 — `list_adapters` summary line + surfaced install hints.** Add `summary: "2/4 installed"` and lift `installHint` for missing adapters to the top level so it's scannable.
20
- - [x] **P10 — `debug_run` macro tool.** Launch, run to completion, return all stdout/stderr. Zero breakpoints, zero round-trips. For "what does this script actually print/crash with?" cases.
21
-
22
- ## Tier 3 — Polish.
23
-
24
- - [x] **P11 — Better "session is not stopped" error.** Currently says "use step with action: pause" (server.ts:549) — bad advice (Python `pause` lands in arbitrary library code). Suggest "set a breakpoint where you want to inspect, then continue to it".
25
- - [x] **P12 — Version drift.** `McpServer` registers as `0.1.0` (server.ts:48); package.json is `0.1.10`. Read from `package.json`.
26
- - [x] **P13 — `list_breakpoints` tool.** After several `set_breakpoints` calls, no way to introspect what's set. Minor.
27
-
28
- ## Tier 4 — Speculative.
29
-
30
- - [x] **`get_output({ since })` for incremental polling.** Smaller substitute for streaming subscriptions. Caller passes the `nextSince` value from a prior call to receive only newly-emitted entries. Useful for watching logpoint output during `continue` against long-running programs.
31
- - [ ] ~~Streaming output via MCP resource subscriptions.~~ AI agents don't watch streams in real time; the request/response pattern doesn't benefit. `since`-based polling covers the practical case.
32
- - [ ] ~~Auto-detect test runner from program path.~~ Too magic; SKILL.md recipes (P2) make the right call explicit, and silent misfires would be worse than no detection at all.
@@ -1,326 +0,0 @@
1
- # DAP Wrapper MCP Server — Design Document
2
-
3
- **Date**: 2026-03-05
4
- **Status**: Approved
5
-
6
- ## Purpose
7
-
8
- An MCP server that wraps the Debug Adapter Protocol (DAP), enabling AI agents (Claude, etc.) to use real debuggers instead of relying on print statements and log analysis. The server spawns debug adapters as child processes and exposes a coarse-grained set of MCP tools optimized for agent-driven debugging workflows.
9
-
10
- ## Decisions
11
-
12
- - **Language**: TypeScript (Node.js)
13
- - **Transport**: MCP over stdio; DAP over child process stdin/stdout
14
- - **Adapter management**: Config-based with a registration tool + built-in defaults for Python (debugpy), Node.js (js-debug), Go (delve), C/C++ (lldb-dap)
15
- - **Tool granularity**: Coarse-grained (~12 tools), composite responses
16
- - **Execution model**: Synchronous stepping with configurable timeout — `step` blocks until the debuggee stops and returns the new state
17
-
18
- ## Architecture
19
-
20
- ```
21
- ┌──────────────────────────────────────────────────┐
22
- │ MCP Server (Node.js) │
23
- │ │
24
- │ ┌──────────┐ ┌─────────────────────────────┐ │
25
- │ │ Adapter │ │ Session Manager │ │
26
- │ │ Registry │ │ │ │
27
- │ │ │ │ Session ──► DAP Client ─────┼───┼──► adapter (child process)
28
- │ │ - python │ │ • state (running/stopped) │ │ (stdin/stdout)
29
- │ │ - node │ │ • breakpoints map │ │
30
- │ │ - go │ │ • output ring buffer │ │
31
- │ │ - cppdbg │ │ • event queue │ │
32
- │ │ - custom │ │ • focused thread │ │
33
- │ └──────────┘ └─────────────────────────────┘ │
34
- │ │
35
- │ ┌───────────────────────────────────────────┐ │
36
- │ │ MCP Layer (stdio transport) │ │
37
- │ │ - 12 Tool handlers │ │
38
- │ │ - Resource: dap://sessions │ │
39
- │ └───────────────────────────────────────────┘ │
40
- └──────────────────────────────────────────────────┘
41
- ```
42
-
43
- ### Components
44
-
45
- 1. **Adapter Registry** — Stores adapter configurations. Each config: `type`, `runtime` (optional), `program` (path to adapter binary), `args`, `launchDefaults`. Built-in defaults for common adapters. Persisted to `~/.dap-mcp/adapters.json` (global) and `./.dap-mcp/adapters.json` (project-local).
46
-
47
- 2. **Session Manager** — Manages active debug sessions. Each session owns a `DAPClient`, tracks state (`idle | configuring | running | stopped | terminated`), maintains breakpoints map, buffers output in a ring buffer (10,000 lines max), and handles adapter crash detection.
48
-
49
- 3. **DAP Client** — Low-level protocol handler. Spawns adapter child process, sends/receives DAP messages with `Content-Length` framing, correlates request/response by `seq`, emits events to the session. Includes startup timeout (10s default).
50
-
51
- 4. **MCP Layer** — Registers tools, handles tool calls, serves the `dap://sessions` resource.
52
-
53
- ## Tools (12)
54
-
55
- ### Session Lifecycle
56
-
57
- #### `debug_launch`
58
- Start a new debug session by launching a program.
59
-
60
- ```typescript
61
- Input: {
62
- adapter: string, // "python" | "node" | "go" | "cppdbg" | custom
63
- program: string,
64
- args?: string[],
65
- cwd?: string,
66
- env?: Record<string, string>,
67
- stopOnEntry?: boolean, // default: true
68
- breakpoints?: Array<{
69
- file: string,
70
- lines: Array<{
71
- line: number,
72
- condition?: string,
73
- hitCondition?: string,
74
- logMessage?: string
75
- }>
76
- }>,
77
- exceptionBreakpoints?: string[], // e.g., ["uncaught"]
78
- adapterConfig?: Record<string, any> // pass-through to adapter
79
- }
80
- Output: { sessionId: string, state: StoppedState | RunningState }
81
- ```
82
-
83
- #### `debug_attach`
84
- Attach to a running process.
85
-
86
- ```typescript
87
- Input: {
88
- adapter: string,
89
- processId?: number,
90
- host?: string,
91
- port?: number,
92
- adapterConfig?: Record<string, any>
93
- }
94
- Output: { sessionId: string, state: StoppedState | RunningState }
95
- ```
96
-
97
- #### `debug_restart`
98
- Restart the current debug session with the same configuration.
99
-
100
- ```typescript
101
- Input: { sessionId?: string }
102
- Output: { sessionId: string, state: StoppedState | RunningState }
103
- ```
104
-
105
- #### `debug_disconnect`
106
- End a debug session.
107
-
108
- ```typescript
109
- Input: {
110
- sessionId?: string,
111
- terminateDebuggee?: boolean // default: true for launch, false for attach
112
- }
113
- Output: { success: boolean }
114
- ```
115
-
116
- ### Breakpoints
117
-
118
- #### `set_breakpoints`
119
- Set or replace breakpoints in a source file. Replaces all breakpoints in the specified file (DAP semantics).
120
-
121
- ```typescript
122
- Input: {
123
- sessionId?: string,
124
- file: string,
125
- breakpoints: Array<{
126
- line: number,
127
- condition?: string,
128
- hitCondition?: string,
129
- logMessage?: string
130
- }>
131
- }
132
- Output: {
133
- breakpoints: Array<{
134
- id: number,
135
- verified: boolean,
136
- line: number,
137
- message?: string
138
- }>
139
- }
140
- ```
141
-
142
- #### `set_exception_breakpoints`
143
- Configure which exceptions cause the debugger to break.
144
-
145
- ```typescript
146
- Input: {
147
- sessionId?: string,
148
- filters: string[] // adapter-specific, e.g., ["uncaught", "raised"]
149
- }
150
- Output: { filters: string[] }
151
- ```
152
-
153
- ### State Inspection
154
-
155
- #### `get_state`
156
- Get current debuggee state. When stopped: threads + stack trace + scopes + variables. When running: status + buffered output.
157
-
158
- ```typescript
159
- Input: {
160
- sessionId?: string,
161
- threadId?: number, // default: thread that triggered stop
162
- depth?: number, // stack frames to return, default 10
163
- variableDepth?: number, // nested expansion depth, default 1
164
- timeout?: number // ms to wait if running, default 0
165
- }
166
- Output: StoppedState | RunningState
167
- ```
168
-
169
- #### `evaluate`
170
- Evaluate an expression in the debuggee's context.
171
-
172
- ```typescript
173
- Input: {
174
- sessionId?: string,
175
- expression: string,
176
- frameId?: number, // default: top frame
177
- context?: "repl" | "watch" | "hover" // default: "repl"
178
- }
179
- Output: {
180
- result: string,
181
- type?: string,
182
- hasChildren: boolean,
183
- variablesReference: number
184
- }
185
- ```
186
-
187
- #### `get_output`
188
- Get buffered program output.
189
-
190
- ```typescript
191
- Input: {
192
- sessionId?: string,
193
- category?: "stdout" | "stderr" | "console", // default: all
194
- clear?: boolean // clear buffer after reading, default false
195
- }
196
- Output: {
197
- output: Array<{ category: string, text: string, timestamp: string }>,
198
- truncated: boolean
199
- }
200
- ```
201
-
202
- ### Execution Control
203
-
204
- #### `step`
205
- Control execution. Synchronous: blocks until debuggee stops or timeout.
206
-
207
- ```typescript
208
- Input: {
209
- sessionId?: string,
210
- action: "continue" | "next" | "stepIn" | "stepOut" | "pause",
211
- threadId?: number,
212
- timeout?: number // ms, default 30000
213
- }
214
- Output: StoppedState | { status: "running", elapsedMs: number }
215
- ```
216
-
217
- ### Adapter Management
218
-
219
- #### `configure_adapter`
220
- Register or update a debug adapter configuration.
221
-
222
- ```typescript
223
- Input: {
224
- type: string, // adapter identifier
225
- runtime?: string, // e.g., "node", "python3"
226
- program: string, // path to adapter binary/script
227
- args?: string[],
228
- launchDefaults?: Record<string, any>,
229
- scope?: "global" | "project" // default: "project"
230
- }
231
- Output: { success: boolean }
232
- ```
233
-
234
- #### `list_adapters`
235
- List available debug adapter configurations with availability status.
236
-
237
- ```typescript
238
- Input: {}
239
- Output: {
240
- adapters: Array<{
241
- type: string,
242
- source: "builtin" | "global" | "project",
243
- available: boolean, // binary exists on system
244
- program: string,
245
- installHint?: string // e.g., "pip install debugpy"
246
- }>
247
- }
248
- ```
249
-
250
- ## Common Response Types
251
-
252
- ```typescript
253
- interface StoppedState {
254
- status: "stopped";
255
- reason: "breakpoint" | "step" | "exception" | "pause" | "entry";
256
- location: {
257
- file: string;
258
- line: number;
259
- column?: number;
260
- functionName?: string;
261
- };
262
- threads: Array<{ id: number; name: string; stopped: boolean }>;
263
- stackTrace: Array<{
264
- id: number;
265
- name: string;
266
- file: string;
267
- line: number;
268
- column?: number;
269
- }>;
270
- scopes: Array<{
271
- name: string;
272
- variables: Array<{
273
- name: string;
274
- value: string;
275
- type?: string;
276
- hasChildren: boolean;
277
- variablesReference: number;
278
- }>;
279
- }>;
280
- output?: string[];
281
- }
282
-
283
- interface RunningState {
284
- status: "running";
285
- output?: string[];
286
- }
287
- ```
288
-
289
- ## Built-in Adapter Defaults
290
-
291
- | Type | Adapter | Detection | Install Hint |
292
- |---|---|---|---|
293
- | `python` | debugpy | `python3 -c "import debugpy"` | `pip install debugpy` |
294
- | `node` | js-debug-dap | `which js-debug-dap` or bundled | Ships with MCP |
295
- | `go` | delve | `which dlv` | `go install github.com/go-delve/delve/cmd/dlv@latest` |
296
- | `cppdbg` | lldb-dap | `which lldb-dap` | `apt install lldb` / `brew install llvm` |
297
-
298
- ## Error Handling
299
-
300
- All execution errors use MCP's `isError: true` in tool results (not JSON-RPC protocol errors), so the AI can read and self-correct.
301
-
302
- | Scenario | Behavior |
303
- |---|---|
304
- | Adapter binary not found | `isError: true` with install instructions |
305
- | Adapter crash (child exit) | Session marked `terminated`, stderr in error message |
306
- | DAP protocol error | Adapter's error message surfaced verbatim |
307
- | Timeout on step/continue | Return `{ status: "running", elapsedMs }` — not an error |
308
- | Invalid session ID | Error listing available sessions |
309
- | Expression eval failure | Adapter's error message (e.g., "NameError: ...") |
310
-
311
- ## MCP Resource
312
-
313
- - `dap://sessions` — List of active sessions with status summary. Subscribable (emits `notifications/resources/updated` on session state changes).
314
-
315
- ## Config Files
316
-
317
- - `~/.dap-mcp/adapters.json` — Global adapter configurations
318
- - `./.dap-mcp/adapters.json` — Project-local adapter overrides (takes precedence)
319
-
320
- ## Key Design Principles
321
-
322
- 1. **One call, maximum info**: Composite responses (stack + variables + threads) reduce round-trips
323
- 2. **Smart defaults**: Auto-select single session, auto-select stopped thread, `stopOnEntry: true`
324
- 3. **Errors are information**: Execution errors in results (not protocol errors) let the AI self-correct
325
- 4. **Bounded resources**: Output ring buffer (10K lines), variable depth limits, stack frame limits
326
- 5. **Crash resilience**: Adapter process monitoring with clear error reporting