@debugmcp/mcp-debugger
Version:
Run-time step-through debugging for LLM agents.
358 lines (300 loc) • 7.94 kB
Markdown
# Using the mcp-debugger
This document describes how to use the mcp-debugger with Large Language Models (LLMs) for step-through debugging, based on real testing conducted on 2025-06-11.
## Installation
### Prerequisites
- Node.js 16+
- Python 3.7+ with debugpy (for Python debugging)
### Installing from NPM
```bash
npm install -g mcp-debugger
```
### Building from Source
```bash
git clone https://github.com/debugmcp/mcp-debugger.git
cd mcp-debugger
npm install
npm run build
```
## Configuration
### MCP Client Configuration
Add the server to your MCP settings:
```json
{
"mcpServers": {
"mcp-debugger": {
"command": "node",
"args": ["C:/path/to/mcp-debugger/dist/index.js", "--log-level", "debug", "--log-file", "C:/path/to/logs/debug-mcp-server.log"],
"disabled": false,
"autoApprove": ["create_debug_session", "set_breakpoint", "get_variables"]
}
}
}
```
## Complete Debugging Workflow Example
Here's a real example of debugging a Python script with a bug:
### The Buggy Script
```python
# swap_vars.py
def swap_variables(a, b):
print(f"Initial values: a = {a}, b = {b}")
a = b # Bug: 'a' loses its original value here
b = a # Bug: 'b' gets the new value of 'a' (which is original 'b')
print(f"Swapped values: a = {a}, b = {b}")
return a, b
def main():
x = 10
y = 20
print("Starting variable swap demo...")
swapped_x, swapped_y = swap_variables(x, y)
if swapped_x == 20 and swapped_y == 10:
print("Swap successful!")
else:
print(f"Swap NOT successful. Expected x=20, y=10 but got x={swapped_x}, y={swapped_y}")
if __name__ == "__main__":
main()
```
### Step 1: Create a Debug Session
```json
// Tool: create_debug_session
// Request:
{
"language": "python",
"name": "Investigate Swap Bug"
}
// Response:
{
"success": true,
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7",
"message": "Created python debug session: Investigate Swap Bug"
}
```
### Step 2: Set Breakpoints
Set a breakpoint where the bug occurs:
```json
// Tool: set_breakpoint
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7",
"file": "swap_vars.py",
"line": 4
}
// Response:
{
"success": true,
"breakpointId": "28e06119-619e-43c0-b029-339cec2615df",
"file": "C:\\path\\to\\swap_vars.py",
"line": 4,
"verified": false,
"message": "Breakpoint set at C:\\path\\to\\swap_vars.py:4"
}
```
### Step 3: Start Debugging
```json
// Tool: start_debugging
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7",
"scriptPath": "swap_vars.py"
}
// Response:
{
"success": true,
"state": "paused",
"message": "Debugging started for swap_vars.py. Current state: paused",
"data": {
"message": "Debugging started for swap_vars.py. Current state: paused",
"reason": "breakpoint"
}
}
```
### Step 4: Inspect the Stack
```json
// Tool: get_stack_trace
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7"
}
// Response:
{
"success": true,
"stackFrames": [
{
"id": 3,
"name": "swap_variables",
"file": "C:\\path\\to\\swap_vars.py",
"line": 4,
"column": 1
},
{
"id": 4,
"name": "main",
"file": "C:\\path\\to\\swap_vars.py",
"line": 13,
"column": 1
},
{
"id": 2,
"name": "<module>",
"file": "C:\\path\\to\\swap_vars.py",
"line": 21,
"column": 1
}
],
"count": 3
}
```
### Step 5: Get Variable Scopes
```json
// Tool: get_scopes
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7",
"frameId": 3
}
// Response:
{
"success": true,
"scopes": [
{
"name": "Locals",
"variablesReference": 5,
"expensive": false,
"presentationHint": "locals",
"source": {}
},
{
"name": "Globals",
"variablesReference": 6,
"expensive": false,
"source": {}
}
]
}
```
### Step 6: Inspect Variables Before the Bug
```json
// Tool: get_variables
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7",
"scope": 5
}
// Response:
{
"success": true,
"variables": [
{"name": "a", "value": "10", "type": "int", "variablesReference": 0, "expandable": false},
{"name": "b", "value": "20", "type": "int", "variablesReference": 0, "expandable": false}
],
"count": 2,
"variablesReference": 5
}
```
### Step 7: Step Through the Bug
```json
// Tool: step_over
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7"
}
// Response:
{
"success": true,
"state": "paused",
"message": "Stepped over"
}
```
### Step 8: Check Variables After First Assignment
```json
// Tool: get_variables
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7",
"scope": 5
}
// Response:
{
"success": true,
"variables": [
{"name": "a", "value": "20", "type": "int", "variablesReference": 0, "expandable": false},
{"name": "b", "value": "20", "type": "int", "variablesReference": 0, "expandable": false}
],
"count": 2,
"variablesReference": 5
}
```
Now we can see the bug! After `a = b`, both variables have the value 20.
### Step 9: Continue Execution
```json
// Tool: continue_execution
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7"
}
// Response:
{
"success": true,
"state": "running",
"message": "Continued execution"
}
```
### Step 10: Close the Session
```json
// Tool: close_debug_session
// Request:
{
"sessionId": "a4d1acc8-84a8-44fe-a13e-28628c5b33c7"
}
// Response:
{
"success": true,
"message": "Closed debug session: a4d1acc8-84a8-44fe-a13e-28628c5b33c7"
}
```
## Important Implementation Details
### Session IDs
- All session IDs are UUIDs in the format: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
- Sessions can terminate unexpectedly, always check if a session exists before operations
### Variable Scope References
- The `variablesReference` from `get_scopes` is what you pass to `get_variables`
- This is NOT the same as the frame ID from `get_stack_trace`
- Common mistake: Using frame ID instead of variablesReference
### Breakpoint Behavior
- Breakpoints always show `"verified": false` until debugging starts
- Avoid setting breakpoints on non-executable lines (comments, blank lines)
- Best lines for breakpoints: assignments, function calls, conditionals
### File Paths
- The server converts relative paths to absolute paths
- Responses always include the full absolute path
- Use forward slashes (/) or escaped backslashes (\\\\) in JSON
## Common Errors and Solutions
### "Managed session not found"
```json
{
"code": -32603,
"message": "MCP error -32603: Failed to continue execution: Managed session not found: {sessionId}"
}
```
**Solution**: The session has terminated. Create a new session.
### Invalid Scope Reference
```json
{
"code": -32602,
"message": "scope (variablesReference) parameter is required and must be a number"
}
```
**Solution**: Use the `variablesReference` from `get_scopes`, not the frame ID.
## Unimplemented Features
The following tools are defined but not yet implemented:
1. **pause_execution**: Returns "Pause execution not yet implemented with proxy"
2. **evaluate_expression**: Returns "Evaluate expression not yet implemented with proxy"
3. **get_source_context**: Returns "Get source context not yet fully implemented with proxy"
See [Roadmap.md](../Roadmap.md) for implementation timeline.
## Best Practices
1. **Always create a session first** - No debugging operations work without an active session
2. **Check the stack trace** - Understand where you are in the code before inspecting variables
3. **Get scopes before variables** - You need the variablesReference to inspect variables
4. **Handle errors gracefully** - Sessions can terminate, files might not exist
5. **Use meaningful session names** - Helps when debugging multiple scripts
---
*Last updated: 2025-06-11 based on actual testing*