get_source_context
Retrieve source code context around a specific line in a file during debugging sessions to understand program execution flow and inspect code behavior.
Instructions
Get source context around a specific line in a file
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes | ||
| file | Yes | Path to the source file. Use absolute paths or paths relative to your current working directory | |
| line | Yes | Line number to get context for | |
| linesContext | No | Number of lines before and after to include (default: 5) |
Implementation Reference
- src/server.ts:1020-1085 (handler)Primary handler method for the 'get_source_context' MCP tool. Performs session and file validation, invokes LineReader for context extraction, and formats the JSON response.private async handleGetSourceContext(args: { sessionId: string, file: string, line: number, linesContext?: number }): Promise<ServerResult> { try { // Validate session this.validateSession(args.sessionId); // Check file exists for immediate feedback const fileCheck = await this.fileChecker.checkExists(args.file); if (!fileCheck.exists) { throw new McpError(McpErrorCode.InvalidParams, `Line context file not found: '${args.file}'\nLooked for: '${fileCheck.effectivePath}'${fileCheck.errorMessage ? `\nError: ${fileCheck.errorMessage}` : ''}`); } this.logger.info(`Source context requested for session: ${args.sessionId}, file: ${fileCheck.effectivePath}, line: ${args.line}`); // Get line context using the line reader const contextLines = args.linesContext ?? 5; // Default to 5 lines of context const lineContext = await this.lineReader.getLineContext( fileCheck.effectivePath, args.line, { contextLines } ); if (!lineContext) { // File might be binary or unreadable return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: 'Could not read source context. File may be binary or inaccessible.', file: args.file, line: args.line }) }] }; } // Log source context request this.logger.info('debug:source_context', { sessionId: args.sessionId, sessionName: this.getSessionName(args.sessionId), file: args.file, line: args.line, contextLines: contextLines, timestamp: Date.now() }); return { content: [{ type: 'text', text: JSON.stringify({ success: true, file: args.file, line: args.line, lineContent: lineContext.lineContent, surrounding: lineContext.surrounding, contextLines: contextLines }) }] }; } catch (error) { this.logger.error('Failed to get source context', { error }); if (error instanceof McpError) throw error; throw new McpError(McpErrorCode.InternalError, `Failed to get source context: ${(error as Error).message}`); } }
- src/utils/line-reader.ts:120-159 (helper)Core helper function implementing source context logic: caches file lines, detects binary/large files, validates line numbers, extracts target line and surrounding context.async getLineContext( filePath: string, lineNumber: number, options: LineReaderOptions = {} ): Promise<LineContext | null> { const contextLines = options.contextLines ?? 2; // Read file lines const lines = await this.readFileLines(filePath, options); if (!lines) { return null; } // Validate line number (1-based) if (lineNumber < 1 || lineNumber > lines.length) { this.logger?.debug(`[LineReader] Line ${lineNumber} out of range for ${filePath} (1-${lines.length})`); return null; } // Get the target line content (convert to 0-based index) const lineContent = lines[lineNumber - 1]; // Calculate surrounding lines range const startLine = Math.max(1, lineNumber - contextLines); const endLine = Math.min(lines.length, lineNumber + contextLines); // Build surrounding context const surrounding: LineContext['surrounding'] = []; for (let i = startLine; i <= endLine; i++) { surrounding.push({ line: i, content: lines[i - 1] }); } return { lineContent, surrounding }; }
- src/server.ts:483-483 (schema)Input schema definition and description for the get_source_context tool in the ListTools response.{ name: 'get_source_context', description: 'Get source context around a specific line in a file', inputSchema: { type: 'object', properties: { sessionId: { type: 'string' }, file: { type: 'string', description: fileDescription }, line: { type: 'number', description: 'Line number to get context for' }, linesContext: { type: 'number', description: 'Number of lines before and after to include (default: 5)' } }, required: ['sessionId', 'file', 'line'] } },
- src/server.ts:879-881 (registration)Registration of the tool handler dispatch in the MCP CallToolRequestSchema switch statement.case 'get_source_context': { result = await this.handleGetSourceContext(args as { sessionId: string; file: string; line: number; linesContext?: number }); break;