README.md•15.3 kB
# Debug-MCP: Python Debugging via Model Context Protocol
A Python debugging tool that exposes breakpoint-based debugging capabilities through a clean API and CLI, designed for integration with AI assistants and development tools.
English | [日本語](README.ja.md)
## Features
- **Advanced Debugging via DAP**: Production-ready debugging using Microsoft's debugpy
- **Breakpoint Debugging**: Set breakpoints and inspect local variables at runtime
- **Step Execution**: True step-in, step-over, step-out operations
- **No Corruption**: Isolated process execution prevents sys.modules issues
- **Environment-aware**: Automatically uses target project's Python interpreter
- **Session Management**: Isolated debug sessions with timeout protection
- **Dual Interface**:
- **CLI**: Interactive debugging with beautiful table output
- **MCP Server**: Official MCP SDK-based integration for AI assistants
- **Safe Execution**: Sandboxed subprocess execution with configurable limits
- **Type Safety**: Pydantic v2 schemas for request/response validation
- **Async Support**: Built on MCP SDK with full async/await support
- **Comprehensive Testing**: 254 tests (119 unit + 122 integration + 13 exploration) covering DAP workflows, session management, and edge cases
- **Legacy Compatibility**: Optional bdb mode for backward compatibility
## Quick Start
### Installation
```bash
# Clone repository
git clone https://github.com/your-org/Debug-MCP.git
cd Debug-MCP
# Create virtual environment
uv venv
# Install with CLI support
uv pip install -e ".[cli]"
```
### VS Code Copilot Integration
To use this tool with GitHub Copilot in VS Code, set up the MCP server configuration.
**See [VS Code Setup Guide](docs/vscode-setup.md) for detailed instructions.**
**Quick Setup (Using from Debug-MCP repository):**
1. Create MCP config directory (macOS/Linux):
```bash
mkdir -p ~/Library/Application\ Support/Code/User/globalStorage/github.copilot-chat
```
2. Edit `mcp.json` file:
```json
{
"mcpServers": {
"python-debug": {
"command": "uv",
"args": ["run", "mcp-debug-server", "--workspace", "${workspaceFolder}"],
"env": {"PYTHONUNBUFFERED": "1"}
}
}
}
```
3. Restart VS Code
**Using from Another Repository:**
When using this tool from a different repository, specify the Debug-MCP installation path:
```json
{
"mcpServers": {
"python-debug": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/Debug-MCP",
"run",
"mcp-debug-server",
"--workspace",
"${workspaceFolder}"
],
"env": {
"PYTHONUNBUFFERED": "1"
}
}
}
}
```
Replace `/absolute/path/to/Debug-MCP` with the actual path to your Debug-MCP installation.
**Using Copilot Chat:**
```
@workspace Set a breakpoint at line 42 in src/main.py and
show me the local variables at that point.
```
See `mcp-config-example.json` for a complete configuration example.
### CLI Usage (Recommended for Interactive Debugging)
```bash
# Start a debug session
SESSION_ID=$(uv run mcp-debug start-session src/app.py | jq -r .sessionId)
# Run to breakpoint and inspect locals
uv run mcp-debug run-to-breakpoint $SESSION_ID src/app.py 42 --format table
# Continue to next breakpoint
uv run mcp-debug continue $SESSION_ID src/app.py 100 --format table
# Check session state
uv run mcp-debug state $SESSION_ID --format table
# End session
uv run mcp-debug end $SESSION_ID
```
See [Quickstart Guide](specs/001-python-debug-tool/quickstart.md) for more CLI examples.
### API Usage (Python Integration)
```python
from pathlib import Path
from mcp_debug_tool.sessions import SessionManager
from mcp_debug_tool.schemas import StartSessionRequest, BreakpointRequest
# Initialize
workspace = Path.cwd()
manager = SessionManager(workspace)
# Create session
req = StartSessionRequest(entry="src/main.py", args=["--verbose"])
session = manager.create_session(req)
# Run to breakpoint
bp_req = BreakpointRequest(file="src/main.py", line=15)
result = manager.run_to_breakpoint(session.sessionId, bp_req)
if result.hit:
print(f"Paused at {result.frameInfo.file}:{result.frameInfo.line}")
print(f"Locals: {result.locals}")
# Continue execution
continue_result = manager.continue_execution(
session.sessionId,
BreakpointRequest(file="src/main.py", line=42)
)
# Cleanup
manager.end_session(session.sessionId)
```
## Safety & Constraints
### Execution Limits
- **Timeout**: 20 seconds per breakpoint operation (configurable)
- **Output Capture**: 10MB maximum per session
- **Variable Depth**: Max 2 levels of nesting in local variable inspection
- **Collection Size**: Max 50 items shown in lists/dicts
- **String Length**: Max 256 characters before truncation
### Security
- **Path Validation**: Only project-relative paths allowed (no `..` traversal)
- **Subprocess Isolation**: Debuggee runs in isolated subprocess
- **Working Directory**: Locked to workspace root
- **No Network**: Debuggee has no special network access (app code may still use network)
⚠️ **Important**: The debugger executes user code with minimal restrictions. Only debug trusted code.
## Architecture
### Current Implementation (v2 - DAP-based)
Debug-MCP now uses **DAP (Debug Adapter Protocol)** via debugpy for production debugging:
```
┌─────────────────────────────────────────────────┐
│ MCP Server (server.py) │
│ - Official MCP SDK (async) │
│ - Tool registration & routing │
└────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Session Manager (sessions.py) │
│ - Lifecycle management │
│ - DAP/bdb mode selection │
└────────────────┬────────────────────────────────┘
│
▼ (DAP mode - default)
┌─────────────────────────────────────────────────┐
│ DAPSyncWrapper (dap_wrapper.py) │
│ - Synchronous DAP interface │
│ - Event queue management │
│ - Timeout handling │
└────────────────┬────────────────────────────────┘
│ DAP Protocol (JSON-RPC)
▼
┌─────────────────────────────────────────────────┐
│ debugpy Server (separate process) │
│ - Microsoft's official DAP implementation │
│ - Handles breakpoints, stepping, variables │
│ - Manages target script execution │
└────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Target Python Script │
│ - Runs in isolated process │
│ - Full access to target dependencies │
│ - No sys.modules corruption │
└─────────────────────────────────────────────────┘
```
**Why DAP (debugpy)?**
- ✅ **No sys.modules corruption** - Runs in separate process
- ✅ **True step execution** - Maintains execution state across steps
- ✅ **Automatic environment handling** - Uses target Python interpreter
- ✅ **Industry standard** - Microsoft's battle-tested implementation
- ✅ **Rich features** - Step in/over/out, conditional breakpoints, watch expressions
- ✅ **Future-proof** - Easy to extend with advanced debugging features
**Communication Flow:**
1. MCP Client (VS Code Copilot) → MCP Server (tool call)
2. Server → SessionManager (sync method via async wrapper)
3. SessionManager → DAPSyncWrapper (manages DAP session)
4. DAPSyncWrapper ↔ debugpy Server (DAP protocol over socket)
5. debugpy captures locals → DAPSyncWrapper → SessionManager → Server → Client
### Legacy bdb Mode
The bdb-based implementation is still available for compatibility (`useDap=false`):
```
SessionManager → runner_main.py (subprocess) → DebugController (bdb)
```
However, **DAP is now the default** and recommended for all use cases. The bdb mode has known issues:
- sys.modules corruption with multiple runs
- No true step execution (replay-based)
- Complex PYTHONPATH management
### File Organization (2025-11-03)
**Active Files (Production)**:
- ✅ `server.py` - MCP SDK server
- ✅ `sessions.py` - Session lifecycle management
- ✅ `dap_wrapper.py` - DAP synchronous wrapper (PRIMARY)
- ✅ `dap_client.py` - Low-level DAP protocol client (PRIMARY)
- ✅ `schemas.py` - Pydantic models
- ✅ `utils.py` - Variable repr helpers and path utilities
**Legacy Files (Compatibility)**:
- ⚠️ `debugger.py` - bdb-based engine (legacy, use `useDap=false`)
- ⚠️ `runner_main.py` - bdb subprocess runner (legacy)
**Removed Files**:
- ~~`runner.py`~~ - Old multiprocessing approach (removed 2025-10-30)
## Development
### Setup
See [docs/development.md](docs/development.md) for detailed setup instructions.
Quick commands:
```bash
# Run all tests (254 tests: 119 unit + 122 integration + 13 exploration)
uv run pytest
# Run only unit tests
uv run pytest tests/unit/
# Run only integration tests
uv run pytest tests/integration/
# Run tests with coverage
uv run pytest --cov=src/mcp_debug_tool --cov-report=html
# Lint
uv run ruff check .
# Format
uv run ruff format .
# Auto-fix lint issues
uv run ruff check --fix .
```
### Project Structure
```
Debug-MCP/
├── src/
│ ├── mcp_debug_tool/ # Core debugging engine
│ │ ├── server.py # MCP SDK-based server (v2.0+)
│ │ ├── sessions.py # Session management (DAP/bdb mode selection)
│ │ ├── dap_wrapper.py # DAP synchronous wrapper (PRIMARY)
│ │ ├── dap_client.py # DAP protocol client (PRIMARY)
│ │ ├── debugger.py # bdb-based debugger (LEGACY, use useDap=false)
│ │ ├── runner_main.py # bdb subprocess runner (LEGACY)
│ │ ├── schemas.py # Pydantic models
│ │ └── utils.py # Variable repr helpers
│ └── cli/
│ └── main.py # Typer CLI
├── tests/
│ ├── unit/ # Unit tests (debugger, schemas, DAP, sessions)
│ └── integration/ # Integration tests (DAP workflows, bdb compat)
├── specs/
│ └── 001-python-debug-tool/ # Specification documents
└── docs/ # Additional documentation
├── dap-phase*-*.md # DAP integration documentation
└── roadmap.md # Future enhancements
```
## Documentation
- [VS Code Setup Guide](docs/vscode-setup.md) - How to use MCP tool with VS Code Copilot ⭐
- [Quickstart Guide](specs/001-python-debug-tool/quickstart.md) - CLI and API usage examples
- [Specification](specs/001-python-debug-tool/spec.md) - Complete feature specification
- [Data Model](specs/001-python-debug-tool/data-model.md) - Entity schemas and validation rules
- [Research](specs/001-python-debug-tool/research.md) - Design decisions and rationale
- [Development Guide](docs/development.md) - Setup and contribution guide
- [Performance Tuning](docs/performance-tuning.md) - Timeout and resource configuration
- [Roadmap](docs/roadmap.md) - Planned v2 features
## Current Status
**v2.0 Released! DAP Integration Complete** 🎉
- ✅ Phase 1: Foundation (Complete - 6/6 tests passing)
- ✅ Phase 2: Core Logic (Complete - 28/28 tests passing)
- ✅ Phase 3: Session Lifecycle (Complete - 29/29 tests passing)
- ✅ Phase 4: Breakpoint Operations (Complete - 41/41 tests passing)
- ✅ Phase 5: Error Visibility (Complete - 71/71 tests passing)
- ✅ Phase 6: MCP SDK Migration (Complete - SDK-based server with async support)
- ✅ **Phase 7: DAP Integration (Complete - Production-ready debugpy integration)**
**What's New in v2.0:**
- **DAP (debugpy) is now the default** - No more sys.modules corruption!
- **True step execution** - Step in, step over, step out all working
- **Automatic environment handling** - Uses target project's Python interpreter
- **Industry-standard protocol** - Microsoft's battle-tested implementation
- **Enhanced reliability** - Isolated process execution prevents crashes
- **Backward compatible** - Legacy bdb mode still available with `useDap=false`
**Migration from v1.x:**
- Existing code works as-is (DAP is opt-in by default)
- To explicitly use bdb: `StartSessionRequest(entry="...", useDap=False)`
- Recommended: Let it default to DAP for best results
## Limitations (v2)
- **Script entry only**: No module (`python -m`) or pytest target support (planned for v2.1)
- **Single-threaded**: No support for multi-threaded debugging (planned for v2.1)
- **Line breakpoints**: Conditional breakpoints not yet exposed via MCP (DAP supports it)
**✅ Resolved from v1:**
- ~~No stepping~~ → **Now available**: Step in, step over, step out
- ~~sys.modules corruption~~ → **Fixed**: DAP uses isolated processes
- ~~Python environment mismatch~~ → **Fixed**: Uses target interpreter
See [docs/roadmap.md](docs/roadmap.md) for planned v2.1+ enhancements.
## Contributing
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes with tests
4. Run tests and linting (`uv run pytest && uv run ruff check .`)
5. Commit changes (`git commit -m 'Add amazing feature'`)
6. Push to branch (`git push origin feature/amazing-feature`)
7. Open a Pull Request
## License
MIT License - see [LICENSE](LICENSE) file for details
## Acknowledgments
Built with:
- [debugpy](https://github.com/microsoft/debugpy) - Microsoft's Python debugger (DAP implementation)
- [MCP SDK](https://github.com/modelcontextprotocol/python-sdk) - Model Context Protocol Python SDK
- [bdb/pdb](https://docs.python.org/3/library/bdb.html) - Python's standard debugger framework (legacy mode)
- [Pydantic](https://docs.pydantic.dev/) - Data validation using Python type annotations
- [Typer](https://typer.tiangolo.com/) - CLI framework built on Click
- [Rich](https://rich.readthedocs.io/) - Beautiful terminal formatting
- [pytest](https://pytest.org/) - Testing framework