xdebug-mcp 1.0.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 +21 -0
- package/README.md +341 -0
- package/dist/config.d.ts +36 -0
- package/dist/config.js +47 -0
- package/dist/config.js.map +1 -0
- package/dist/dbgp/connection.d.ts +52 -0
- package/dist/dbgp/connection.js +362 -0
- package/dist/dbgp/connection.js.map +1 -0
- package/dist/dbgp/index.d.ts +3 -0
- package/dist/dbgp/index.js +4 -0
- package/dist/dbgp/index.js.map +1 -0
- package/dist/dbgp/server.d.ts +34 -0
- package/dist/dbgp/server.js +94 -0
- package/dist/dbgp/server.js.map +1 -0
- package/dist/dbgp/types.d.ts +112 -0
- package/dist/dbgp/types.js +28 -0
- package/dist/dbgp/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/session/code-coverage.d.ts +94 -0
- package/dist/session/code-coverage.js +226 -0
- package/dist/session/code-coverage.js.map +1 -0
- package/dist/session/debug-config.d.ts +102 -0
- package/dist/session/debug-config.js +194 -0
- package/dist/session/debug-config.js.map +1 -0
- package/dist/session/index.d.ts +10 -0
- package/dist/session/index.js +11 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/logpoint-manager.d.ts +94 -0
- package/dist/session/logpoint-manager.js +167 -0
- package/dist/session/logpoint-manager.js.map +1 -0
- package/dist/session/manager.d.ts +41 -0
- package/dist/session/manager.js +135 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/session/profiler.d.ts +89 -0
- package/dist/session/profiler.js +191 -0
- package/dist/session/profiler.js.map +1 -0
- package/dist/session/request-context.d.ts +50 -0
- package/dist/session/request-context.js +182 -0
- package/dist/session/request-context.js.map +1 -0
- package/dist/session/session-export.d.ts +83 -0
- package/dist/session/session-export.js +320 -0
- package/dist/session/session-export.js.map +1 -0
- package/dist/session/session.d.ts +92 -0
- package/dist/session/session.js +369 -0
- package/dist/session/session.js.map +1 -0
- package/dist/session/step-filter.d.ts +81 -0
- package/dist/session/step-filter.js +174 -0
- package/dist/session/step-filter.js.map +1 -0
- package/dist/session/watch-manager.d.ts +64 -0
- package/dist/session/watch-manager.js +137 -0
- package/dist/session/watch-manager.js.map +1 -0
- package/dist/tools/advanced.d.ts +26 -0
- package/dist/tools/advanced.js +502 -0
- package/dist/tools/advanced.js.map +1 -0
- package/dist/tools/breakpoints.d.ts +6 -0
- package/dist/tools/breakpoints.js +308 -0
- package/dist/tools/breakpoints.js.map +1 -0
- package/dist/tools/execution.d.ts +6 -0
- package/dist/tools/execution.js +283 -0
- package/dist/tools/execution.js.map +1 -0
- package/dist/tools/index.d.ts +31 -0
- package/dist/tools/index.js +44 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/inspection.d.ts +7 -0
- package/dist/tools/inspection.js +431 -0
- package/dist/tools/inspection.js.map +1 -0
- package/dist/tools/session.d.ts +6 -0
- package/dist/tools/session.js +164 -0
- package/dist/tools/session.js.map +1 -0
- package/dist/utils/logger.d.ts +16 -0
- package/dist/utils/logger.js +47 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/path-mapper.d.ts +13 -0
- package/dist/utils/path-mapper.js +56 -0
- package/dist/utils/path-mapper.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool Registration
|
|
3
|
+
*/
|
|
4
|
+
import { WatchManager } from '../session/watch-manager.js';
|
|
5
|
+
import { LogpointManager } from '../session/logpoint-manager.js';
|
|
6
|
+
import { Profiler } from '../session/profiler.js';
|
|
7
|
+
import { RequestContextCapture } from '../session/request-context.js';
|
|
8
|
+
import { StepFilter } from '../session/step-filter.js';
|
|
9
|
+
import { DebugConfigManager } from '../session/debug-config.js';
|
|
10
|
+
import { CodeCoverageTracker } from '../session/code-coverage.js';
|
|
11
|
+
import { SessionExporter } from '../session/session-export.js';
|
|
12
|
+
import { registerSessionTools } from './session.js';
|
|
13
|
+
import { registerBreakpointTools } from './breakpoints.js';
|
|
14
|
+
import { registerExecutionTools } from './execution.js';
|
|
15
|
+
import { registerInspectionTools } from './inspection.js';
|
|
16
|
+
import { registerAdvancedTools } from './advanced.js';
|
|
17
|
+
export function createToolsContext(sessionManager) {
|
|
18
|
+
return {
|
|
19
|
+
sessionManager,
|
|
20
|
+
watchManager: new WatchManager(),
|
|
21
|
+
logpointManager: new LogpointManager(),
|
|
22
|
+
profiler: new Profiler(),
|
|
23
|
+
requestCapture: new RequestContextCapture(),
|
|
24
|
+
stepFilter: new StepFilter(),
|
|
25
|
+
configManager: new DebugConfigManager(),
|
|
26
|
+
coverageTracker: new CodeCoverageTracker(),
|
|
27
|
+
sessionExporter: new SessionExporter(),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function registerAllTools(server, ctx) {
|
|
31
|
+
// Core debugging tools
|
|
32
|
+
registerSessionTools(server, ctx.sessionManager);
|
|
33
|
+
registerBreakpointTools(server, ctx.sessionManager);
|
|
34
|
+
registerExecutionTools(server, ctx.sessionManager);
|
|
35
|
+
registerInspectionTools(server, ctx.sessionManager);
|
|
36
|
+
// Advanced tools
|
|
37
|
+
registerAdvancedTools(server, ctx);
|
|
38
|
+
}
|
|
39
|
+
export { registerSessionTools } from './session.js';
|
|
40
|
+
export { registerBreakpointTools } from './breakpoints.js';
|
|
41
|
+
export { registerExecutionTools } from './execution.js';
|
|
42
|
+
export { registerInspectionTools } from './inspection.js';
|
|
43
|
+
export { registerAdvancedTools } from './advanced.js';
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAwB,MAAM,eAAe,CAAC;AAc5E,MAAM,UAAU,kBAAkB,CAAC,cAA8B;IAC/D,OAAO;QACL,cAAc;QACd,YAAY,EAAE,IAAI,YAAY,EAAE;QAChC,eAAe,EAAE,IAAI,eAAe,EAAE;QACtC,QAAQ,EAAE,IAAI,QAAQ,EAAE;QACxB,cAAc,EAAE,IAAI,qBAAqB,EAAE;QAC3C,UAAU,EAAE,IAAI,UAAU,EAAE;QAC5B,aAAa,EAAE,IAAI,kBAAkB,EAAE;QACvC,eAAe,EAAE,IAAI,mBAAmB,EAAE;QAC1C,eAAe,EAAE,IAAI,eAAe,EAAE;KACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,MAAiB,EACjB,GAAiB;IAEjB,uBAAuB;IACvB,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IACjD,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IACpD,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IACnD,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAEpD,iBAAiB;IACjB,qBAAqB,CAAC,MAAM,EAAE,GAA2B,CAAC,CAAC;AAC7D,CAAC;AAED,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inspection MCP Tools
|
|
3
|
+
* Tools for inspecting variables, stack traces, and evaluating expressions.
|
|
4
|
+
*/
|
|
5
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
|
+
import { SessionManager } from '../session/manager.js';
|
|
7
|
+
export declare function registerInspectionTools(server: McpServer, sessionManager: SessionManager): void;
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inspection MCP Tools
|
|
3
|
+
* Tools for inspecting variables, stack traces, and evaluating expressions.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
// Helper to format property for output
|
|
7
|
+
function formatProperty(prop, depth = 0) {
|
|
8
|
+
const result = {
|
|
9
|
+
name: prop.name,
|
|
10
|
+
type: prop.type,
|
|
11
|
+
};
|
|
12
|
+
if (prop.classname)
|
|
13
|
+
result.classname = prop.classname;
|
|
14
|
+
if (prop.value !== undefined)
|
|
15
|
+
result.value = prop.value;
|
|
16
|
+
if (prop.numchildren !== undefined && prop.numchildren > 0) {
|
|
17
|
+
result.numchildren = prop.numchildren;
|
|
18
|
+
}
|
|
19
|
+
if (prop.constant)
|
|
20
|
+
result.constant = true;
|
|
21
|
+
// Include nested properties if present and not too deep
|
|
22
|
+
if (prop.properties && prop.properties.length > 0 && depth < 3) {
|
|
23
|
+
result.children = prop.properties.map((p) => formatProperty(p, depth + 1));
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
export function registerInspectionTools(server, sessionManager) {
|
|
28
|
+
// Get stack trace
|
|
29
|
+
server.tool('get_stack_trace', 'Get the current call stack showing all function calls leading to the current position', {
|
|
30
|
+
session_id: z.string().optional().describe('Session ID'),
|
|
31
|
+
}, async ({ session_id }) => {
|
|
32
|
+
const session = sessionManager.resolveSession(session_id);
|
|
33
|
+
if (!session) {
|
|
34
|
+
return {
|
|
35
|
+
content: [
|
|
36
|
+
{
|
|
37
|
+
type: 'text',
|
|
38
|
+
text: JSON.stringify({ error: 'No active debug session' }),
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const frames = await session.getStackTrace();
|
|
45
|
+
return {
|
|
46
|
+
content: [
|
|
47
|
+
{
|
|
48
|
+
type: 'text',
|
|
49
|
+
text: JSON.stringify({
|
|
50
|
+
stack: frames.map((frame) => ({
|
|
51
|
+
level: frame.level,
|
|
52
|
+
file: frame.filename,
|
|
53
|
+
line: frame.lineno,
|
|
54
|
+
where: frame.where || '(main)',
|
|
55
|
+
type: frame.type,
|
|
56
|
+
})),
|
|
57
|
+
depth: frames.length,
|
|
58
|
+
}, null, 2),
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
return {
|
|
65
|
+
content: [
|
|
66
|
+
{
|
|
67
|
+
type: 'text',
|
|
68
|
+
text: JSON.stringify({
|
|
69
|
+
error: 'Failed to get stack trace',
|
|
70
|
+
message: error instanceof Error ? error.message : String(error),
|
|
71
|
+
}),
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// Get available contexts
|
|
78
|
+
server.tool('get_contexts', 'Get available variable contexts (Local, Superglobals, User-defined constants) at the current position', {
|
|
79
|
+
stack_depth: z
|
|
80
|
+
.number()
|
|
81
|
+
.int()
|
|
82
|
+
.default(0)
|
|
83
|
+
.describe('Stack frame depth (0 = current frame)'),
|
|
84
|
+
session_id: z.string().optional().describe('Session ID'),
|
|
85
|
+
}, async ({ stack_depth, session_id }) => {
|
|
86
|
+
const session = sessionManager.resolveSession(session_id);
|
|
87
|
+
if (!session) {
|
|
88
|
+
return {
|
|
89
|
+
content: [
|
|
90
|
+
{
|
|
91
|
+
type: 'text',
|
|
92
|
+
text: JSON.stringify({ error: 'No active debug session' }),
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const contexts = await session.getContexts(stack_depth);
|
|
99
|
+
return {
|
|
100
|
+
content: [
|
|
101
|
+
{
|
|
102
|
+
type: 'text',
|
|
103
|
+
text: JSON.stringify({
|
|
104
|
+
contexts: contexts.map((ctx) => ({
|
|
105
|
+
id: ctx.id,
|
|
106
|
+
name: ctx.name,
|
|
107
|
+
})),
|
|
108
|
+
hint: 'Use context_id in get_variables to get variables from a specific context',
|
|
109
|
+
}, null, 2),
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
return {
|
|
116
|
+
content: [
|
|
117
|
+
{
|
|
118
|
+
type: 'text',
|
|
119
|
+
text: JSON.stringify({
|
|
120
|
+
error: 'Failed to get contexts',
|
|
121
|
+
message: error instanceof Error ? error.message : String(error),
|
|
122
|
+
}),
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
// Get all variables in scope
|
|
129
|
+
server.tool('get_variables', 'Get all variables at the current execution point. Use context_id to switch between local variables, superglobals, etc.', {
|
|
130
|
+
context_id: z
|
|
131
|
+
.number()
|
|
132
|
+
.int()
|
|
133
|
+
.default(0)
|
|
134
|
+
.describe('Context ID: 0=Local variables, 1=Superglobals, 2=User constants'),
|
|
135
|
+
stack_depth: z
|
|
136
|
+
.number()
|
|
137
|
+
.int()
|
|
138
|
+
.default(0)
|
|
139
|
+
.describe('Stack frame depth (0 = current frame)'),
|
|
140
|
+
session_id: z.string().optional().describe('Session ID'),
|
|
141
|
+
}, async ({ context_id, stack_depth, session_id }) => {
|
|
142
|
+
const session = sessionManager.resolveSession(session_id);
|
|
143
|
+
if (!session) {
|
|
144
|
+
return {
|
|
145
|
+
content: [
|
|
146
|
+
{
|
|
147
|
+
type: 'text',
|
|
148
|
+
text: JSON.stringify({ error: 'No active debug session' }),
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
const variables = await session.getVariables(context_id, stack_depth);
|
|
155
|
+
return {
|
|
156
|
+
content: [
|
|
157
|
+
{
|
|
158
|
+
type: 'text',
|
|
159
|
+
text: JSON.stringify({
|
|
160
|
+
variables: variables.map((v) => formatProperty(v)),
|
|
161
|
+
count: variables.length,
|
|
162
|
+
context_id,
|
|
163
|
+
stack_depth,
|
|
164
|
+
}, null, 2),
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
return {
|
|
171
|
+
content: [
|
|
172
|
+
{
|
|
173
|
+
type: 'text',
|
|
174
|
+
text: JSON.stringify({
|
|
175
|
+
error: 'Failed to get variables',
|
|
176
|
+
message: error instanceof Error ? error.message : String(error),
|
|
177
|
+
}),
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
// Get a specific variable
|
|
184
|
+
server.tool('get_variable', "Get a specific variable by name, including nested properties. Use PHP syntax for nested access (e.g., '$user->name', '$array[0]', '$obj->items[2]->value')", {
|
|
185
|
+
name: z
|
|
186
|
+
.string()
|
|
187
|
+
.describe("Variable name with $ prefix (e.g., '$user', '$data[\"key\"]', '$obj->property')"),
|
|
188
|
+
context_id: z.number().int().default(0).describe('Context ID'),
|
|
189
|
+
stack_depth: z.number().int().default(0).describe('Stack frame depth'),
|
|
190
|
+
max_depth: z
|
|
191
|
+
.number()
|
|
192
|
+
.int()
|
|
193
|
+
.default(2)
|
|
194
|
+
.describe('Maximum depth for nested properties'),
|
|
195
|
+
session_id: z.string().optional().describe('Session ID'),
|
|
196
|
+
}, async ({ name, context_id, stack_depth, max_depth, session_id }) => {
|
|
197
|
+
const session = sessionManager.resolveSession(session_id);
|
|
198
|
+
if (!session) {
|
|
199
|
+
return {
|
|
200
|
+
content: [
|
|
201
|
+
{
|
|
202
|
+
type: 'text',
|
|
203
|
+
text: JSON.stringify({ error: 'No active debug session' }),
|
|
204
|
+
},
|
|
205
|
+
],
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
try {
|
|
209
|
+
const variable = await session.getVariable(name, {
|
|
210
|
+
contextId: context_id,
|
|
211
|
+
stackDepth: stack_depth,
|
|
212
|
+
maxDepth: max_depth,
|
|
213
|
+
});
|
|
214
|
+
if (!variable) {
|
|
215
|
+
return {
|
|
216
|
+
content: [
|
|
217
|
+
{
|
|
218
|
+
type: 'text',
|
|
219
|
+
text: JSON.stringify({
|
|
220
|
+
error: 'Variable not found',
|
|
221
|
+
name,
|
|
222
|
+
message: `Variable "${name}" does not exist in the current scope`,
|
|
223
|
+
}),
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
return {
|
|
229
|
+
content: [
|
|
230
|
+
{
|
|
231
|
+
type: 'text',
|
|
232
|
+
text: JSON.stringify({
|
|
233
|
+
variable: formatProperty(variable),
|
|
234
|
+
}, null, 2),
|
|
235
|
+
},
|
|
236
|
+
],
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
return {
|
|
241
|
+
content: [
|
|
242
|
+
{
|
|
243
|
+
type: 'text',
|
|
244
|
+
text: JSON.stringify({
|
|
245
|
+
error: 'Failed to get variable',
|
|
246
|
+
message: error instanceof Error ? error.message : String(error),
|
|
247
|
+
}),
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
// Set a variable value
|
|
254
|
+
server.tool('set_variable', 'Set the value of a variable in the current scope', {
|
|
255
|
+
name: z.string().describe('Variable name (e.g., $x, $user->name)'),
|
|
256
|
+
value: z.string().describe('New value as a PHP literal (e.g., 42, "hello", true, null)'),
|
|
257
|
+
context_id: z.number().int().default(0).describe('Context ID'),
|
|
258
|
+
stack_depth: z.number().int().default(0).describe('Stack frame depth'),
|
|
259
|
+
session_id: z.string().optional().describe('Session ID'),
|
|
260
|
+
}, async ({ name, value, context_id, stack_depth, session_id }) => {
|
|
261
|
+
const session = sessionManager.resolveSession(session_id);
|
|
262
|
+
if (!session) {
|
|
263
|
+
return {
|
|
264
|
+
content: [
|
|
265
|
+
{
|
|
266
|
+
type: 'text',
|
|
267
|
+
text: JSON.stringify({ error: 'No active debug session' }),
|
|
268
|
+
},
|
|
269
|
+
],
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
try {
|
|
273
|
+
const success = await session.setVariable(name, value, {
|
|
274
|
+
contextId: context_id,
|
|
275
|
+
stackDepth: stack_depth,
|
|
276
|
+
});
|
|
277
|
+
return {
|
|
278
|
+
content: [
|
|
279
|
+
{
|
|
280
|
+
type: 'text',
|
|
281
|
+
text: JSON.stringify({
|
|
282
|
+
success,
|
|
283
|
+
name,
|
|
284
|
+
value,
|
|
285
|
+
message: success
|
|
286
|
+
? `Variable ${name} set to ${value}`
|
|
287
|
+
: 'Failed to set variable',
|
|
288
|
+
}),
|
|
289
|
+
},
|
|
290
|
+
],
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
return {
|
|
295
|
+
content: [
|
|
296
|
+
{
|
|
297
|
+
type: 'text',
|
|
298
|
+
text: JSON.stringify({
|
|
299
|
+
error: 'Failed to set variable',
|
|
300
|
+
message: error instanceof Error ? error.message : String(error),
|
|
301
|
+
}),
|
|
302
|
+
},
|
|
303
|
+
],
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
// Evaluate an expression
|
|
308
|
+
server.tool('evaluate', "Evaluate a PHP expression in the current context. Returns the result of the expression. Use for calculations, method calls, or inspecting computed values.", {
|
|
309
|
+
expression: z
|
|
310
|
+
.string()
|
|
311
|
+
.describe("PHP expression to evaluate (e.g., '$x + $y', 'count($array)', '$user->getName()', 'array_keys($data)')"),
|
|
312
|
+
stack_depth: z.number().int().default(0).describe('Stack frame depth'),
|
|
313
|
+
session_id: z.string().optional().describe('Session ID'),
|
|
314
|
+
}, async ({ expression, stack_depth, session_id }) => {
|
|
315
|
+
const session = sessionManager.resolveSession(session_id);
|
|
316
|
+
if (!session) {
|
|
317
|
+
return {
|
|
318
|
+
content: [
|
|
319
|
+
{
|
|
320
|
+
type: 'text',
|
|
321
|
+
text: JSON.stringify({ error: 'No active debug session' }),
|
|
322
|
+
},
|
|
323
|
+
],
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
try {
|
|
327
|
+
const result = await session.evaluate(expression, stack_depth);
|
|
328
|
+
if (!result) {
|
|
329
|
+
return {
|
|
330
|
+
content: [
|
|
331
|
+
{
|
|
332
|
+
type: 'text',
|
|
333
|
+
text: JSON.stringify({
|
|
334
|
+
error: 'Evaluation returned no result',
|
|
335
|
+
expression,
|
|
336
|
+
}),
|
|
337
|
+
},
|
|
338
|
+
],
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
content: [
|
|
343
|
+
{
|
|
344
|
+
type: 'text',
|
|
345
|
+
text: JSON.stringify({
|
|
346
|
+
expression,
|
|
347
|
+
result: formatProperty(result),
|
|
348
|
+
}, null, 2),
|
|
349
|
+
},
|
|
350
|
+
],
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
return {
|
|
355
|
+
content: [
|
|
356
|
+
{
|
|
357
|
+
type: 'text',
|
|
358
|
+
text: JSON.stringify({
|
|
359
|
+
error: 'Evaluation failed',
|
|
360
|
+
expression,
|
|
361
|
+
message: error instanceof Error ? error.message : String(error),
|
|
362
|
+
}),
|
|
363
|
+
},
|
|
364
|
+
],
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
// Get source code
|
|
369
|
+
server.tool('get_source', 'Get the source code of a file or a specific line range', {
|
|
370
|
+
file: z.string().describe('File path to get source from'),
|
|
371
|
+
begin_line: z.number().int().optional().describe('Starting line number'),
|
|
372
|
+
end_line: z.number().int().optional().describe('Ending line number'),
|
|
373
|
+
session_id: z.string().optional().describe('Session ID'),
|
|
374
|
+
}, async ({ file, begin_line, end_line, session_id }) => {
|
|
375
|
+
const session = sessionManager.resolveSession(session_id);
|
|
376
|
+
if (!session) {
|
|
377
|
+
return {
|
|
378
|
+
content: [
|
|
379
|
+
{
|
|
380
|
+
type: 'text',
|
|
381
|
+
text: JSON.stringify({ error: 'No active debug session' }),
|
|
382
|
+
},
|
|
383
|
+
],
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
try {
|
|
387
|
+
const source = await session.getSource(file, begin_line, end_line);
|
|
388
|
+
if (source === null) {
|
|
389
|
+
return {
|
|
390
|
+
content: [
|
|
391
|
+
{
|
|
392
|
+
type: 'text',
|
|
393
|
+
text: JSON.stringify({
|
|
394
|
+
error: 'Failed to get source',
|
|
395
|
+
file,
|
|
396
|
+
message: 'File not found or not accessible',
|
|
397
|
+
}),
|
|
398
|
+
},
|
|
399
|
+
],
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
return {
|
|
403
|
+
content: [
|
|
404
|
+
{
|
|
405
|
+
type: 'text',
|
|
406
|
+
text: JSON.stringify({
|
|
407
|
+
file,
|
|
408
|
+
beginLine: begin_line,
|
|
409
|
+
endLine: end_line,
|
|
410
|
+
source,
|
|
411
|
+
}, null, 2),
|
|
412
|
+
},
|
|
413
|
+
],
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
catch (error) {
|
|
417
|
+
return {
|
|
418
|
+
content: [
|
|
419
|
+
{
|
|
420
|
+
type: 'text',
|
|
421
|
+
text: JSON.stringify({
|
|
422
|
+
error: 'Failed to get source',
|
|
423
|
+
message: error instanceof Error ? error.message : String(error),
|
|
424
|
+
}),
|
|
425
|
+
},
|
|
426
|
+
],
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
//# sourceMappingURL=inspection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspection.js","sourceRoot":"","sources":["../../src/tools/inspection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Management MCP Tools
|
|
3
|
+
*/
|
|
4
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import { SessionManager } from '../session/manager.js';
|
|
6
|
+
export declare function registerSessionTools(server: McpServer, sessionManager: SessionManager): void;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Management MCP Tools
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
export function registerSessionTools(server, sessionManager) {
|
|
6
|
+
// List all active debug sessions
|
|
7
|
+
server.tool('list_sessions', 'List all active PHP debug sessions with their current state', {}, async () => {
|
|
8
|
+
const sessions = sessionManager.getAllSessions();
|
|
9
|
+
const activeId = sessionManager.getActiveSessionId();
|
|
10
|
+
const sessionData = sessions.map((s) => {
|
|
11
|
+
const state = s.getState();
|
|
12
|
+
return {
|
|
13
|
+
id: s.id,
|
|
14
|
+
active: s.id === activeId,
|
|
15
|
+
status: state.status,
|
|
16
|
+
file: s.initPacket?.fileUri || 'unknown',
|
|
17
|
+
currentFile: state.filename,
|
|
18
|
+
currentLine: state.lineno,
|
|
19
|
+
ideKey: s.initPacket?.ideKey || 'unknown',
|
|
20
|
+
language: s.initPacket?.language || 'PHP',
|
|
21
|
+
startTime: state.startTime.toISOString(),
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
if (sessionData.length === 0) {
|
|
25
|
+
return {
|
|
26
|
+
content: [
|
|
27
|
+
{
|
|
28
|
+
type: 'text',
|
|
29
|
+
text: JSON.stringify({
|
|
30
|
+
sessions: [],
|
|
31
|
+
message: 'No active debug sessions. Start a PHP script with Xdebug enabled to begin debugging.',
|
|
32
|
+
}, null, 2),
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: 'text',
|
|
41
|
+
text: JSON.stringify({ sessions: sessionData, count: sessionData.length }, null, 2),
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
// Get detailed session state
|
|
47
|
+
server.tool('get_session_state', 'Get detailed state of a specific debug session including current position and status', {
|
|
48
|
+
session_id: z
|
|
49
|
+
.string()
|
|
50
|
+
.optional()
|
|
51
|
+
.describe('Session ID (uses active session if not specified)'),
|
|
52
|
+
}, async ({ session_id }) => {
|
|
53
|
+
const session = sessionManager.resolveSession(session_id);
|
|
54
|
+
if (!session) {
|
|
55
|
+
return {
|
|
56
|
+
content: [
|
|
57
|
+
{
|
|
58
|
+
type: 'text',
|
|
59
|
+
text: JSON.stringify({
|
|
60
|
+
error: 'No session found',
|
|
61
|
+
message: session_id
|
|
62
|
+
? `Session "${session_id}" not found`
|
|
63
|
+
: 'No active debug session. Start a PHP script with Xdebug enabled.',
|
|
64
|
+
}),
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const state = session.getState();
|
|
70
|
+
const initPacket = session.initPacket;
|
|
71
|
+
return {
|
|
72
|
+
content: [
|
|
73
|
+
{
|
|
74
|
+
type: 'text',
|
|
75
|
+
text: JSON.stringify({
|
|
76
|
+
id: session.id,
|
|
77
|
+
status: state.status,
|
|
78
|
+
currentFile: state.filename,
|
|
79
|
+
currentLine: state.lineno,
|
|
80
|
+
startTime: state.startTime.toISOString(),
|
|
81
|
+
init: initPacket
|
|
82
|
+
? {
|
|
83
|
+
fileUri: initPacket.fileUri,
|
|
84
|
+
ideKey: initPacket.ideKey,
|
|
85
|
+
language: initPacket.language,
|
|
86
|
+
protocolVersion: initPacket.protocolVersion,
|
|
87
|
+
engine: initPacket.engine,
|
|
88
|
+
}
|
|
89
|
+
: null,
|
|
90
|
+
isConnected: session.isConnected,
|
|
91
|
+
}, null, 2),
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
// Set active session
|
|
97
|
+
server.tool('set_active_session', 'Set which debug session should be the active/default session for subsequent commands', {
|
|
98
|
+
session_id: z.string().describe('Session ID to set as active'),
|
|
99
|
+
}, async ({ session_id }) => {
|
|
100
|
+
const success = sessionManager.setActiveSession(session_id);
|
|
101
|
+
if (!success) {
|
|
102
|
+
return {
|
|
103
|
+
content: [
|
|
104
|
+
{
|
|
105
|
+
type: 'text',
|
|
106
|
+
text: JSON.stringify({
|
|
107
|
+
error: 'Session not found',
|
|
108
|
+
session_id,
|
|
109
|
+
}),
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
content: [
|
|
116
|
+
{
|
|
117
|
+
type: 'text',
|
|
118
|
+
text: JSON.stringify({
|
|
119
|
+
success: true,
|
|
120
|
+
message: `Session "${session_id}" is now active`,
|
|
121
|
+
}),
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
};
|
|
125
|
+
});
|
|
126
|
+
// Close a session
|
|
127
|
+
server.tool('close_session', 'Close and terminate a debug session', {
|
|
128
|
+
session_id: z
|
|
129
|
+
.string()
|
|
130
|
+
.optional()
|
|
131
|
+
.describe('Session ID to close (uses active session if not specified)'),
|
|
132
|
+
}, async ({ session_id }) => {
|
|
133
|
+
const session = sessionManager.resolveSession(session_id);
|
|
134
|
+
if (!session) {
|
|
135
|
+
return {
|
|
136
|
+
content: [
|
|
137
|
+
{
|
|
138
|
+
type: 'text',
|
|
139
|
+
text: JSON.stringify({
|
|
140
|
+
error: 'No session found',
|
|
141
|
+
message: session_id
|
|
142
|
+
? `Session "${session_id}" not found`
|
|
143
|
+
: 'No active debug session',
|
|
144
|
+
}),
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const closedId = session.id;
|
|
150
|
+
sessionManager.closeSession(closedId);
|
|
151
|
+
return {
|
|
152
|
+
content: [
|
|
153
|
+
{
|
|
154
|
+
type: 'text',
|
|
155
|
+
text: JSON.stringify({
|
|
156
|
+
success: true,
|
|
157
|
+
message: `Session "${closedId}" closed`,
|
|
158
|
+
}),
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=session.js.map
|