Global Tool Context
Relevant source files
The following files were used as context for generating this wiki page:
The Global Tool Context is a foundational architectural pattern in the lsp-mcp-server that enables tool handlers to access shared services and configuration. It acts as a singleton-style registry that holds references to essential managers—such as the ConnectionManager, DocumentManager, and DiagnosticsCache—ensuring that disparate MCP tool handlers can interact with the Language Server Protocol (LSP) backend in a consistent and thread-safe manner.
This context is initialized during the server startup phase in src/index.ts and is consumed by various tool implementation files (e.g., src/tools/smart-search.ts, src/tools/utils.ts) to resolve the state of language servers and documents.
Sources: src/tools/context.ts:31-33, src/index.ts:515-520, CLAUDE.md:52-55
Architecture and Components
The Global Tool Context is defined by the ToolContext interface, which encapsulates four primary service instances. This structure allows the server to maintain a decoupled architecture where tool handlers depend on interfaces rather than concrete service implementations.
Context Composition
| Component | Interface | Description |
|---|---|---|
| Connection Manager | ConnectionManager | Manages the lifecycle of LSP server instances, keyed by server ID and workspace root. |
| Document Manager | DocumentManager | Handles document synchronization, ensuring files are opened and versioned correctly across clients. |
| Diagnostics Cache | DiagnosticsCache | Stores push-based diagnostics received from LSP publishDiagnostics notifications. |
| Configuration | Config | Holds global server settings such as log levels, timeouts, and server definitions. |
Sources: src/tools/context.ts:34-39, src/types.ts:153-159, CLAUDE.md:57-61
Initialization Flow
The context is initialized once during the main() function execution before the MCP server starts listening for requests. This ensures that any tool call received via the StdioServerTransport has a fully populated context available.
The diagram above shows the sequence of service creation and the subsequent binding of these services to the global context registry.
Sources: src/index.ts:503-520, CLAUDE.md:52-55
Implementation Details
The context mechanism is implemented using a module-level variable and exported setter/getter functions. This design enforces that the context is initialized before use, throwing a runtime error if tool handlers attempt to access services prematurely.
Key Functions
setToolContext(ctx: ToolContext): Assigns the provided service instances to the internaltoolContextvariable.getToolContext(): Retrieves the current context. It includes a safety check that throws an error iftoolContextis null.
Sources: src/tools/context.ts:46-60
// src/tools/context.ts:46-60
let toolContext: ToolContext | null = null;
export function setToolContext(ctx: ToolContext): void {
toolContext = ctx;
}
export function getToolContext(): ToolContext {
if (!toolContext) {
throw new Error('Tool context not initialized. Call setToolContext first.');
}
return toolContext;
}
Data Flow in Tool Handlers
Tool handlers use getToolContext() to perform complex operations that require cross-service coordination. A common pattern is the "Prepare File" flow, which utilizes the context to bridge the gap between a file path and an active LSP client.
Pattern: prepareFile
The prepareFile utility demonstrates how the context provides the necessary managers to validate paths, retrieve or start the correct LSP client, and ensure the document is synchronized.
This diagram illustrates the internal orchestration facilitated by the Global Tool Context when a tool needs to interact with a specific file.
Sources: src/tools/utils.ts:45-64, CLAUDE.md:63-71
Practical Usage Example: smart-search
In the lsp_smart_search tool, the context is used to access the documentManager specifically to retrieve content for references that exist in files other than the one currently being searched.
// src/tools/smart-search.ts:128-132
// Try to get context line
let contextLine = '';
try {
const ctx = getToolContext();
const refContent = ctx.documentManager.getContent(ref.uri);
if (refContent) {
contextLine = getLineContent(refContent, start.line)?.trim() ?? '';
}
} catch {
// Ignore context errors
}
Sources: src/tools/smart-search.ts:126-135
Service Responsibilities within Context
Each service available in the context provides specific capabilities defined in src/types.ts:
- ConnectionManager: Responsible for detecting workspace roots (e.g., finding
package.json) and managingServerInstanceobjects which track the status (starting,running,crashed) and process IDs (PID) of the underlying language servers. - DocumentManager: Maintains
DocumentState, including the current version of the file content and a set of clients currently tracking that document. - DiagnosticsCache: Provides methods like
getSummary()(returning error/warning counts) andgetUris()to see which files have reported issues.
Sources: src/types.ts:182-192, src/types.ts:211-218, src/types.ts:233-245
Conclusion
The Global Tool Context is the central nervous system of the lsp-mcp-server. By centralizing service management, it allows the server to support complex scenarios like monorepos (via keyed connections) and project-wide diagnostics while maintaining a simple, stateless-feeling API for individual tool implementations. It ensures that regardless of which tool is called, the underlying state of language servers and documents remains synchronized and accessible.
Sources: CLAUDE.md:31-34, src/index.ts:515-520