Language servers Language Server Protocol (LSP) support gives the agent semantic information that text search cannot reliably provide: which declaration a name refers to, its type, and its references. The language server runs locally as a subprocess. This is separate from MCP; an LSP server is not an MCP server. Prerequisites Install a stdio language server in your project's Nix development environment, and launch the agent from that environment. The language server also needs the project's compiler, dependencies, and configuration. A globally installed executable does not guarantee that it can understand the project. The following example uses nil for Nix files. Add pkgs.nil to your flake development shell's packages, enter nix develop, and check: command -v nil nil --version Configure a server Merge this lsp object into ~/.haskell-agent/config.json. Preserve your existing settings. Start a new agent session after editing it. { "version": 1, "lsp": { "enabled": true, "servers": { "nix": { "command": "nil", "args": [], "extensionToLanguage": { ".nix": "nix" }, "startupTimeoutMilliseconds": 15000, "shutdownTimeoutMilliseconds": 5000 } } } } The key nix identifies this configuration entry; .nix selects files by extension and the value nix is the language identifier sent to the server. Replace these together when configuring another language. Server options Field | Default | Meaning | lsp.enabled | false | Enable the language-server runtime | lsp.servers | Empty object | Named server configurations | command | Required | Executable name or path, not a combined shell command | args | Empty array | Separate command arguments | env | Empty object | Environment values for the server; diagnostics redact this field | extensionToLanguage | Empty object | Filename-extension to language-identifier mapping | initializationOptions | Absent | Server-specific JSON sent during initialization | settings | Absent | Server-specific workspace configuration | workspaceFolder | Absent | Override the workspace folder | startupTimeoutMilliseconds | 15000 | Initialization deadline | shutdownTimeoutMilliseconds | 5000 | Graceful shutdown deadline | Only transport: "stdio" is supported. Automatic crash restart is not implemented: restartOnCrash: true and any maxRestarts setting are rejected rather than silently ignored. Verify semantic navigation - Launch the agent in the repository's Nix shell. - Choose a declaration or reference in an existing Nix file. - Ask: Use the language server to find the definition of this symbol in flake.nix. Report its file and location; do not edit anything. - Inspect the tool result, not just the final prose. A successful result identifies a source location or explicitly reports that the server returned no locations. Tool availability and naming follow the active model's tool dialect. When the lsp tool is available, it supports goToDefinition, findReferences, hover, goToImplementation, documentSymbol, and workspaceSymbol. Position-based requests use an absolute file_path and zero-based line and character; workspace-symbol searches use a non-empty query. Operation payloads Use operation to select the request. This example asks for hover information at the first character of the first line; replace the path and position with a real symbol in the configured project. {"operation":"hover","file_path":"/absolute/path/to/project/flake.nix","line":0,"character":0} Operation | Inputs | Result to inspect | goToDefinition, goToImplementation | File and zero-based line/character | Destination source locations | findReferences | File and zero-based line/character | Reference locations, not an authorization to rename them | hover | File and zero-based line/character | Type/documentation supplied by the server | documentSymbol | Absolute file_path | Symbols in that document | workspaceSymbol | Non-empty query | Matching symbols across the workspace | An empty result can mean no matching symbol or an unsupported capability. Confirm the position and project environment before falling back to text search. Diagnose failures Symptom | Check | Recovery | Executable not found | Run command -v nil in the same shell | Add the server to the project flake and launch the agent inside nix develop | No configured server for the file | Check enabled and the extension mapping | Map the actual extension, including its leading dot, and restart the session | Startup timeout | Run the server's version command; inspect compiler/dependency availability | Fix the project environment first; increase the deadline only if initialization is legitimately slow | Empty definition or references | Check the symbol position and whether the server supports the operation | Try a known local declaration; an empty result is not a transport failure | Server exits during work | Check its configuration and project logs | Correct the cause and start a new agent session; do not configure unsupported restart options | Language-server output helps investigation; it does not replace compilation or tests. Run the project's normal validation after changing code.