dnd-mcp 0.1.0

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 (100) hide show
  1. package/bin/ClrDebug.dll +0 -0
  2. package/bin/DnD.Core.dll +0 -0
  3. package/bin/DnD.Core.pdb +0 -0
  4. package/bin/DnD.Host.deps.json +440 -0
  5. package/bin/DnD.Host.dll +0 -0
  6. package/bin/DnD.Host.exe +0 -0
  7. package/bin/DnD.Host.pdb +0 -0
  8. package/bin/DnD.Host.runtimeconfig.json +13 -0
  9. package/bin/DnD.Protocol.dll +0 -0
  10. package/bin/DnD.Protocol.pdb +0 -0
  11. package/bin/MessagePack.Annotations.dll +0 -0
  12. package/bin/MessagePack.dll +0 -0
  13. package/bin/Microsoft.NET.StringTools.dll +0 -0
  14. package/bin/Microsoft.VisualStudio.Threading.dll +0 -0
  15. package/bin/Microsoft.VisualStudio.Validation.dll +0 -0
  16. package/bin/Nerdbank.MessagePack.dll +0 -0
  17. package/bin/Nerdbank.Streams.dll +0 -0
  18. package/bin/Newtonsoft.Json.dll +0 -0
  19. package/bin/PolyType.dll +0 -0
  20. package/bin/StreamJsonRpc.dll +0 -0
  21. package/bin/System.Collections.Immutable.dll +0 -0
  22. package/bin/System.IO.Pipelines.dll +0 -0
  23. package/bin/System.Reflection.Metadata.dll +0 -0
  24. package/bin/cs/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  25. package/bin/cs/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  26. package/bin/cs/StreamJsonRpc.resources.dll +0 -0
  27. package/bin/de/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  28. package/bin/de/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  29. package/bin/de/StreamJsonRpc.resources.dll +0 -0
  30. package/bin/es/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  31. package/bin/es/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  32. package/bin/es/StreamJsonRpc.resources.dll +0 -0
  33. package/bin/fr/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  34. package/bin/fr/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  35. package/bin/fr/StreamJsonRpc.resources.dll +0 -0
  36. package/bin/it/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  37. package/bin/it/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  38. package/bin/it/StreamJsonRpc.resources.dll +0 -0
  39. package/bin/ja/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  40. package/bin/ja/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  41. package/bin/ja/StreamJsonRpc.resources.dll +0 -0
  42. package/bin/ko/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  43. package/bin/ko/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  44. package/bin/ko/StreamJsonRpc.resources.dll +0 -0
  45. package/bin/pl/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  46. package/bin/pl/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  47. package/bin/pl/StreamJsonRpc.resources.dll +0 -0
  48. package/bin/pt-BR/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  49. package/bin/pt-BR/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  50. package/bin/pt-BR/StreamJsonRpc.resources.dll +0 -0
  51. package/bin/ru/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  52. package/bin/ru/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  53. package/bin/ru/StreamJsonRpc.resources.dll +0 -0
  54. package/bin/runtimes/win-x64/native/dbgshim.dll +0 -0
  55. package/bin/tr/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  56. package/bin/tr/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  57. package/bin/tr/StreamJsonRpc.resources.dll +0 -0
  58. package/bin/zh-Hans/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  59. package/bin/zh-Hans/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  60. package/bin/zh-Hans/StreamJsonRpc.resources.dll +0 -0
  61. package/bin/zh-Hant/Microsoft.VisualStudio.Threading.resources.dll +0 -0
  62. package/bin/zh-Hant/Microsoft.VisualStudio.Validation.resources.dll +0 -0
  63. package/bin/zh-Hant/StreamJsonRpc.resources.dll +0 -0
  64. package/dist/client-manager.d.ts +39 -0
  65. package/dist/client-manager.d.ts.map +1 -0
  66. package/dist/client-manager.js +150 -0
  67. package/dist/client-manager.js.map +1 -0
  68. package/dist/debugger-client.d.ts +39 -0
  69. package/dist/debugger-client.d.ts.map +1 -0
  70. package/dist/debugger-client.js +135 -0
  71. package/dist/debugger-client.js.map +1 -0
  72. package/dist/index.d.ts +3 -0
  73. package/dist/index.d.ts.map +1 -0
  74. package/dist/index.js +31 -0
  75. package/dist/index.js.map +1 -0
  76. package/dist/tools/breakpoints.d.ts +4 -0
  77. package/dist/tools/breakpoints.d.ts.map +1 -0
  78. package/dist/tools/breakpoints.js +108 -0
  79. package/dist/tools/breakpoints.js.map +1 -0
  80. package/dist/tools/execution.d.ts +18 -0
  81. package/dist/tools/execution.d.ts.map +1 -0
  82. package/dist/tools/execution.js +215 -0
  83. package/dist/tools/execution.js.map +1 -0
  84. package/dist/tools/inspection.d.ts +4 -0
  85. package/dist/tools/inspection.d.ts.map +1 -0
  86. package/dist/tools/inspection.js +123 -0
  87. package/dist/tools/inspection.js.map +1 -0
  88. package/dist/tools/process.d.ts +4 -0
  89. package/dist/tools/process.d.ts.map +1 -0
  90. package/dist/tools/process.js +114 -0
  91. package/dist/tools/process.js.map +1 -0
  92. package/dist/types/protocol.d.ts +133 -0
  93. package/dist/types/protocol.d.ts.map +1 -0
  94. package/dist/types/protocol.js +3 -0
  95. package/dist/types/protocol.js.map +1 -0
  96. package/dist/types/rpc-methods.d.ts +24 -0
  97. package/dist/types/rpc-methods.d.ts.map +1 -0
  98. package/dist/types/rpc-methods.js +25 -0
  99. package/dist/types/rpc-methods.js.map +1 -0
  100. package/package.json +47 -0
