UNPKG

@debugmcp/mcp-debugger

Version:

Run-time step-through debugging for LLM agents.

288 lines (234 loc) 8.77 kB
# Current Component Architecture ## System Overview ```mermaid graph TD Client[MCP Client] -->|MCP Protocol| Server[server.ts] Server -->|Creates/Manages| SM[SessionManager] SM -->|Creates| PM[ProxyManager] PM -->|Spawns| PA[Python Adapter Process] PA -->|DAP Protocol| DP[debugpy] DP -->|Controls| PY[Python Script] SM -->|Uses| PU[python-utils.ts] SM -->|Uses| PT[PathTranslator] SM -->|Stores| SS[SessionStore] style PA fill:#f9f,stroke:#333,stroke-width:2px style DP fill:#f9f,stroke:#333,stroke-width:2px style PU fill:#f9f,stroke:#333,stroke-width:2px classDef pythonSpecific fill:#f9f,stroke:#333,stroke-width:2px classDef coreComponent fill:#9cf,stroke:#333,stroke-width:2px classDef protocol fill:#ff9,stroke:#333,stroke-width:2px ``` ## Component Responsibilities | Component | Responsibility | Python Coupling | Refactoring Priority | |-----------|---------------|-----------------|---------------------| | **server.ts** | MCP protocol handling, tool registration | LOW - Language validation only | MEDIUM | | **SessionManager** | Session lifecycle, debugging orchestration | **CRITICAL** - Python path resolution, debugpy assumptions | **HIGH** | | **ProxyManager** | Process spawning, DAP communication | **CRITICAL** - Hardcoded debugpy commands | **HIGH** | | **SessionStore** | Session state persistence | LOW - Python defaults | LOW | | **python-utils.ts** | Python executable discovery | **CRITICAL** - Entirely Python-specific | Keep as-is | | **PathTranslator** | Container/host path translation | NONE - Language agnostic | NONE | | **DebugpyAdapterManager** | debugpy process management | **CRITICAL** - debugpy specific | Replace with adapters | ## Session Creation Sequence ```mermaid sequenceDiagram participant C as MCP Client participant S as server.ts participant SM as SessionManager participant SS as SessionStore participant PU as python-utils C->>S: create_debug_session(language='python') S->>S: Validate language === 'python' ❌ S->>SM: createSession({language, executablePath}) SM->>SS: createSession() SS->>SS: Set default executablePath SM->>PU: findPythonExecutable() PU-->>SM: Python path SM->>SM: Store executable path SM-->>S: SessionInfo S-->>C: {sessionId, success} Note over S: = Python-specific logic ``` ## Debug Session Lifecycle ```mermaid sequenceDiagram participant C as MCP Client participant S as server.ts participant SM as SessionManager participant PM as ProxyManager participant PA as Python Adapter participant DP as debugpy C->>S: start_debugging(sessionId, script) S->>SM: startDebugging() SM->>SM: Resolve Python path SM->>PM: start(config) PM->>PM: Build debugpy command PM->>PA: spawn('python -m debugpy.adapter') PA->>DP: Connect DAP DP-->>PA: Ready PA-->>PM: adapter-configured PM-->>SM: initialized SM-->>S: {success: true} S-->>C: Debug session started ``` ## Breakpoint Setting Flow ```mermaid sequenceDiagram participant C as MCP Client participant S as server.ts participant SM as SessionManager participant PM as ProxyManager participant DP as debugpy C->>S: set_breakpoint(file, line) S->>SM: setBreakpoint() SM->>PM: sendDapRequest('setBreakpoints') PM->>DP: DAP setBreakpoints DP-->>PM: Breakpoint verified PM-->>SM: Response SM-->>S: Breakpoint info S-->>C: {verified, id} ``` ## Current Python Coupling Points ```mermaid graph LR subgraph "MCP API Layer" A[server.ts<br/>Lines 73-75] end subgraph "Session Management" B[SessionManager<br/>Lines 166-196] C[SessionStore<br/>Line 64] end subgraph "Process Management" D[ProxyManager<br/>Lines 35-36] E[DebugpyAdapterManager<br/>Lines 26-32] end subgraph "Utilities" F[python-utils.ts<br/>Entire file] end A -->|validates| B B -->|uses| F B -->|creates| D D -->|delegates to| E style A fill:#fcc,stroke:#333,stroke-width:2px style B fill:#f99,stroke:#333,stroke-width:2px style C fill:#fdd,stroke:#333,stroke-width:2px style D fill:#f99,stroke:#333,stroke-width:2px style E fill:#f66,stroke:#333,stroke-width:2px style F fill:#f66,stroke:#333,stroke-width:2px ``` ## Data Flow Analysis ### Session Creation Data Flow ``` 1. Client Request └─> language: 'python' (hardcoded enum value) └─> executablePath?: string (optional) 2. Server Validation └─> if (language !== 'python') throw 3. SessionManager Processing └─> Resolve executable path (platform-specific) └─> Store in session.executablePath 4. SessionStore └─> Default to env.PYTHON_PATH or 'python'/'python3' ``` ### Configuration Data Flow ``` ProxyConfig { executablePath: string Language-specific field adapterHost: string adapterPort: number scriptPath: string initialBreakpoints: [] } ``` ## Component Dependencies Graph ```mermaid graph BT subgraph "External Dependencies" PY[Python Runtime] DP[debugpy Package] end subgraph "Core Components" SM[SessionManager] PM[ProxyManager] PA[ProxyAdapterManager] end subgraph "Utilities" PU[python-utils] PT[PathTranslator] end SM --> PU SM --> PM PM --> PA PA --> PY PA --> DP PU --> PY style PY fill:#f9f,stroke:#333,stroke-width:2px style DP fill:#f9f,stroke:#333,stroke-width:2px style PU fill:#f9f,stroke:#333,stroke-width:2px style PA fill:#fcc,stroke:#333,stroke-width:2px ``` ## Event Flow Patterns ### Current Event Handling ```mermaid stateDiagram-v2 [*] --> Created: Session Created Created --> Initializing: startDebugging() Initializing --> Running: Python found Initializing --> Error: Python not found Running --> Paused: Breakpoint hit Paused --> Running: Continue Running --> Stopped: Program exits Paused --> Stopped: Terminate Error --> [*] Stopped --> [*] note right of Initializing: Python discovery happens here note right of Running: debugpy controls execution ``` ## Key Architecture Insights ### 1. **Proxy Pattern Already Exists** The system already uses a proxy pattern (ProxyManager Adapter Process), which is perfect for multi-language support. We just need to make it language-agnostic. ### 2. **Clear Separation Points** - **Good**: python-utils.ts is isolated - **Bad**: SessionManager mixes session logic with Python logic - **Ugly**: ProxyManager hardcodes debugpy commands ### 3. **Single Language Assumption** The `DebugLanguage` enum having only `PYTHON` means: - No existing multi-language code to break - All current code assumes Python - Clean slate for adapter pattern ### 4. **Event-Driven Architecture** The system is already event-driven (DAP events), making it easier to abstract language-specific behavior. ## Refactoring Opportunities ### Current Anti-Pattern ``` Client Server SessionManager Python Logic ProxyManager debugpy python-utils ``` ### Target Architecture ``` Client Server SessionManager IDebugAdapter Language-Specific Adapter AdapterFactory PythonAdapter / NodeAdapter / etc. ``` ## Component Coupling Matrix | Component | Depends On | Python Coupling | Refactor Difficulty | |-----------|------------|-----------------|-------------------| | server.ts | SessionManager | Language validation | LOW | | SessionManager | python-utils, ProxyManager | Path resolution, config | HIGH | | ProxyManager | DebugpyAdapterManager | Command building | MEDIUM | | SessionStore | None (uses defaults) | Default paths | LOW | | PathTranslator | None | None | NONE | | python-utils | Python runtime | Entire purpose | N/A (Keep) | ## System Constraints 1. **MCP Protocol**: Fixed interface, must maintain compatibility 2. **DAP Protocol**: Standard debug protocol, language-agnostic 3. **Current Tests**: 50+ tests assume Python behavior 4. **Docker**: No Python installed in container (relies on host) ## Next Steps for Refactoring 1. **Extract IDebugAdapter interface** 2. **Move Python logic from SessionManager to PythonAdapter** 3. **Create AdapterFactory for language selection** 4. **Update ProxyManager to be language-agnostic** 5. **Remove hardcoded language validation from server.ts**