@debugmcp/mcp-debugger
Version:
Run-time step-through debugging for LLM agents.
563 lines (401 loc) • 14.9 kB
Markdown
# mcp-debugger API Reference
> **⚠️ DRAFT DOCUMENTATION**
> This API reference is based on mcp-debugger v0.10.0 and will be updated as the architecture evolves.
## Table of Contents
1. [IDebugAdapter Interface](#idebugadapter-interface)
2. [SessionManager API](#sessionmanager-api)
3. [ProxyManager API](#proxymanager-api)
4. [AdapterRegistry API](#adapterregistry-api)
5. [Event System](#event-system)
6. [Type Definitions](#type-definitions)
## IDebugAdapter Interface
The core interface that all language adapters must implement.
**Source**: [src/adapters/debug-adapter-interface.ts](../../src/adapters/debug-adapter-interface.ts)
### Properties
```typescript
readonly language: DebugLanguage; // Language identifier
readonly name: string; // Human-readable adapter name
```
### Lifecycle Methods
#### `initialize(): Promise<void>`
Initializes the adapter and prepares it for use.
**When called**: After adapter creation, before any operations
**Expected behavior**: Validate environment, set up internal state
**Emits**: `'initialized'` event on success
#### `dispose(): Promise<void>`
Cleans up resources and connections.
**When called**: When session ends or adapter is no longer needed
**Expected behavior**: Close connections, clean up resources
**Emits**: `'disposed'` event
### State Management Methods
#### `getState(): AdapterState`
Returns the current adapter state.
**Returns**: One of: `UNINITIALIZED`, `INITIALIZING`, `READY`, `CONNECTED`, `DEBUGGING`, `DISCONNECTED`, `ERROR`
#### `isReady(): boolean`
Quick check if adapter is ready for debugging.
**Returns**: `true` if adapter can accept debug operations
#### `getCurrentThreadId(): number | null`
Gets the currently active thread ID during debugging.
**Returns**: Thread ID or `null` if not debugging
### Environment Validation Methods
#### `validateEnvironment(): Promise<ValidationResult>`
Comprehensive environment check for debugging readiness.
**Returns**:
```typescript
{
valid: boolean;
errors: ValidationError[];
warnings: ValidationWarning[];
}
```
**Example**:
```typescript
const result = await adapter.validateEnvironment();
if (!result.valid) {
console.error('Environment issues:', result.errors);
}
```
#### `getRequiredDependencies(): DependencyInfo[]`
Lists all dependencies needed for debugging.
**Returns**: Array of dependency information with install commands
### Executable Management Methods
#### `resolveExecutablePath(preferredPath?: string): Promise<string>`
Finds or validates the language runtime executable.
**Parameters**:
- `preferredPath` - User-specified path (optional)
**Returns**: Resolved executable path
**Throws**: `AdapterError` if executable not found
#### `getDefaultExecutableName(): string`
Platform-aware default executable name.
**Returns**: e.g., `'python'`, `'node'`, `'go'`
#### `getExecutableSearchPaths(): string[]`
Paths to search for the executable.
**Returns**: Array of paths (usually from PATH environment variable)
### Adapter Configuration Methods
#### `buildAdapterCommand(config: AdapterConfig): AdapterCommand`
Constructs the command to launch the debug adapter process.
**Parameters**:
```typescript
{
sessionId: string;
executablePath: string;
adapterHost: string;
adapterPort: number;
logDir: string;
scriptPath: string;
scriptArgs?: string[];
launchConfig: GenericLaunchConfig;
}
```
**Returns**:
```typescript
{
command: string; // Executable to run
args: string[]; // Command line arguments
env?: Record<string, string>; // Environment variables
}
```
#### `getAdapterModuleName(): string`
Debug adapter module identifier.
**Returns**: e.g., `'debugpy.adapter'`, `'node-debug2'`
#### `getAdapterInstallCommand(): string`
Command to install the debug adapter.
**Returns**: e.g., `'pip install debugpy'`, `'npm install -g node-debug2'`
### Debug Configuration Methods
#### `transformLaunchConfig(config: GenericLaunchConfig): LanguageSpecificLaunchConfig`
Converts generic config to language-specific format.
**Parameters**: Generic launch configuration
**Returns**: Language-specific configuration with additional fields
#### `getDefaultLaunchConfig(): Partial<GenericLaunchConfig>`
Default configuration values for the language.
**Returns**: Common default settings
### Path Translation Methods
#### `translateScriptPath(scriptPath: string, context: PathContext): string`
Handles language-specific path requirements.
**Parameters**:
```typescript
{
isContainer: boolean;
workspaceRoot: string;
platform: NodeJS.Platform;
}
```
**Returns**: Translated path suitable for the debug adapter
#### `translateBreakpointPath(filePath: string, context: PathContext): string`
Translates paths for breakpoint locations.
**Parameters**: Same as `translateScriptPath`
**Returns**: Translated breakpoint file path
### DAP Protocol Methods
#### `sendDapRequest<T>(command: string, args?: unknown): Promise<T>`
Sends a DAP request (usually delegated to ProxyManager).
**Parameters**:
- `command` - DAP command name
- `args` - Command arguments
**Returns**: DAP response
#### `handleDapEvent(event: DebugProtocol.Event): void`
Processes incoming DAP events.
**Critical**: Must update internal state based on events!
**Example**:
```typescript
handleDapEvent(event: DebugProtocol.Event): void {
if (event.event === 'stopped') {
this.currentThreadId = event.body?.threadId;
this.transitionTo(AdapterState.DEBUGGING);
}
this.emit(event.event, event.body);
}
```
#### `handleDapResponse(response: DebugProtocol.Response): void`
Processes DAP responses if special handling needed.
### Connection Management Methods
#### `connect(host: string, port: number): Promise<void>`
Establishes connection to debug adapter.
**Parameters**: Host and port for connection
**Emits**: `'connected'` event on success
#### `disconnect(): Promise<void>`
Closes debug adapter connection.
**Emits**: `'disconnected'` event
#### `isConnected(): boolean`
Connection status check.
**Returns**: `true` if connected to debug adapter
### Error Handling Methods
#### `getInstallationInstructions(): string`
User-friendly installation guide for the debugger.
**Returns**: Multi-line instructions with platform-specific commands
#### `getMissingExecutableError(): string`
Error message when runtime is not found.
**Returns**: Helpful error with installation hints
#### `translateErrorMessage(error: Error): string`
Converts generic errors to language-specific messages.
**Parameters**: Original error
**Returns**: User-friendly error message
### Feature Support Methods
#### `supportsFeature(feature: DebugFeature): boolean`
Checks if a DAP feature is supported.
**Parameters**: Feature from `DebugFeature` enum
**Returns**: `true` if supported
#### `getFeatureRequirements(feature: DebugFeature): FeatureRequirement[]`
Requirements for enabling a feature.
**Returns**: Array of requirements (dependencies, versions, etc.)
#### `getCapabilities(): AdapterCapabilities`
Full DAP capabilities declaration.
**Returns**: Object matching DAP Capabilities specification
## SessionManager API
Manages debug sessions and coordinates adapters with ProxyManager.
**Source**: [src/session/session-manager.ts](../../src/session/session-manager.ts)
### Core Methods
#### `createSession(params: CreateSessionParams): Promise<SessionInfo>`
Creates a new debug session.
**Parameters**:
```typescript
{
language: DebugLanguage;
name?: string;
config?: Partial<LaunchConfig>;
}
```
**Returns**: Session information with unique ID
#### `startDebugging(params: StartDebuggingParams): Promise<DebugResult>`
Starts debugging for a session.
**Parameters**:
```typescript
{
sessionId: string;
script: string;
launchConfig?: Partial<LaunchConfig>;
executablePath?: string;
args?: string[];
env?: Record<string, string>;
cwd?: string;
}
```
**Returns**: Debug result with success status
#### `setBreakpoints(sessionId: string, file: string, breakpoints: SourceBreakpoint[]): Promise<Breakpoint[]>`
Sets breakpoints in a file.
**Returns**: Array of verified breakpoints with actual locations
#### `continue(sessionId: string, threadId?: number): Promise<void>`
Resumes execution from a breakpoint.
#### `stepOver(sessionId: string, threadId?: number): Promise<void>`
Steps over the current line.
#### `stepInto(sessionId: string, threadId?: number): Promise<void>`
Steps into a function call.
#### `stepOut(sessionId: string, threadId?: number): Promise<void>`
Steps out of the current function.
#### `pause(sessionId: string): Promise<void>`
Pauses execution.
#### `terminate(sessionId: string): Promise<void>`
Terminates the debug session.
#### `getStackTrace(sessionId: string, threadId: number): Promise<StackFrame[]>`
Gets the current call stack.
#### `getScopes(sessionId: string, frameId: number): Promise<Scope[]>`
Gets variable scopes for a stack frame.
#### `getVariables(sessionId: string, variablesReference: number): Promise<Variable[]>`
Gets variables in a scope.
#### `evaluateExpression(sessionId: string, expression: string, frameId?: number): Promise<string>`
Evaluates an expression in the current context.
### Session Management
#### `getSession(sessionId: string): SessionInfo | null`
Retrieves session information.
#### `listSessions(): SessionInfo[]`
Lists all active sessions.
#### `deleteSession(sessionId: string): Promise<void>`
Removes a session and cleans up resources.
## ProxyManager API
Manages debug adapter process lifecycle and DAP communication.
**Source**: [src/proxy/proxy-manager.ts](../../src/proxy/proxy-manager.ts)
### Key Methods
#### `constructor(adapter: IDebugAdapter, config: ProxyConfig)`
Creates a new ProxyManager with an adapter.
#### `start(config: StartConfig): Promise<void>`
Starts the debug adapter process and establishes connection.
#### `sendDapRequest(command: string, args?: any): Promise<any>`
Sends a DAP request and waits for response.
#### `stop(): Promise<void>`
Stops the debug adapter process and cleans up.
### Events
ProxyManager forwards all DAP events from the adapter:
- `stopped`, `continued`, `terminated`, `exited`
- `thread`, `output`, `breakpoint`, `module`
- Plus adapter lifecycle events
## AdapterRegistry API
Manages available debug adapters.
**Source**: [src/adapters/adapter-registry.ts](../../src/adapters/adapter-registry.ts)
### Methods
#### `register(language: string, factory: IAdapterFactory): void`
Registers a new adapter factory.
**Example**:
```typescript
registry.register('python', new PythonAdapterFactory());
```
#### `create(language: string, config: AdapterConfig): IDebugAdapter`
Creates an adapter instance.
**Throws**: `AdapterNotFoundError` if language not supported
#### `isLanguageSupported(language: string): boolean`
Checks if a language has a registered adapter.
#### `getSupportedLanguages(): string[]`
Lists all registered languages.
## Event System
### Adapter Events
All adapters emit these events:
```typescript
interface AdapterEvents {
// DAP events
'stopped': (event: DebugProtocol.StoppedEvent) => void;
'continued': (event: DebugProtocol.ContinuedEvent) => void;
'terminated': (event: DebugProtocol.TerminatedEvent) => void;
'exited': (event: DebugProtocol.ExitedEvent) => void;
'thread': (event: DebugProtocol.ThreadEvent) => void;
'output': (event: DebugProtocol.OutputEvent) => void;
'breakpoint': (event: DebugProtocol.BreakpointEvent) => void;
'module': (event: DebugProtocol.ModuleEvent) => void;
// Lifecycle events
'initialized': () => void;
'connected': () => void;
'disconnected': () => void;
'error': (error: AdapterError) => void;
// State events
'stateChanged': (oldState: AdapterState, newState: AdapterState) => void;
}
```
### DAP Event Sequences
**Critical**: Understanding event order is crucial! See [DAP Sequence Reference](../development/dap-sequence-reference.md)
Common sequences:
1. **Breakpoint hit**: `stopped` (reason: 'breakpoint')
2. **Continue**: Request → (no event if explicit) → Running
3. **Program end**: `exited` → `terminated`
4. **User stop**: `terminated` (may have `exited` if killed)
## Type Definitions
### Core Types
```typescript
enum DebugLanguage {
PYTHON = 'python',
MOCK = 'mock',
// Future: NODE = 'node', GO = 'go', etc.
}
enum AdapterState {
UNINITIALIZED = 'uninitialized',
INITIALIZING = 'initializing',
READY = 'ready',
CONNECTED = 'connected',
DEBUGGING = 'debugging',
DISCONNECTED = 'disconnected',
ERROR = 'error'
}
interface ValidationResult {
valid: boolean;
errors: ValidationError[];
warnings: ValidationWarning[];
}
interface AdapterCommand {
command: string;
args: string[];
env?: Record<string, string>;
}
```
### Error Types
```typescript
class AdapterError extends Error {
constructor(
message: string,
public code: AdapterErrorCode,
public recoverable: boolean = false
);
}
enum AdapterErrorCode {
ENVIRONMENT_INVALID = 'ENVIRONMENT_INVALID',
EXECUTABLE_NOT_FOUND = 'EXECUTABLE_NOT_FOUND',
ADAPTER_NOT_INSTALLED = 'ADAPTER_NOT_INSTALLED',
CONNECTION_FAILED = 'CONNECTION_FAILED',
// ... more codes
}
```
## Usage Examples
### Creating and Starting a Debug Session
```typescript
// 1. Create session
const sessionInfo = await sessionManager.createSession({
language: 'python',
name: 'My Debug Session'
});
// 2. Set breakpoints
await sessionManager.setBreakpoints(
sessionInfo.sessionId,
'app.py',
[{ line: 10 }, { line: 20 }]
);
// 3. Start debugging
await sessionManager.startDebugging({
sessionId: sessionInfo.sessionId,
script: 'app.py',
launchConfig: { stopOnEntry: true }
});
// 4. Listen for events
sessionManager.on('stopped', (event) => {
console.log('Paused at:', event.body.reason);
});
// 5. Continue execution
await sessionManager.continue(sessionInfo.sessionId);
```
### Creating a Custom Adapter
```typescript
class MyAdapter extends EventEmitter implements IDebugAdapter {
// Implement all required methods
// See MockDebugAdapter for complete example
}
// Register it
const registry = new AdapterRegistry(dependencies);
registry.register('mylang', new MyAdapterFactory());
// Use it
const adapter = registry.create('mylang', config);
```
## Best Practices
1. **Always handle events** - Update adapter state based on DAP events
2. **Emit events** - Notify listeners of state changes
3. **Provide context in errors** - Include helpful messages and recovery hints
4. **Log important operations** - Use the provided logger for debugging
5. **Test thoroughly** - Use mock adapter for integration tests
## See Also
- [Architecture Overview](./README.md)
- [Adapter Development Guide](./adapter-development-guide.md)
- [DAP Sequence Reference](../development/dap-sequence-reference.md)
- [Migration Guide](../migration-guide.md)