@dr-debug/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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Saswat Mohanty (https://github.com/SazWhatician)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # 🔌 @dr-debug/mcp
2
+
3
+ > **Model Context Protocol (MCP) Server & Docker Telemetry Bridge for Dr. Debug**
4
+ > Connects running browser tabs, frontend substrate errors, and backend Docker container logs directly to AI IDEs (Cursor, Claude Code, Antigravity, Windsurf, and VS Code).
5
+
6
+ [![npm version](https://img.shields.io/npm/v/@dr-debug/mcp.svg?color=blue)](https://www.npmjs.com/package/@dr-debug/mcp)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D18-green.svg)](https://nodejs.org/)
9
+
10
+ Created by **Saswat Mohanty** ([@SazWhatician](https://github.com/SazWhatician))
11
+ - **GitHub:** [https://github.com/SazWhatician/DebugCopilot](https://github.com/SazWhatician/DebugCopilot)
12
+ - **LinkedIn:** [https://www.linkedin.com/in/saswat-mohanty-0a4549331/](https://www.linkedin.com/in/saswat-mohanty-0a4549331/)
13
+
14
+ ---
15
+
16
+ ## ⚡ Instant Run (Zero Installation)
17
+
18
+ Run directly with `npx`:
19
+
20
+ ```bash
21
+ npx -y @dr-debug/mcp
22
+ ```
23
+
24
+ This boots the dual-mode bridge:
25
+ 1. **MCP STDIO Server**: Ready for Cursor, Claude Code, Antigravity, or VS Code.
26
+ 2. **Local HTTP/WebSocket Gateway** (`http://127.0.0.1:9999`): Streams real-time Docker container states and browser telemetry.
27
+
28
+ ---
29
+
30
+ ## 🛠️ Adding to Your AI Editor / IDE
31
+
32
+ ### 1. Claude Desktop / Claude Code (`claude_desktop_config.json`)
33
+
34
+ ```json
35
+ {
36
+ "mcpServers": {
37
+ "dr-debug": {
38
+ "command": "npx",
39
+ "args": ["-y", "@dr-debug/mcp"]
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ ### 2. Cursor IDE (`.cursor/mcp.json`)
46
+
47
+ ```json
48
+ {
49
+ "mcpServers": {
50
+ "dr-debug": {
51
+ "command": "npx",
52
+ "args": ["-y", "@dr-debug/mcp"]
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ ---
59
+
60
+ ## 🔬 MCP Tools Exposed
61
+
62
+ When connected, your AI coding agent has direct access to the following tools:
63
+
64
+ - `list_browser_tabs`: Discover active tabs with Dr. Debug instrumented.
65
+ - `get_browser_state`: Fetch the full `<debug_state>` snapshot (DOM anomalies, console errors, network failures).
66
+ - `get_recent_errors`: Query high-priority substrate and runtime exceptions.
67
+ - `get_network_log`: Inspect recent HTTP requests, status codes, and request/response payloads.
68
+ - `list_docker_containers`: Inspect local Docker containers, images, ports, and health statuses.
69
+ - `get_docker_logs`: Stream container standard output and standard error logs to correlate with browser errors.
70
+
71
+ ---
72
+
73
+ ## 📄 License
74
+
75
+ MIT © [Saswat Mohanty](https://github.com/SazWhatician)
@@ -0,0 +1,36 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { DockerContainerInfo, DockerLogEntry, LogLevel } from './types.js';
3
+ export interface DockerBridgeStatus {
4
+ isAvailable: boolean;
5
+ daemonRunning: boolean;
6
+ containerCount: number;
7
+ activeStreams: number;
8
+ error?: string;
9
+ }
10
+ export declare class DockerBridge extends EventEmitter {
11
+ private isAvailable;
12
+ private daemonRunning;
13
+ private containers;
14
+ private activeStreams;
15
+ private pollInterval?;
16
+ private logsBuffer;
17
+ private maxLogsBuffer;
18
+ private lastCheckError?;
19
+ constructor();
20
+ start(): Promise<void>;
21
+ checkDockerAvailability(): Promise<DockerBridgeStatus>;
22
+ refreshContainers(): Promise<DockerContainerInfo[]>;
23
+ private attachLogStream;
24
+ classifyLogLevel(msg: string, stream: 'stdout' | 'stderr'): LogLevel;
25
+ private startContainerPolling;
26
+ getContainers(): DockerContainerInfo[];
27
+ getLogs(options?: {
28
+ container?: string;
29
+ level?: LogLevel | 'all';
30
+ grep?: string;
31
+ tail?: number;
32
+ }): DockerLogEntry[];
33
+ getStatus(): DockerBridgeStatus;
34
+ stop(): void;
35
+ }
36
+ //# sourceMappingURL=DockerBridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DockerBridge.d.ts","sourceRoot":"","sources":["../src/DockerBridge.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE/E,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,OAAO,CAAA;IACpB,aAAa,EAAE,OAAO,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,qBAAa,YAAa,SAAQ,YAAY;IAC5C,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,YAAY,CAAC,CAAgB;IACrC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,cAAc,CAAC,CAAQ;;IAMlB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBtB,uBAAuB,IAAI,OAAO,CAAC,kBAAkB,CAAC;IA2CtD,iBAAiB,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAoEhE,OAAO,CAAC,eAAe;IAkEhB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ;IAwB3E,OAAO,CAAC,qBAAqB;IAOtB,aAAa,IAAI,mBAAmB,EAAE;IAItC,OAAO,CAAC,OAAO,CAAC,EAAE;QACvB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,KAAK,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAA;QACxB,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,GAAG,cAAc,EAAE;IAwBb,SAAS,IAAI,kBAAkB;IAU/B,IAAI,IAAI,IAAI;CAiBpB"}
@@ -0,0 +1,266 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { EventEmitter } from 'node:events';
3
+ export class DockerBridge extends EventEmitter {
4
+ isAvailable = false;
5
+ daemonRunning = false;
6
+ containers = new Map();
7
+ activeStreams = new Map();
8
+ pollInterval;
9
+ logsBuffer = [];
10
+ maxLogsBuffer = 500;
11
+ lastCheckError;
12
+ constructor() {
13
+ super();
14
+ }
15
+ async start() {
16
+ await this.checkDockerAvailability();
17
+ if (this.daemonRunning) {
18
+ await this.refreshContainers();
19
+ this.startContainerPolling(5000);
20
+ }
21
+ else {
22
+ // Recheck availability periodically in case Docker Desktop is booted up
23
+ this.pollInterval = setInterval(async () => {
24
+ await this.checkDockerAvailability();
25
+ if (this.daemonRunning) {
26
+ if (this.pollInterval)
27
+ clearInterval(this.pollInterval);
28
+ await this.refreshContainers();
29
+ this.startContainerPolling(5000);
30
+ }
31
+ }, 8000);
32
+ }
33
+ }
34
+ async checkDockerAvailability() {
35
+ return new Promise((resolve) => {
36
+ try {
37
+ const proc = spawn('docker', ['version', '--format', '{{.Server.Version}}']);
38
+ let stdout = '';
39
+ let stderr = '';
40
+ proc.stdout?.on('data', (d) => {
41
+ stdout += d.toString();
42
+ });
43
+ proc.stderr?.on('data', (d) => {
44
+ stderr += d.toString();
45
+ });
46
+ proc.on('error', (err) => {
47
+ this.isAvailable = false;
48
+ this.daemonRunning = false;
49
+ this.lastCheckError = `Docker CLI not found or failed: ${err.message}`;
50
+ resolve(this.getStatus());
51
+ });
52
+ proc.on('close', (code) => {
53
+ if (code === 0 && stdout.trim().length > 0) {
54
+ this.isAvailable = true;
55
+ this.daemonRunning = true;
56
+ this.lastCheckError = undefined;
57
+ }
58
+ else {
59
+ this.isAvailable = true; // CLI exists
60
+ this.daemonRunning = false; // Daemon is stopped
61
+ this.lastCheckError = stderr.trim() || 'Docker daemon is not running';
62
+ }
63
+ resolve(this.getStatus());
64
+ });
65
+ }
66
+ catch (err) {
67
+ this.isAvailable = false;
68
+ this.daemonRunning = false;
69
+ this.lastCheckError = err.message;
70
+ resolve(this.getStatus());
71
+ }
72
+ });
73
+ }
74
+ async refreshContainers() {
75
+ if (!this.daemonRunning)
76
+ return [];
77
+ return new Promise((resolve) => {
78
+ try {
79
+ const proc = spawn('docker', ['ps', '--format', '{{json .}}']);
80
+ let output = '';
81
+ proc.stdout?.on('data', (d) => {
82
+ output += d.toString();
83
+ });
84
+ proc.on('close', (code) => {
85
+ if (code === 0) {
86
+ const lines = output.split('\n').filter((l) => l.trim().length > 0);
87
+ const currentNames = new Set();
88
+ for (const line of lines) {
89
+ try {
90
+ const parsed = JSON.parse(line);
91
+ const name = parsed.Names || parsed.ID || 'unknown';
92
+ currentNames.add(name);
93
+ const info = {
94
+ id: parsed.ID,
95
+ name,
96
+ image: parsed.Image,
97
+ status: parsed.Status,
98
+ state: (parsed.State || 'running').toLowerCase(),
99
+ ports: parsed.Ports ? parsed.Ports.split(',').map((p) => p.trim()) : []
100
+ };
101
+ this.containers.set(name, info);
102
+ // Start streaming logs for this container if not already streaming
103
+ if (!this.activeStreams.has(name)) {
104
+ this.attachLogStream(name);
105
+ }
106
+ }
107
+ catch {
108
+ // Ignore parse errors on individual lines
109
+ }
110
+ }
111
+ // Cleanup streams for removed containers
112
+ for (const [name, stream] of this.activeStreams.entries()) {
113
+ if (!currentNames.has(name)) {
114
+ stream.kill();
115
+ this.activeStreams.delete(name);
116
+ this.containers.delete(name);
117
+ }
118
+ }
119
+ this.emit('containers', this.getContainers());
120
+ resolve(this.getContainers());
121
+ }
122
+ else {
123
+ resolve(this.getContainers());
124
+ }
125
+ });
126
+ proc.on('error', () => {
127
+ resolve(this.getContainers());
128
+ });
129
+ }
130
+ catch {
131
+ resolve(this.getContainers());
132
+ }
133
+ });
134
+ }
135
+ attachLogStream(containerName) {
136
+ if (this.activeStreams.has(containerName))
137
+ return;
138
+ try {
139
+ // Follow logs with 50 lines of initial history and timestamps
140
+ const proc = spawn('docker', ['logs', '--follow', '--tail', '50', '--timestamps', containerName]);
141
+ this.activeStreams.set(containerName, proc);
142
+ const handleLogLine = (line, stream) => {
143
+ if (!line.trim())
144
+ return;
145
+ let timestamp = Date.now();
146
+ let message = line.trim();
147
+ // Extract ISO timestamp if present
148
+ const isoMatch = message.match(/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z)\s+(.*)$/);
149
+ if (isoMatch) {
150
+ const parsed = Date.parse(isoMatch[1]);
151
+ if (!isNaN(parsed)) {
152
+ timestamp = parsed;
153
+ message = isoMatch[2];
154
+ }
155
+ }
156
+ const level = this.classifyLogLevel(message, stream);
157
+ const entry = {
158
+ id: `docker_${containerName}_${timestamp}_${Math.random().toString(36).slice(2, 7)}`,
159
+ containerName,
160
+ timestamp,
161
+ stream,
162
+ message,
163
+ level
164
+ };
165
+ if (this.logsBuffer.length >= this.maxLogsBuffer) {
166
+ this.logsBuffer.shift();
167
+ }
168
+ this.logsBuffer.push(entry);
169
+ this.emit('log', entry);
170
+ };
171
+ proc.stdout?.on('data', (d) => {
172
+ const lines = d.toString().split('\n');
173
+ lines.forEach((l) => handleLogLine(l, 'stdout'));
174
+ });
175
+ proc.stderr?.on('data', (d) => {
176
+ const lines = d.toString().split('\n');
177
+ lines.forEach((l) => handleLogLine(l, 'stderr'));
178
+ });
179
+ proc.on('close', () => {
180
+ this.activeStreams.delete(containerName);
181
+ });
182
+ proc.on('error', () => {
183
+ this.activeStreams.delete(containerName);
184
+ });
185
+ }
186
+ catch {
187
+ // Ignore spawn errors
188
+ }
189
+ }
190
+ classifyLogLevel(msg, stream) {
191
+ const upper = msg.toUpperCase();
192
+ if (stream === 'stderr' ||
193
+ upper.includes('FATAL') ||
194
+ upper.includes('PANIC') ||
195
+ upper.includes('ERROR') ||
196
+ upper.includes('EXCEPTION') ||
197
+ upper.includes('FAIL') ||
198
+ upper.includes('ERR_') ||
199
+ upper.includes('TRACEBACK') ||
200
+ upper.includes('CRITICAL')) {
201
+ return 'error';
202
+ }
203
+ if (upper.includes('WARN')) {
204
+ return 'warn';
205
+ }
206
+ if (upper.includes('DEBUG')) {
207
+ return 'log';
208
+ }
209
+ return 'info';
210
+ }
211
+ startContainerPolling(intervalMs = 5000) {
212
+ if (this.pollInterval)
213
+ clearInterval(this.pollInterval);
214
+ this.pollInterval = setInterval(() => {
215
+ this.refreshContainers();
216
+ }, intervalMs);
217
+ }
218
+ getContainers() {
219
+ return Array.from(this.containers.values());
220
+ }
221
+ getLogs(options) {
222
+ let result = [...this.logsBuffer];
223
+ if (options?.container && options.container !== 'all') {
224
+ const target = options.container.toLowerCase();
225
+ result = result.filter((l) => l.containerName.toLowerCase().includes(target));
226
+ }
227
+ if (options?.level && options.level !== 'all') {
228
+ result = result.filter((l) => l.level === options.level);
229
+ }
230
+ if (options?.grep) {
231
+ const q = options.grep.toLowerCase();
232
+ result = result.filter((l) => l.message.toLowerCase().includes(q));
233
+ }
234
+ if (options?.tail && options.tail > 0) {
235
+ result = result.slice(-options.tail);
236
+ }
237
+ return result;
238
+ }
239
+ getStatus() {
240
+ return {
241
+ isAvailable: this.isAvailable,
242
+ daemonRunning: this.daemonRunning,
243
+ containerCount: this.containers.size,
244
+ activeStreams: this.activeStreams.size,
245
+ error: this.lastCheckError
246
+ };
247
+ }
248
+ stop() {
249
+ if (this.pollInterval) {
250
+ clearInterval(this.pollInterval);
251
+ this.pollInterval = undefined;
252
+ }
253
+ for (const [name, stream] of this.activeStreams.entries()) {
254
+ try {
255
+ stream.kill();
256
+ }
257
+ catch {
258
+ // ignore
259
+ }
260
+ }
261
+ this.activeStreams.clear();
262
+ this.containers.clear();
263
+ this.logsBuffer = [];
264
+ }
265
+ }
266
+ //# sourceMappingURL=DockerBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DockerBridge.js","sourceRoot":"","sources":["../src/DockerBridge.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ import { DrDebugMCPServer } from './server.js';
3
+ const port = parseInt(process.env.DR_DEBUG_MCP_PORT || '9229', 10);
4
+ const server = new DrDebugMCPServer({ port });
5
+ console.log(`
6
+ ┌─────────────────────────────────────────────────────────────┐
7
+ │ 🩺 Dr. Debug Host Docker Bridge & MCP Daemon │
8
+ │ 👨‍💻 Created by Saswat Mohanty (@SazWhatician) │
9
+ │ 🔗 GitHub: https://github.com/SazWhatician │
10
+ │ 💼 LinkedIn: https://www.linkedin.com/in/saswat-mohanty/ │
11
+ └─────────────────────────────────────────────────────────────┘
12
+ `);
13
+ server
14
+ .start()
15
+ .then(() => {
16
+ console.log(`✅ Dr. Debug Daemon is active on port ${port}`);
17
+ console.log(`🐳 Host Docker Stream: http://localhost:${port}/docker/stream (SSE)`);
18
+ console.log(`🔌 Model Context Protocol: ws://localhost:${port}`);
19
+ console.log(`\n💡 Open your web app and click the "🐳 Docker" tab in Dr. Debug to view live container logs!`);
20
+ })
21
+ .catch((err) => {
22
+ console.error('❌ Failed to start Dr. Debug Daemon:', err.message);
23
+ process.exit(1);
24
+ });
25
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE9C,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,MAAM,EAAE,EAAE,CAAC,CAAA;AAClE,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;AAE7C,OAAO,CAAC,GAAG,CAAC;;;;;;;CAOX,CAAC,CAAA;AAEF,MAAM;KACH,KAAK,EAAE;KACP,IAAI,CAAC,GAAG,EAAE;IACT,OAAO,CAAC,GAAG,CAAC,wCAAwC,IAAI,EAAE,CAAC,CAAA;IAC3D,OAAO,CAAC,GAAG,CAAC,2CAA2C,IAAI,sBAAsB,CAAC,CAAA;IAClF,OAAO,CAAC,GAAG,CAAC,6CAA6C,IAAI,EAAE,CAAC,CAAA;IAChE,OAAO,CAAC,GAAG,CAAC,gGAAgG,CAAC,CAAA;AAC/G,CAAC,CAAC;KACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACb,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ export { DockerBridge, type DockerBridgeStatus } from './DockerBridge.js';
2
+ export { MCPResourceManager } from './resources.js';
3
+ export { DrDebugMCPServer, type DrDebugMCPServerOptions } from './server.js';
4
+ export { MCPToolManager } from './tools.js';
5
+ export { MCPTransport } from './transport.js';
6
+ export * from './types.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,cAAc,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { DockerBridge } from './DockerBridge.js';
2
+ export { MCPResourceManager } from './resources.js';
3
+ export { DrDebugMCPServer } from './server.js';
4
+ export { MCPToolManager } from './tools.js';
5
+ export { MCPTransport } from './transport.js';
6
+ export * from './types.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA2B,MAAM,mBAAmB,CAAA;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAgC,MAAM,aAAa,CAAA;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,cAAc,YAAY,CAAA"}
@@ -0,0 +1,6 @@
1
+ import type { BrowserTabTelemetry, MCPResource, MCPResourceContent } from './types.js';
2
+ export declare class MCPResourceManager {
3
+ static listResources(sessions: Map<string, BrowserTabTelemetry>): MCPResource[];
4
+ static readResource(uri: string, sessions: Map<string, BrowserTabTelemetry>): MCPResourceContent;
5
+ }
6
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEtF,qBAAa,kBAAkB;WACf,aAAa,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,GAAG,WAAW,EAAE;WA+CxE,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,GAAG,kBAAkB;CAqDxG"}
@@ -0,0 +1,94 @@
1
+ export class MCPResourceManager {
2
+ static listResources(sessions) {
3
+ const resources = [
4
+ {
5
+ uri: 'drdebug://state/live',
6
+ name: 'Live Debug State Snapshot',
7
+ mimeType: 'application/xml',
8
+ description: 'Real-time <debug_state> XML token snapshot across console, network, docker, memory, and causal graphs.'
9
+ },
10
+ {
11
+ uri: 'drdebug://console/errors',
12
+ name: 'Console Runtime Error Stream',
13
+ mimeType: 'application/json',
14
+ description: 'Active uncaught runtime errors, unhandled rejections, and demangled stack frames.'
15
+ },
16
+ {
17
+ uri: 'drdebug://network/failures',
18
+ name: 'Network HTTP Failures & 4xx/5xx',
19
+ mimeType: 'application/json',
20
+ description: 'Failed HTTP requests, status codes, request/response headers, and payloads.'
21
+ },
22
+ {
23
+ uri: 'drdebug://interactions/replay',
24
+ name: 'User Interaction Replay Sequence',
25
+ mimeType: 'text/plain',
26
+ description: 'Chronological list of user clicks, inputs, scrolls, and DOM mutations in the 30 seconds leading up to bugs.'
27
+ },
28
+ {
29
+ uri: 'drdebug://matrix/diagnostics',
30
+ name: '2D Substrate Diagnostics Matrix',
31
+ mimeType: 'application/json',
32
+ description: '2D grid aggregating error severity across Network, Console, Docker, and System substrates.'
33
+ }
34
+ ];
35
+ // Multi-tab dynamic resources
36
+ for (const [tabId, tab] of sessions.entries()) {
37
+ resources.push({
38
+ uri: `drdebug://tab/${tabId}/state`,
39
+ name: `Live State for [${tab.title || tab.url}]`,
40
+ mimeType: 'application/json',
41
+ description: `Browser tab ${tabId}: ${tab.url}`
42
+ });
43
+ }
44
+ return resources;
45
+ }
46
+ static readResource(uri, sessions) {
47
+ const defaultSession = Array.from(sessions.values())[0];
48
+ const state = defaultSession?.stateSnapshot || {};
49
+ if (uri === 'drdebug://state/live') {
50
+ return {
51
+ uri,
52
+ mimeType: 'application/xml',
53
+ text: state.serializedXml || '<debug_state><note>No active browser session connected.</note></debug_state>'
54
+ };
55
+ }
56
+ if (uri === 'drdebug://console/errors') {
57
+ const errors = (state.console?.entries || []).filter((e) => e.level === 'error');
58
+ return {
59
+ uri,
60
+ mimeType: 'application/json',
61
+ text: JSON.stringify(errors, null, 2)
62
+ };
63
+ }
64
+ if (uri === 'drdebug://network/failures') {
65
+ const failed = (state.network?.records || []).filter((r) => r.isFailed || (r.status && r.status >= 400));
66
+ return {
67
+ uri,
68
+ mimeType: 'application/json',
69
+ text: JSON.stringify(failed, null, 2)
70
+ };
71
+ }
72
+ if (uri === 'drdebug://interactions/replay') {
73
+ const replay = state.interactionsHuman || 'No interactions recorded.';
74
+ return {
75
+ uri,
76
+ mimeType: 'text/plain',
77
+ text: replay
78
+ };
79
+ }
80
+ if (uri === 'drdebug://matrix/diagnostics') {
81
+ return {
82
+ uri,
83
+ mimeType: 'application/json',
84
+ text: JSON.stringify(state.diagnosticMatrix || {}, null, 2)
85
+ };
86
+ }
87
+ return {
88
+ uri,
89
+ mimeType: 'text/plain',
90
+ text: `Resource "${uri}" not found.`
91
+ };
92
+ }
93
+ }
94
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { DockerBridge } from './DockerBridge.js';
2
+ import type { MCPRequest, MCPResponse } from './types.js';
3
+ export interface DrDebugMCPServerOptions {
4
+ port?: number;
5
+ enableDocker?: boolean;
6
+ }
7
+ export declare class DrDebugMCPServer {
8
+ private transport;
9
+ private dockerBridge;
10
+ private isRunning;
11
+ constructor(options?: DrDebugMCPServerOptions);
12
+ getDockerBridge(): DockerBridge;
13
+ start(): Promise<void>;
14
+ handleRequest(req: MCPRequest): Promise<MCPResponse>;
15
+ stop(): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAIhD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAEzD,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,SAAS,CAAQ;gBAEb,OAAO,GAAE,uBAA4B;IAK1C,eAAe,IAAI,YAAY;IAIzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAetB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAoEpD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAKnC"}
package/dist/server.js ADDED
@@ -0,0 +1,91 @@
1
+ import { DockerBridge } from './DockerBridge.js';
2
+ import { MCPResourceManager } from './resources.js';
3
+ import { MCPToolManager } from './tools.js';
4
+ import { MCPTransport } from './transport.js';
5
+ export class DrDebugMCPServer {
6
+ transport;
7
+ dockerBridge;
8
+ isRunning = false;
9
+ constructor(options = {}) {
10
+ this.dockerBridge = new DockerBridge();
11
+ this.transport = new MCPTransport(options.port || 9229, this.dockerBridge);
12
+ }
13
+ getDockerBridge() {
14
+ return this.dockerBridge;
15
+ }
16
+ async start() {
17
+ if (this.isRunning)
18
+ return;
19
+ // Start Docker bridge discovery in background
20
+ this.dockerBridge.start().catch((err) => {
21
+ console.warn('Docker bridge initialization warning:', err.message);
22
+ });
23
+ await this.transport.start(async (req) => {
24
+ return this.handleRequest(req);
25
+ });
26
+ this.isRunning = true;
27
+ }
28
+ async handleRequest(req) {
29
+ const { id, method, params } = req;
30
+ const sessions = this.transport.getSessions();
31
+ try {
32
+ // 1. Initialize Handshake
33
+ if (method === 'initialize') {
34
+ return {
35
+ jsonrpc: '2.0',
36
+ id,
37
+ result: {
38
+ protocolVersion: '2024-11-05',
39
+ capabilities: {
40
+ resources: { subscribe: true },
41
+ tools: {}
42
+ },
43
+ serverInfo: {
44
+ name: 'Dr. Debug Autonomous Observability MCP Server',
45
+ version: '0.1.0'
46
+ }
47
+ }
48
+ };
49
+ }
50
+ // 2. Resource listing
51
+ if (method === 'resources/list') {
52
+ const resources = MCPResourceManager.listResources(sessions);
53
+ return { jsonrpc: '2.0', id, result: { resources } };
54
+ }
55
+ // 3. Resource reading
56
+ if (method === 'resources/read') {
57
+ const content = MCPResourceManager.readResource(params.uri, sessions);
58
+ return { jsonrpc: '2.0', id, result: { contents: [content] } };
59
+ }
60
+ // 4. Tool listing
61
+ if (method === 'tools/list') {
62
+ const tools = MCPToolManager.listTools();
63
+ return { jsonrpc: '2.0', id, result: { tools } };
64
+ }
65
+ // 5. Tool execution
66
+ if (method === 'tools/call') {
67
+ const result = await MCPToolManager.callTool(params.name, params.arguments || {}, sessions, (cmd) => this.transport.sendCommandToBrowser(cmd));
68
+ return { jsonrpc: '2.0', id, result };
69
+ }
70
+ // Fallback for unrecognized methods
71
+ return {
72
+ jsonrpc: '2.0',
73
+ id,
74
+ error: { code: -32601, message: `Method not found: ${method}` }
75
+ };
76
+ }
77
+ catch (err) {
78
+ return {
79
+ jsonrpc: '2.0',
80
+ id,
81
+ error: { code: -32603, message: err.message || 'Internal MCP Server Error' }
82
+ };
83
+ }
84
+ }
85
+ async stop() {
86
+ this.dockerBridge.stop();
87
+ await this.transport.stop();
88
+ this.isRunning = false;
89
+ }
90
+ }
91
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { BrowserTabTelemetry, MCPToolDefinition } from './types.js';
2
+ export declare class MCPToolManager {
3
+ static listTools(): MCPToolDefinition[];
4
+ static callTool(name: string, args: any, sessions: Map<string, BrowserTabTelemetry>, sendCommand: (command: any) => Promise<any>): Promise<{
5
+ content: Array<{
6
+ type: string;
7
+ text: string;
8
+ }>;
9
+ isError?: boolean;
10
+ }>;
11
+ }
12
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAExE,qBAAa,cAAc;WACX,SAAS,IAAI,iBAAiB,EAAE;WAoE1B,QAAQ,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAC1C,WAAW,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GAC1C,OAAO,CAAC;QAAE,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAmDlF"}
package/dist/tools.js ADDED
@@ -0,0 +1,116 @@
1
+ export class MCPToolManager {
2
+ static listTools() {
3
+ return [
4
+ {
5
+ name: 'drdebug_get_diagnostics',
6
+ description: 'Returns the aggregated multi-substrate health status and active anomalies in the live browser application.',
7
+ inputSchema: {
8
+ type: 'object',
9
+ properties: {
10
+ tabId: {
11
+ type: 'string',
12
+ description: 'Optional browser tab ID (defaults to active tab).'
13
+ }
14
+ }
15
+ }
16
+ },
17
+ {
18
+ name: 'drdebug_inspect_request',
19
+ description: 'Fetches full HTTP request/response payloads, headers, timings, and curl reproduction command for an API call.',
20
+ inputSchema: {
21
+ type: 'object',
22
+ properties: {
23
+ requestId: {
24
+ type: 'string',
25
+ description: 'The unique request ID to inspect.'
26
+ }
27
+ },
28
+ required: ['requestId']
29
+ }
30
+ },
31
+ {
32
+ name: 'drdebug_inspect_error',
33
+ description: 'Inspects a recorded runtime exception or console error, returning demangled stack frames and file locations.',
34
+ inputSchema: {
35
+ type: 'object',
36
+ properties: {
37
+ errorId: {
38
+ type: 'string',
39
+ description: 'The unique error ID to inspect.'
40
+ }
41
+ },
42
+ required: ['errorId']
43
+ }
44
+ },
45
+ {
46
+ name: 'drdebug_get_interaction_replay',
47
+ description: 'Returns the chronological sequence of user clicks, inputs, scrolls, and navigations in the 30 seconds before errors.',
48
+ inputSchema: {
49
+ type: 'object',
50
+ properties: {}
51
+ }
52
+ },
53
+ {
54
+ name: 'drdebug_execute_script',
55
+ description: 'Evaluates a JavaScript expression in the live browser tab and returns the serialized result.',
56
+ inputSchema: {
57
+ type: 'object',
58
+ properties: {
59
+ expression: {
60
+ type: 'string',
61
+ description: 'JavaScript code expression to evaluate.'
62
+ }
63
+ },
64
+ required: ['expression']
65
+ }
66
+ }
67
+ ];
68
+ }
69
+ static async callTool(name, args, sessions, sendCommand) {
70
+ const defaultSession = Array.from(sessions.values())[0];
71
+ const state = defaultSession?.stateSnapshot || {};
72
+ if (name === 'drdebug_get_diagnostics') {
73
+ const summary = {
74
+ url: state.pageContext?.url || 'No active page connected',
75
+ title: state.pageContext?.title,
76
+ errorCount: (state.console?.entries || []).filter((e) => e.level === 'error').length,
77
+ failedRequests: (state.network?.records || []).filter((r) => r.isFailed).length,
78
+ memoryUsageMB: state.memory ? Math.round((state.memory.usedJSHeapSize || 0) / (1024 * 1024)) : undefined,
79
+ activeCorrelations: state.correlations?.length || 0,
80
+ matrix: state.diagnosticMatrix
81
+ };
82
+ return { content: [{ type: 'text', text: JSON.stringify(summary, null, 2) }] };
83
+ }
84
+ if (name === 'drdebug_inspect_request') {
85
+ const records = state.network?.records || [];
86
+ const req = records.find((r) => r.id === args.requestId || r.url.includes(args.requestId));
87
+ if (!req) {
88
+ return { content: [{ type: 'text', text: `Request "${args.requestId}" not found in recorded telemetry.` }], isError: true };
89
+ }
90
+ return { content: [{ type: 'text', text: JSON.stringify(req, null, 2) }] };
91
+ }
92
+ if (name === 'drdebug_inspect_error') {
93
+ const entries = state.console?.entries || [];
94
+ const err = entries.find((e) => e.id === args.errorId || e.message.includes(args.errorId));
95
+ if (!err) {
96
+ return { content: [{ type: 'text', text: `Error "${args.errorId}" not found in recorded telemetry.` }], isError: true };
97
+ }
98
+ return { content: [{ type: 'text', text: JSON.stringify(err, null, 2) }] };
99
+ }
100
+ if (name === 'drdebug_get_interaction_replay') {
101
+ const replay = state.interactionsHuman || 'No interactions recorded.';
102
+ return { content: [{ type: 'text', text: replay }] };
103
+ }
104
+ if (name === 'drdebug_execute_script') {
105
+ try {
106
+ const res = await sendCommand({ type: 'EVAL_SCRIPT', expression: args.expression });
107
+ return { content: [{ type: 'text', text: JSON.stringify(res, null, 2) }] };
108
+ }
109
+ catch (err) {
110
+ return { content: [{ type: 'text', text: `Failed to evaluate in browser: ${err.message}` }], isError: true };
111
+ }
112
+ }
113
+ return { content: [{ type: 'text', text: `Unknown tool: ${name}` }], isError: true };
114
+ }
115
+ }
116
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { BrowserTabTelemetry, MCPRequest, MCPResponse } from './types.js';
2
+ import type { DockerBridge } from './DockerBridge.js';
3
+ export declare class MCPTransport {
4
+ private server;
5
+ private port;
6
+ private sessions;
7
+ private dockerBridge?;
8
+ constructor(port?: number, dockerBridge?: DockerBridge);
9
+ setDockerBridge(dockerBridge: DockerBridge): void;
10
+ start(onRequest: (req: MCPRequest) => Promise<MCPResponse>, onStateUpdate?: (tabId: string, state: any) => void): Promise<void>;
11
+ sendCommandToBrowser(_command: any, _targetTabId?: string): Promise<any>;
12
+ getSessions(): Map<string, BrowserTabTelemetry>;
13
+ stop(): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,IAAI,CAAQ;IACpB,OAAO,CAAC,QAAQ,CAA8C;IAC9D,OAAO,CAAC,YAAY,CAAC,CAAc;gBAEvB,IAAI,SAAO,EAAE,YAAY,CAAC,EAAE,YAAY;IAK7C,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI;IAIjD,KAAK,CACV,SAAS,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,CAAC,EACpD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,GAClD,OAAO,CAAC,IAAI,CAAC;IA8LH,oBAAoB,CAAC,QAAQ,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAI9E,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC;IAI/C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAY7B"}
@@ -0,0 +1,203 @@
1
+ import * as http from 'node:http';
2
+ export class MCPTransport {
3
+ server = null;
4
+ port;
5
+ sessions = new Map();
6
+ dockerBridge;
7
+ constructor(port = 9229, dockerBridge) {
8
+ this.port = port;
9
+ this.dockerBridge = dockerBridge;
10
+ }
11
+ setDockerBridge(dockerBridge) {
12
+ this.dockerBridge = dockerBridge;
13
+ }
14
+ start(onRequest, onStateUpdate) {
15
+ return new Promise((resolve, reject) => {
16
+ try {
17
+ this.server = http.createServer(async (req, res) => {
18
+ // CORS headers for browser and IDE access
19
+ res.setHeader('Access-Control-Allow-Origin', '*');
20
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
21
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
22
+ if (req.method === 'OPTIONS') {
23
+ res.writeHead(204);
24
+ res.end();
25
+ return;
26
+ }
27
+ const url = req.url || '/';
28
+ // 1. Browser Telemetry Ingestion (POST /telemetry or POST /browser)
29
+ if (req.method === 'POST' && (url.startsWith('/telemetry') || url.startsWith('/browser'))) {
30
+ let body = '';
31
+ req.on('data', (chunk) => {
32
+ body += chunk;
33
+ });
34
+ req.on('end', () => {
35
+ try {
36
+ const msg = JSON.parse(body);
37
+ const tabId = msg.tabId || `tab_${Date.now()}`;
38
+ if (msg.state) {
39
+ this.sessions.set(tabId, {
40
+ tabId,
41
+ url: msg.state?.pageContext?.url || 'Unknown',
42
+ title: msg.state?.pageContext?.title || 'Unknown Page',
43
+ lastSeen: Date.now(),
44
+ stateSnapshot: msg.state
45
+ });
46
+ onStateUpdate?.(tabId, msg.state);
47
+ }
48
+ res.writeHead(200, { 'Content-Type': 'application/json' });
49
+ res.end(JSON.stringify({ status: 'ok', tabId }));
50
+ }
51
+ catch (err) {
52
+ res.writeHead(400, { 'Content-Type': 'application/json' });
53
+ res.end(JSON.stringify({ error: err.message }));
54
+ }
55
+ });
56
+ return;
57
+ }
58
+ // 2. MCP JSON-RPC Endpoint (POST / or POST /mcp)
59
+ if (req.method === 'POST') {
60
+ let body = '';
61
+ req.on('data', (chunk) => {
62
+ body += chunk;
63
+ });
64
+ req.on('end', async () => {
65
+ try {
66
+ const mcpReq = JSON.parse(body);
67
+ const mcpRes = await onRequest(mcpReq);
68
+ res.writeHead(200, { 'Content-Type': 'application/json' });
69
+ res.end(JSON.stringify(mcpRes));
70
+ }
71
+ catch (err) {
72
+ res.writeHead(200, { 'Content-Type': 'application/json' });
73
+ res.end(JSON.stringify({
74
+ jsonrpc: '2.0',
75
+ id: null,
76
+ error: { code: -32700, message: err.message || 'Parse error' }
77
+ }));
78
+ }
79
+ });
80
+ return;
81
+ }
82
+ // 3. Docker Endpoints
83
+ if (url.startsWith('/docker/')) {
84
+ if (!this.dockerBridge) {
85
+ res.writeHead(503, { 'Content-Type': 'application/json' });
86
+ res.end(JSON.stringify({ error: 'Docker bridge not initialized on MCP daemon' }));
87
+ return;
88
+ }
89
+ // A. Docker Status
90
+ if (url === '/docker/status') {
91
+ res.writeHead(200, { 'Content-Type': 'application/json' });
92
+ res.end(JSON.stringify(this.dockerBridge.getStatus()));
93
+ return;
94
+ }
95
+ // B. Docker Containers
96
+ if (url === '/docker/containers') {
97
+ await this.dockerBridge.refreshContainers();
98
+ res.writeHead(200, { 'Content-Type': 'application/json' });
99
+ res.end(JSON.stringify(this.dockerBridge.getContainers()));
100
+ return;
101
+ }
102
+ // C. Docker Logs Query
103
+ if (url.startsWith('/docker/logs')) {
104
+ try {
105
+ const parsedUrl = new URL(url, `http://localhost:${this.port}`);
106
+ const container = parsedUrl.searchParams.get('container') || undefined;
107
+ const level = parsedUrl.searchParams.get('level') || undefined;
108
+ const grep = parsedUrl.searchParams.get('grep') || undefined;
109
+ const tailStr = parsedUrl.searchParams.get('tail');
110
+ const tail = tailStr ? parseInt(tailStr, 10) : 50;
111
+ const logs = this.dockerBridge.getLogs({ container, level, grep, tail });
112
+ res.writeHead(200, { 'Content-Type': 'application/json' });
113
+ res.end(JSON.stringify(logs));
114
+ }
115
+ catch (err) {
116
+ res.writeHead(400, { 'Content-Type': 'application/json' });
117
+ res.end(JSON.stringify({ error: err.message }));
118
+ }
119
+ return;
120
+ }
121
+ // D. Real-Time Docker Event & Log SSE Stream
122
+ if (url === '/docker/stream') {
123
+ res.writeHead(200, {
124
+ 'Content-Type': 'text/event-stream',
125
+ 'Cache-Control': 'no-cache',
126
+ Connection: 'keep-alive'
127
+ });
128
+ // Send initial state immediately
129
+ const initPayload = {
130
+ type: 'INIT',
131
+ status: this.dockerBridge.getStatus(),
132
+ containers: this.dockerBridge.getContainers(),
133
+ recentLogs: this.dockerBridge.getLogs({ tail: 30 })
134
+ };
135
+ res.write(`data: ${JSON.stringify(initPayload)}\n\n`);
136
+ const onLog = (entry) => {
137
+ res.write(`data: ${JSON.stringify({ type: 'LOG', entry })}\n\n`);
138
+ };
139
+ const onContainers = (containers) => {
140
+ res.write(`data: ${JSON.stringify({ type: 'CONTAINERS', containers })}\n\n`);
141
+ };
142
+ this.dockerBridge.on('log', onLog);
143
+ this.dockerBridge.on('containers', onContainers);
144
+ // Heartbeat keep-alive every 15s
145
+ const heartbeat = setInterval(() => {
146
+ res.write(`: ping\n\n`);
147
+ }, 15000);
148
+ req.on('close', () => {
149
+ clearInterval(heartbeat);
150
+ this.dockerBridge?.off('log', onLog);
151
+ this.dockerBridge?.off('containers', onContainers);
152
+ });
153
+ return;
154
+ }
155
+ }
156
+ // 4. Health & Discovery (GET /)
157
+ if (req.method === 'GET') {
158
+ res.writeHead(200, { 'Content-Type': 'application/json' });
159
+ res.end(JSON.stringify({
160
+ name: 'Dr. Debug MCP Server',
161
+ status: 'running',
162
+ sessions: Array.from(this.sessions.keys()),
163
+ docker: this.dockerBridge ? this.dockerBridge.getStatus() : { isAvailable: false },
164
+ timestamp: Date.now()
165
+ }));
166
+ return;
167
+ }
168
+ res.writeHead(404);
169
+ res.end('Not Found');
170
+ });
171
+ this.server.listen(this.port, () => {
172
+ resolve();
173
+ });
174
+ this.server.on('error', (err) => {
175
+ reject(err);
176
+ });
177
+ }
178
+ catch (err) {
179
+ reject(err);
180
+ }
181
+ });
182
+ }
183
+ async sendCommandToBrowser(_command, _targetTabId) {
184
+ return { status: 'acknowledged', note: 'Browser command dispatched' };
185
+ }
186
+ getSessions() {
187
+ return this.sessions;
188
+ }
189
+ stop() {
190
+ return new Promise((resolve) => {
191
+ if (this.server) {
192
+ this.server.close(() => {
193
+ this.server = null;
194
+ resolve();
195
+ });
196
+ }
197
+ else {
198
+ resolve();
199
+ }
200
+ });
201
+ }
202
+ }
203
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAIjC,MAAM,OAAO,YAAY;IACf,MAAM,GAAuB,IAAI,CAAA;IACjC,IAAI,CAAQ;IACZ,QAAQ,GAAqC,IAAI,GAAG,EAAE,CAAA;IACtD,YAAY,CAAe;IAEnC,YAAY,IAAI,GAAG,IAAI,EAAE,YAA2B;QAClD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IAClC,CAAC;IAEM,eAAe,CAAC,YAA0B;QAC/C,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IAClC,CAAC;IAEM,KAAK,CACV,SAAoD,EACpD,aAAmD;QAEnD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;oBACjD,0CAA0C;oBAC1C,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAA;oBACjD,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,oBAAoB,CAAC,CAAA;oBACnE,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,6BAA6B,CAAC,CAAA;oBAE5E,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;wBAC7B,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;wBAClB,GAAG,CAAC,GAAG,EAAE,CAAA;wBACT,OAAM;oBACR,CAAC;oBAED,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAA;oBAE1B,oEAAoE;oBACpE,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;wBAC1F,IAAI,IAAI,GAAG,EAAE,CAAA;wBACb,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;4BACvB,IAAI,IAAI,KAAK,CAAA;wBACf,CAAC,CAAC,CAAA;wBACF,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;4BACjB,IAAI,CAAC;gCACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gCAC5B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;gCAC9C,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;oCACd,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE;wCACvB,KAAK;wCACL,GAAG,EAAE,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,IAAI,SAAS;wCAC7C,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,IAAI,cAAc;wCACtD,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;wCACpB,aAAa,EAAE,GAAG,CAAC,KAAK;qCACzB,CAAC,CAAA;oCACF,aAAa,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAA;gCACnC,CAAC;gCACD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;gCAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;4BAClD,CAAC;4BAAC,OAAO,GAAQ,EAAE,CAAC;gCAClB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;gCAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;4BACjD,CAAC;wBACH,CAAC,CAAC,CAAA;wBACF,OAAM;oBACR,CAAC;oBAED,iDAAiD;oBACjD,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;wBAC1B,IAAI,IAAI,GAAG,EAAE,CAAA;wBACb,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;4BACvB,IAAI,IAAI,KAAK,CAAA;wBACf,CAAC,CAAC,CAAA;wBACF,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;4BACvB,IAAI,CAAC;gCACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAA;gCAC7C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAA;gCACtC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;gCAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;4BACjC,CAAC;4BAAC,OAAO,GAAQ,EAAE,CAAC;gCAClB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;gCAC1D,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,SAAS,CAAC;oCACb,OAAO,EAAE,KAAK;oCACd,EAAE,EAAE,IAAI;oCACR,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,aAAa,EAAE;iCAC/D,CAAC,CACH,CAAA;4BACH,CAAC;wBACH,CAAC,CAAC,CAAA;wBACF,OAAM;oBACR,CAAC;oBAED,sBAAsB;oBACtB,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;wBAC/B,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;4BACvB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;4BAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,6CAA6C,EAAE,CAAC,CAAC,CAAA;4BACjF,OAAM;wBACR,CAAC;wBAED,mBAAmB;wBACnB,IAAI,GAAG,KAAK,gBAAgB,EAAE,CAAC;4BAC7B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;4BAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;4BACtD,OAAM;wBACR,CAAC;wBAED,uBAAuB;wBACvB,IAAI,GAAG,KAAK,oBAAoB,EAAE,CAAC;4BACjC,MAAM,IAAI,CAAC,YAAY,CAAC,iBAAiB,EAAE,CAAA;4BAC3C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;4BAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,CAAC,CAAA;4BAC1D,OAAM;wBACR,CAAC;wBAED,uBAAuB;wBACvB,IAAI,GAAG,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;4BACnC,IAAI,CAAC;gCACH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,oBAAoB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;gCAC/D,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,SAAS,CAAA;gCACtE,MAAM,KAAK,GAAI,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAS,IAAI,SAAS,CAAA;gCACvE,MAAM,IAAI,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS,CAAA;gCAC5D,MAAM,OAAO,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;gCAClD,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;gCAEjD,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;gCACxE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;gCAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;4BAC/B,CAAC;4BAAC,OAAO,GAAQ,EAAE,CAAC;gCAClB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;gCAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;4BACjD,CAAC;4BACD,OAAM;wBACR,CAAC;wBAED,6CAA6C;wBAC7C,IAAI,GAAG,KAAK,gBAAgB,EAAE,CAAC;4BAC7B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gCACjB,cAAc,EAAE,mBAAmB;gCACnC,eAAe,EAAE,UAAU;gCAC3B,UAAU,EAAE,YAAY;6BACzB,CAAC,CAAA;4BAEF,iCAAiC;4BACjC,MAAM,WAAW,GAAG;gCAClB,IAAI,EAAE,MAAM;gCACZ,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE;gCACrC,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE;gCAC7C,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;6BACpD,CAAA;4BACD,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;4BAErD,MAAM,KAAK,GAAG,CAAC,KAAU,EAAE,EAAE;gCAC3B,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,CAAA;4BAClE,CAAC,CAAA;4BAED,MAAM,YAAY,GAAG,CAAC,UAAe,EAAE,EAAE;gCACvC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,MAAM,CAAC,CAAA;4BAC9E,CAAC,CAAA;4BAED,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;4BAClC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;4BAEhD,iCAAiC;4BACjC,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;gCACjC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;4BACzB,CAAC,EAAE,KAAK,CAAC,CAAA;4BAET,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gCACnB,aAAa,CAAC,SAAS,CAAC,CAAA;gCACxB,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;gCACpC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;4BACpD,CAAC,CAAC,CAAA;4BACF,OAAM;wBACR,CAAC;oBACH,CAAC;oBAED,gCAAgC;oBAChC,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;wBACzB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAA;wBAC1D,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,SAAS,CAAC;4BACb,IAAI,EAAE,sBAAsB;4BAC5B,MAAM,EAAE,SAAS;4BACjB,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;4BAC1C,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE;4BAClF,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;yBACtB,CAAC,CACH,CAAA;wBACD,OAAM;oBACR,CAAC;oBAED,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;oBAClB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;gBACtB,CAAC,CAAC,CAAA;gBAEF,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE;oBACjC,OAAO,EAAE,CAAA;gBACX,CAAC,CAAC,CAAA;gBAEF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAQ,EAAE,EAAE;oBACnC,MAAM,CAAC,GAAG,CAAC,CAAA;gBACb,CAAC,CAAC,CAAA;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,GAAG,CAAC,CAAA;YACb,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAEM,KAAK,CAAC,oBAAoB,CAAC,QAAa,EAAE,YAAqB;QACpE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAA;IACvE,CAAC;IAEM,WAAW;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAEM,IAAI;QACT,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;oBACrB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;oBAClB,OAAO,EAAE,CAAA;gBACX,CAAC,CAAC,CAAA;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAA;YACX,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;CACF"}
@@ -0,0 +1,69 @@
1
+ export interface MCPResource {
2
+ uri: string;
3
+ name: string;
4
+ mimeType: string;
5
+ description: string;
6
+ }
7
+ export interface MCPResourceContent {
8
+ uri: string;
9
+ mimeType: string;
10
+ text?: string;
11
+ blob?: string;
12
+ }
13
+ export interface MCPToolParameter {
14
+ type: string;
15
+ description?: string;
16
+ enum?: string[];
17
+ properties?: Record<string, any>;
18
+ required?: string[];
19
+ }
20
+ export interface MCPToolDefinition {
21
+ name: string;
22
+ description: string;
23
+ inputSchema: {
24
+ type: 'object';
25
+ properties: Record<string, any>;
26
+ required?: string[];
27
+ };
28
+ }
29
+ export interface MCPRequest {
30
+ jsonrpc: '2.0';
31
+ id: string | number;
32
+ method: string;
33
+ params?: any;
34
+ }
35
+ export interface MCPResponse {
36
+ jsonrpc: '2.0';
37
+ id: string | number;
38
+ result?: any;
39
+ error?: {
40
+ code: number;
41
+ message: string;
42
+ data?: any;
43
+ };
44
+ }
45
+ export interface BrowserTabTelemetry {
46
+ tabId: string;
47
+ url: string;
48
+ title: string;
49
+ lastSeen: number;
50
+ stateSnapshot: any;
51
+ }
52
+ export type LogLevel = 'error' | 'warn' | 'info' | 'log';
53
+ export interface DockerContainerInfo {
54
+ id: string;
55
+ name: string;
56
+ image: string;
57
+ state: 'running' | 'exited' | 'restarting' | 'paused' | string;
58
+ status: string;
59
+ ports?: string[];
60
+ }
61
+ export interface DockerLogEntry {
62
+ id: string;
63
+ containerName: string;
64
+ timestamp: number;
65
+ stream: 'stdout' | 'stderr';
66
+ message: string;
67
+ level: LogLevel;
68
+ }
69
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAA;QACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QAC/B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KACpB,CAAA;CACF;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAA;IACd,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,GAAG,CAAA;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,KAAK,CAAA;IACd,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,GAAG,CAAA;IACZ,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,IAAI,CAAC,EAAE,GAAG,CAAA;KACX,CAAA;CACF;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,GAAG,CAAA;CACnB;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAA;AAExD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,QAAQ,GAAG,MAAM,CAAA;IAC9D,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,QAAQ,CAAA;CAChB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@dr-debug/mcp",
3
+ "version": "0.1.0",
4
+ "description": "Model Context Protocol (MCP) server & IDE bridge for Dr. Debug",
5
+ "type": "module",
6
+ "bin": {
7
+ "dr-debug-mcp": "./dist/cli.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "files": [
12
+ "dist",
13
+ "README.md",
14
+ "LICENSE"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc -b tsconfig.json",
18
+ "start": "node dist/cli.js"
19
+ },
20
+ "dependencies": {},
21
+ "devDependencies": {
22
+ "@types/node": "^22.10.0",
23
+ "typescript": "^5.7.2"
24
+ },
25
+ "author": "Saswat Mohanty (https://github.com/SazWhatician)",
26
+ "homepage": "https://github.com/SazWhatician",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/SazWhatician/DebugCopilot"
30
+ },
31
+ "license": "MIT"
32
+ }