On this page

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

FieldDefaultMeaning
lsp.enabledfalseEnable the language-server runtime
lsp.serversEmpty objectNamed server configurations
commandRequiredExecutable name or path, not a combined shell command
argsEmpty arraySeparate command arguments
envEmpty objectEnvironment values for the server; diagnostics redact this field
extensionToLanguageEmpty objectFilename-extension to language-identifier mapping
initializationOptionsAbsentServer-specific JSON sent during initialization
settingsAbsentServer-specific workspace configuration
workspaceFolderAbsentOverride the workspace folder
startupTimeoutMilliseconds15000Initialization deadline
shutdownTimeoutMilliseconds5000Graceful 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

  1. Launch the agent in the repository's Nix shell.
  2. Choose a declaration or reference in an existing Nix file.
  3. Ask: Use the language server to find the definition of this symbol in flake.nix. Report its file and location; do not edit anything.
  4. 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}
OperationInputsResult to inspect
goToDefinition, goToImplementationFile and zero-based line/characterDestination source locations
findReferencesFile and zero-based line/characterReference locations, not an authorization to rename them
hoverFile and zero-based line/characterType/documentation supplied by the server
documentSymbolAbsolute file_pathSymbols in that document
workspaceSymbolNon-empty queryMatching 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

SymptomCheckRecovery
Executable not foundRun command -v nil in the same shellAdd the server to the project flake and launch the agent inside nix develop
No configured server for the fileCheck enabled and the extension mappingMap the actual extension, including its leading dot, and restart the session
Startup timeoutRun the server's version command; inspect compiler/dependency availabilityFix the project environment first; increase the deadline only if initialization is legitimately slow
Empty definition or referencesCheck the symbol position and whether the server supports the operationTry a known local declaration; an empty result is not a transport failure
Server exits during workCheck its configuration and project logsCorrect 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.