@@ -0,0 +1,150 @@
1
+ import { resolve, dirname, join } from "node:path";
2
+ import { homedir, tmpdir } from "node:os";
3
+ import { createWriteStream, existsSync, unlinkSync, } from "node:fs";
4
+ import { randomBytes } from "node:crypto";
5
+ import { fileURLToPath } from "node:url";
6
+ import { DebuggerClient } from "./debugger-client.js";
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ function resolveHostPath() {
9
+ // 1. Environment variable (development override)
10
+ if (process.env.DND_HOST_PATH) {
11
+ return process.env.DND_HOST_PATH;
12
+ }
13
+ // 2. Bundled binary (npm package)
14
+ const bundledPath = resolve(__dirname, "../bin/DnD.Host.dll");
15
+ if (existsSync(bundledPath)) {
16
+ return bundledPath;
17
+ }
18
+ // 3. dotnet global tool
19
+ const toolPath = join(homedir(), ".dotnet", "tools", "dnd-host.exe");
20
+ if (existsSync(toolPath)) {
21
+ return toolPath;
22
+ }
23
+ throw new Error("DnD.Host not found. Install with: dotnet tool install -g DnD.Host, or set DND_HOST_PATH environment variable.");
24
+ }
25
+ export class ClientManager {
26
+ client = null;
27
+ hostPath;
28
+ stubMode;
29
+ // Output file (D1)
30
+ outputFilePath = null;
31
+ outputStream = null;
32
+ // State tracking (F1)
33
+ _state = "not-started";
34
+ _lastStopped = null;
35
+ _lastExitCode = null;
36
+ constructor(options) {
37
+ this.hostPath = options?.hostPath ?? resolveHostPath();
38
+ this.stubMode = options?.stub ?? false;
39
+ }
40
+ get state() {
41
+ return this._state;
42
+ }
43
+ get outputFile() {
44
+ return this.outputFilePath;
45
+ }
46
+ get hostPid() {
47
+ return this.client?.hostPid ?? null;
48
+ }
49
+ getStateSnapshot() {
50
+ const snap = { state: this._state };
51
+ if (this._state === "stopped" && this._lastStopped) {
52
+ snap.stopReason = this._lastStopped.reason;
53
+ snap.stopDescription = this._lastStopped.description;
54
+ snap.threadId = this._lastStopped.threadId;
55
+ snap.breakpointId = this._lastStopped.breakpointId;
56
+ }
57
+ if (this._state === "exited" && this._lastExitCode != null) {
58
+ snap.exitCode = this._lastExitCode;
59
+ }
60
+ if (this.outputFilePath) {
61
+ snap.outputFile = this.outputFilePath;
62
+ }
63
+ return snap;
64
+ }
65
+ async ensureClient() {
66
+ if (this.client?.isConnected && this._state !== "exited") {
67
+ return this.client;
68
+ }
69
+ // Dispose old client (may still be connected if debuggee exited but Host is alive)
70
+ if (this.client) {
71
+ await this.client.dispose();
72
+ this.client = null;
73
+ }
74
+ // Close output stream from previous session
75
+ if (this.outputStream) {
76
+ this.outputStream.end();
77
+ this.outputStream = null;
78
+ }
79
+ // Clean up previous output file from last session
80
+ this.cleanupOutputFile();
81
+ const args = this.stubMode ? ["--stub"] : [];
82
+ this.client = new DebuggerClient(this.hostPath, args);
83
+ await this.client.start();
84
+ // Create output file
85
+ const id = randomBytes(4).toString("hex");
86
+ this.outputFilePath = join(tmpdir(), `dnd-output-${id}.log`);
87
+ this.outputStream = createWriteStream(this.outputFilePath, { flags: "a" });
88
+ // Wire events for output file and state tracking
89
+ this.client.on("output", (params) => {
90
+ if (this.outputStream) {
91
+ this.outputStream.write(params.output);
92
+ }
93
+ });
94
+ this.client.on("stopped", (params) => {
95
+ this._state = "stopped";
96
+ this._lastStopped = params;
97
+ });
98
+ this.client.on("exited", (params) => {
99
+ this._state = "exited";
100
+ this._lastExitCode = params.exitCode;
101
+ });
102
+ this._state = "not-started";
103
+ this._lastStopped = null;
104
+ this._lastExitCode = null;
105
+ return this.client;
106
+ }
107
+ /** Mark state as running (called after launch/attach/continue/step) */
108
+ markRunning() {
109
+ this._state = "running";
110
+ }
111
+ getClient() {
112
+ if (!this.client?.isConnected) {
113
+ throw new Error("No active debugger connection. Call launch or attach first.");
114
+ }
115
+ return this.client;
116
+ }
117
+ async dispose() {
118
+ // Close output stream but keep the file for LLM to read later
119
+ if (this.outputStream) {
120
+ this.outputStream.end();
121
+ this.outputStream = null;
122
+ }
123
+ if (this.client) {
124
+ await this.client.dispose();
125
+ this.client = null;
126
+ }
127
+ // Keep outputFilePath and state so getState/Read can still access them after exit
128
+ }
129
+ /** Clean up output file — called when starting a new session or on shutdown */
130
+ cleanupOutputFile() {
131
+ if (this.outputFilePath) {
132
+ try {
133
+ unlinkSync(this.outputFilePath);
134
+ }
135
+ catch {
136
+ /* ignore */
137
+ }
138
+ this.outputFilePath = null;
139
+ }
140
+ this._state = "not-started";
141
+ this._lastStopped = null;
142
+ this._lastExitCode = null;
143
+ }
144
+ /** Full cleanup including output file — for MCP server shutdown */
145
+ async shutdown() {
146
+ await this.dispose();
147
+ this.cleanupOutputFile();
148
+ }
149
+ }
150
+ //# sourceMappingURL=client-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-manager.js","sourceRoot":"","sources":["../src/client-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { EventEmitter } from "node:events";
2
+ import type { LaunchParams, LaunchResult, AttachParams, AttachResult, ContinueParams, StepInParams, StepOverParams, StepOutParams, SetBreakpointParams, SetBreakpointResult, RemoveBreakpointParams, GetBreakpointsResult, SetExceptionBreakpointsParams, SetExceptionBreakpointsResult, GetStackTraceParams, GetStackTraceResult, GetVariablesParams, GetVariablesResult, EvaluateParams, EvaluateResult, GetThreadsResult, GetExceptionParams, GetExceptionResult, StoppedParams, ExitedParams, OutputParams } from "./types/protocol.js";
3
+ export interface DebuggerClientEvents {
4
+ stopped: [StoppedParams];
5
+ exited: [ExitedParams];
6
+ output: [OutputParams];
7
+ error: [Error];
8
+ }
9
+ export declare class DebuggerClient extends EventEmitter<DebuggerClientEvents> {
10
+ private process;
11
+ private connection;
12
+ private readonly hostPath;
13
+ private readonly hostArgs;
14
+ constructor(hostPath: string, hostArgs?: string[]);
15
+ start(): Promise<void>;
16
+ launch(params: LaunchParams): Promise<LaunchResult>;
17
+ attach(params: AttachParams): Promise<AttachResult>;
18
+ detach(): Promise<void>;
19
+ terminate(): Promise<void>;
20
+ pause(): Promise<void>;
21
+ continue(params: ContinueParams): Promise<void>;
22
+ stepIn(params: StepInParams): Promise<void>;
23
+ stepOver(params: StepOverParams): Promise<void>;
24
+ stepOut(params: StepOutParams): Promise<void>;
25
+ setBreakpoint(params: SetBreakpointParams): Promise<SetBreakpointResult>;
26
+ removeBreakpoint(params: RemoveBreakpointParams): Promise<void>;
27
+ getBreakpoints(): Promise<GetBreakpointsResult>;
28
+ setExceptionBreakpoints(params: SetExceptionBreakpointsParams): Promise<SetExceptionBreakpointsResult>;
29
+ getStackTrace(params: GetStackTraceParams): Promise<GetStackTraceResult>;
30
+ getVariables(params: GetVariablesParams): Promise<GetVariablesResult>;
31
+ evaluate(params: EvaluateParams): Promise<EvaluateResult>;
32
+ getThreads(): Promise<GetThreadsResult>;
33
+ getException(params: GetExceptionParams): Promise<GetExceptionResult>;
34
+ dispose(): Promise<void>;
35
+ get hostPid(): number | null;
36
+ get isConnected(): boolean;
37
+ private sendRequest;
38
+ }
39
+ //# sourceMappingURL=debugger-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debugger-client.d.ts","sourceRoot":"","sources":["../src/debugger-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA0B3C,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,6BAA6B,EAC7B,6BAA6B,EAC7B,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,YAAY,EACb,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,CAAC,aAAa,CAAC,CAAC;IACzB,MAAM,EAAE,CAAC,YAAY,CAAC,CAAC;IACvB,MAAM,EAAE,CAAC,YAAY,CAAC,CAAC;IACvB,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;CAChB;AAED,qBAAa,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IACpE,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,UAAU,CAAsC;IACxD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;gBAExB,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,EAAO;IAM/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA6CtB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAInD,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAInD,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAM1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7C,aAAa,CACjB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC;IAIzB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D,cAAc,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAI/C,uBAAuB,CAC3B,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,6BAA6B,CAAC;IAMnC,aAAa,CACjB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC;IAIzB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAIrE,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAIzD,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAIvC,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAMrE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAW9B,IAAI,OAAO,IAAI,MAAM,GAAG,IAAI,CAE3B;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAID,OAAO,CAAC,WAAW;CAcpB"}
@@ -0,0 +1,135 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { spawn } from "node:child_process";
3
+ import * as rpc from "vscode-jsonrpc/node.js";
4
+ import { LaunchRequest, AttachRequest, DetachRequest, TerminateRequest, ContinueRequest, PauseRequest, StepInRequest, StepOverRequest, StepOutRequest, SetBreakpointRequest, RemoveBreakpointRequest, GetBreakpointsRequest, SetExceptionBreakpointsRequest, GetStackTraceRequest, GetVariablesRequest, EvaluateRequest, GetThreadsRequest, GetExceptionRequest, StoppedNotification, ExitedNotification, OutputNotification, } from "./types/rpc-methods.js";
5
+ export class DebuggerClient extends EventEmitter {
6
+ process = null;
7
+ connection = null;
8
+ hostPath;
9
+ hostArgs;
10
+ constructor(hostPath, hostArgs = []) {
11
+ super();
12
+ this.hostPath = hostPath;
13
+ this.hostArgs = hostArgs;
14
+ }
15
+ async start() {
16
+ const isDll = this.hostPath.endsWith(".dll");
17
+ const command = isDll ? "dotnet" : this.hostPath;
18
+ const args = isDll
19
+ ? [this.hostPath, ...this.hostArgs, "--parentPid", process.pid.toString()]
20
+ : [...this.hostArgs, "--parentPid", process.pid.toString()];
21
+ this.process = spawn(command, args, {
22
+ stdio: ["pipe", "pipe", "pipe"],
23
+ });
24
+ this.process.stderr?.on("data", (data) => {
25
+ // DnD.Host writes diagnostic messages to stderr
26
+ process.stderr.write(`[DnD.Host] ${data.toString()}`);
27
+ });
28
+ this.process.on("error", (err) => {
29
+ this.emit("error", err);
30
+ });
31
+ this.process.on("exit", (code) => {
32
+ this.connection = null;
33
+ this.process = null;
34
+ });
35
+ const reader = new rpc.StreamMessageReader(this.process.stdout);
36
+ const writer = new rpc.StreamMessageWriter(this.process.stdin);
37
+ this.connection = rpc.createMessageConnection(reader, writer);
38
+ // Wire notifications
39
+ this.connection.onNotification(StoppedNotification, (params) => {
40
+ this.emit("stopped", params);
41
+ });
42
+ this.connection.onNotification(ExitedNotification, (params) => {
43
+ this.emit("exited", params);
44
+ });
45
+ this.connection.onNotification(OutputNotification, (params) => {
46
+ this.emit("output", params);
47
+ });
48
+ this.connection.listen();
49
+ }
50
+ // Process control
51
+ async launch(params) {
52
+ return this.sendRequest(LaunchRequest, params);
53
+ }
54
+ async attach(params) {
55
+ return this.sendRequest(AttachRequest, params);
56
+ }
57
+ async detach() {
58
+ return this.sendRequest(DetachRequest);
59
+ }
60
+ async terminate() {
61
+ return this.sendRequest(TerminateRequest);
62
+ }
63
+ // Execution control
64
+ async pause() {
65
+ return this.sendRequest(PauseRequest);
66
+ }
67
+ async continue(params) {
68
+ return this.sendRequest(ContinueRequest, params);
69
+ }
70
+ async stepIn(params) {
71
+ return this.sendRequest(StepInRequest, params);
72
+ }
73
+ async stepOver(params) {
74
+ return this.sendRequest(StepOverRequest, params);
75
+ }
76
+ async stepOut(params) {
77
+ return this.sendRequest(StepOutRequest, params);
78
+ }
79
+ // Breakpoints
80
+ async setBreakpoint(params) {
81
+ return this.sendRequest(SetBreakpointRequest, params);
82
+ }
83
+ async removeBreakpoint(params) {
84
+ return this.sendRequest(RemoveBreakpointRequest, params);
85
+ }
86
+ async getBreakpoints() {
87
+ return this.sendRequest(GetBreakpointsRequest);
88
+ }
89
+ async setExceptionBreakpoints(params) {
90
+ return this.sendRequest(SetExceptionBreakpointsRequest, params);
91
+ }
92
+ // Inspection
93
+ async getStackTrace(params) {
94
+ return this.sendRequest(GetStackTraceRequest, params);
95
+ }
96
+ async getVariables(params) {
97
+ return this.sendRequest(GetVariablesRequest, params);
98
+ }
99
+ async evaluate(params) {
100
+ return this.sendRequest(EvaluateRequest, params);
101
+ }
102
+ async getThreads() {
103
+ return this.sendRequest(GetThreadsRequest);
104
+ }
105
+ async getException(params) {
106
+ return this.sendRequest(GetExceptionRequest, params);
107
+ }
108
+ // Lifecycle
109
+ async dispose() {
110
+ if (this.connection) {
111
+ this.connection.dispose();
112
+ this.connection = null;
113
+ }
114
+ if (this.process) {
115
+ this.process.kill();
116
+ this.process = null;
117
+ }
118
+ }
119
+ get hostPid() {
120
+ return this.process?.pid ?? null;
121
+ }
122
+ get isConnected() {
123
+ return this.connection !== null && this.process !== null;
124
+ }
125
+ sendRequest(type, params) {
126
+ if (!this.connection) {
127
+ throw new Error("Not connected to DnD.Host");
128
+ }
129
+ if (params !== undefined) {
130
+ return this.connection.sendRequest(type, params);
131
+ }
132
+ return this.connection.sendRequest(type);
133
+ }
134
+ }
135
+ //# sourceMappingURL=debugger-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debugger-client.js","sourceRoot":"","sources":["../src/debugger-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { ClientManager } from "./client-manager.js";
5
+ import { registerProcessTools } from "./tools/process.js";
6
+ import { registerExecutionTools } from "./tools/execution.js";
7
+ import { registerBreakpointTools } from "./tools/breakpoints.js";
8
+ import { registerInspectionTools } from "./tools/inspection.js";
9
+ const server = new McpServer({
10
+ name: "dnd-debugger",
11
+ version: "0.1.0",
12
+ });
13
+ const clientManager = new ClientManager();
14
+ registerProcessTools(server, clientManager);
15
+ registerExecutionTools(server, clientManager);
16
+ registerBreakpointTools(server, clientManager);
17
+ registerInspectionTools(server, clientManager);
18
+ const transport = new StdioServerTransport();
19
+ await server.connect(transport);
20
+ // Cleanup on process exit
21
+ process.on("SIGINT", async () => {
22
+ await clientManager.shutdown();
23
+ await server.close();
24
+ process.exit(0);
25
+ });
26
+ process.on("SIGTERM", async () => {
27
+ await clientManager.shutdown();
28
+ await server.close();
29
+ process.exit(0);
30
+ });
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;AAE1C,oBAAoB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAC5C,sBAAsB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAC9C,uBAAuB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAC/C,uBAAuB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAE/C,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAEhC,0BAA0B;AAC1B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;IAC9B,MAAM,aAAa,CAAC,QAAQ,EAAE,CAAC;IAC/B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;IAC/B,MAAM,aAAa,CAAC,QAAQ,EAAE,CAAC;IAC/B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ClientManager } from "../client-manager.js";
3
+ export declare function registerBreakpointTools(server: McpServer, clientManager: ClientManager): void;
4
+ //# sourceMappingURL=breakpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breakpoints.d.ts","sourceRoot":"","sources":["../../src/tools/breakpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,aAAa,EAAE,aAAa,QAiI7B"}
@@ -0,0 +1,108 @@
1
+ import { z } from "zod";
2
+ export function registerBreakpointTools(server, clientManager) {
3
+ server.tool("setBreakpoint", "Set a breakpoint at a specific file and line. Can be called before or after launching. Supports optional condition (expression that must evaluate to true) and hit count (stop only after N hits).", {
4
+ file: z.string().describe("Absolute path to the source file"),
5
+ line: z.coerce.number().describe("Line number (1-based)"),
6
+ condition: z
7
+ .string()
8
+ .optional()
9
+ .describe("Condition expression — breakpoint only stops when this evaluates to true (e.g., 'x > 10')"),
10
+ hitCount: z.coerce
11
+ .number()
12
+ .optional()
13
+ .describe("Hit count — breakpoint only stops after being hit this many times"),
14
+ }, async (params) => {
15
+ const client = await clientManager.ensureClient();
16
+ const result = await client.setBreakpoint(params);
17
+ const bp = result.breakpoint;
18
+ const status = bp.verified
19
+ ? "verified"
20
+ : "pending — will activate when code is loaded";
21
+ const extras = [];
22
+ if (bp.condition)
23
+ extras.push(`condition: ${bp.condition}`);
24
+ if (bp.hitCount)
25
+ extras.push(`hitCount: ${bp.hitCount}`);
26
+ const suffix = extras.length > 0 ? ` [${extras.join(", ")}]` : "";
27
+ return {
28
+ content: [
29
+ {
30
+ type: "text",
31
+ text: `Breakpoint ${bp.id} set at ${bp.file}:${bp.line} (${status})${suffix}`,
32
+ },
33
+ ],
34
+ };
35
+ });
36
+ server.tool("removeBreakpoint", "Remove a previously set breakpoint by its ID.", {
37
+ breakpointId: z.coerce.number().describe("Breakpoint ID to remove"),
38
+ }, async (params) => {
39
+ const client = clientManager.getClient();
40
+ await client.removeBreakpoint(params);
41
+ return {
42
+ content: [
43
+ {
44
+ type: "text",
45
+ text: `Breakpoint ${params.breakpointId} removed`,
46
+ },
47
+ ],
48
+ };
49
+ });
50
+ server.tool("getBreakpoints", "List all currently set breakpoints.", async () => {
51
+ const client = clientManager.getClient();
52
+ const result = await client.getBreakpoints();
53
+ if (result.breakpoints.length === 0) {
54
+ return {
55
+ content: [{ type: "text", text: "No breakpoints set" }],
56
+ };
57
+ }
58
+ const lines = result.breakpoints.map((bp) => {
59
+ const status = bp.verified ? "verified" : "pending";
60
+ const extras = [];
61
+ if (bp.condition)
62
+ extras.push(`condition: ${bp.condition}`);
63
+ if (bp.hitCount)
64
+ extras.push(`hitCount: ${bp.hitCount}`);
65
+ const suffix = extras.length > 0 ? ` [${extras.join(", ")}]` : "";
66
+ return ` #${bp.id} ${bp.file}:${bp.line} (${status})${suffix}`;
67
+ });
68
+ return {
69
+ content: [
70
+ { type: "text", text: `Breakpoints:\n${lines.join("\n")}` },
71
+ ],
72
+ };
73
+ });
74
+ server.tool("setExceptionBreakpoints", "Configure when to break on exceptions. By default, only uncaught (unhandled) exceptions cause a stop. Use this to also break when exceptions are first thrown (before any catch handler runs), or to filter by exception type.", {
75
+ thrown: z
76
+ .boolean()
77
+ .optional()
78
+ .default(false)
79
+ .describe("Break when any exception is thrown (first-chance). Default: false"),
80
+ uncaught: z
81
+ .boolean()
82
+ .optional()
83
+ .default(true)
84
+ .describe("Break on unhandled exceptions. Default: true"),
85
+ types: z
86
+ .array(z.string())
87
+ .optional()
88
+ .describe("Only break on exceptions whose type name contains one of these strings (e.g., ['ArgumentException', 'InvalidOperation']). Applies to both thrown and uncaught."),
89
+ }, async (params) => {
90
+ const client = await clientManager.ensureClient();
91
+ const result = await client.setExceptionBreakpoints(params);
92
+ const parts = [];
93
+ if (result.thrown)
94
+ parts.push("thrown (first-chance)");
95
+ if (result.uncaught)
96
+ parts.push("uncaught (unhandled)");
97
+ if (parts.length === 0)
98
+ parts.push("none");
99
+ let text = `Exception breakpoints: ${parts.join(", ")}`;
100
+ if (result.types?.length) {
101
+ text += `\nType filter: ${result.types.join(", ")}`;
102
+ }
103
+ return {
104
+ content: [{ type: "text", text }],
105
+ };
106
+ });
107
+ }
108
+ //# sourceMappingURL=breakpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breakpoints.js","sourceRoot":"","sources":["../../src/tools/breakpoints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ClientManager } from "../client-manager.js";
3
+ import type { DebuggerClient } from "../debugger-client.js";
4
+ import type { StoppedParams, ExitedParams, StackFrame } from "../types/protocol.js";
5
+ interface StopEvent {
6
+ type: "stopped";
7
+ params: StoppedParams;
8
+ }
9
+ interface ExitEvent {
10
+ type: "exited";
11
+ params: ExitedParams;
12
+ }
13
+ export declare function waitForStopOrExit(client: DebuggerClient, timeoutMs?: number): Promise<StopEvent | ExitEvent>;
14
+ export declare function formatStoppedResponse(params: StoppedParams, topFrame: StackFrame | null): string;
15
+ export declare function formatExitedResponse(params: ExitedParams): string;
16
+ export declare function registerExecutionTools(server: McpServer, clientManager: ClientManager): void;
17
+ export {};
18
+ //# sourceMappingURL=execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/tools/execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,UAAU,EAEX,MAAM,sBAAsB,CAAC;AAI9B,UAAU,SAAS;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,cAAc,EACtB,SAAS,SAAqB,GAC7B,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CA6BhC;AAcD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,UAAU,GAAG,IAAI,GAC1B,MAAM,CAaR;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEjE;AAiCD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,EACjB,aAAa,EAAE,aAAa,QA0L7B"}