docs/users/features/lsp.md
Qwen Code provides native Language Server Protocol (LSP) support, enabling advanced code intelligence features like go-to-definition, find references, diagnostics, and code actions. This integration allows the AI agent to understand your code more deeply and provide more accurate assistance.
LSP support in Qwen Code works by connecting to language servers that understand your code. Once you configure servers via .lsp.json (or extensions), Qwen Code can start them and use them to:
LSP is an experimental feature in Qwen Code. To enable it, use the --experimental-lsp command line flag:
qwen --experimental-lsp
LSP servers are configuration-driven. You must define them in .lsp.json (or via extensions) for Qwen Code to start them.
You need to have the language server for your programming language installed:
| Language | Language Server | Install Command |
|---|---|---|
| TypeScript/JavaScript | typescript-language-server | npm install -g typescript-language-server typescript |
| Python | pylsp | pip install python-lsp-server |
| Go | gopls | go install golang.org/x/tools/gopls@latest |
| Rust | rust-analyzer | Installation guide |
| C/C++ | clangd | Install LLVM/clangd via your package manager |
| Java | jdtls | Install JDTLS and a JDK |
You can configure language servers using a .lsp.json file in your project root. Each top-level key is a language identifier, and its value is the server configuration object.
Basic format:
{
"typescript": {
"command": "typescript-language-server",
"args": ["--stdio"],
"extensionToLanguage": {
".ts": "typescript",
".tsx": "typescriptreact",
".js": "javascript",
".jsx": "javascriptreact"
}
}
}
Dependencies:
compile_commands.json) or compile_flags.txt is required for accurate results.Example:
{
"cpp": {
"command": "clangd",
"args": [
"--background-index",
"--clang-tidy",
"--header-insertion=iwyu",
"--completion-style=detailed"
]
}
}
Dependencies:
java).jdtls).Example:
{
"java": {
"command": "jdtls",
"args": ["-configuration", ".jdtls-config", "-data", ".jdtls-workspace"]
}
}
| Option | Type | Description |
|---|---|---|
command | string | Command to start the LSP server. Supports bare command names resolved via PATH (e.g. clangd) and absolute paths (e.g. /opt/llvm/bin/clangd) |
| Option | Type | Default | Description |
|---|---|---|---|
args | string[] | [] | Command line arguments |
transport | string | "stdio" | Transport type: stdio, tcp, or socket |
env | object | - | Environment variables |
initializationOptions | object | - | LSP initialization options |
settings | object | - | Server settings via workspace/didChangeConfiguration |
extensionToLanguage | object | - | Maps file extensions to language identifiers |
workspaceFolder | string | - | Override workspace folder (must be within project root) |
startupTimeout | number | 10000 | Startup timeout in milliseconds |
shutdownTimeout | number | 5000 | Shutdown timeout in milliseconds |
restartOnCrash | boolean | false | Auto-restart on crash |
maxRestarts | number | 3 | Maximum restart attempts |
trustRequired | boolean | true | Require trusted workspace |
For servers that use TCP or Unix socket transport:
{
"remote-lsp": {
"transport": "tcp",
"socket": {
"host": "127.0.0.1",
"port": 9999
},
"extensionToLanguage": {
".custom": "custom"
}
}
}
Qwen Code exposes LSP functionality through the unified lsp tool. Here are the available operations:
Location-based operations (goToDefinition, findReferences, hover, goToImplementation, and prepareCallHierarchy) require an exact filePath + line + character position. If you do not know the exact position, use workspaceSymbol or documentSymbol first to locate the symbol.
Find where a symbol is defined.
Operation: goToDefinition
Parameters:
- filePath: Path to the file
- line: Line number (1-based)
- character: Column number (1-based)
Find all references to a symbol.
Operation: findReferences
Parameters:
- filePath: Path to the file
- line: Line number (1-based)
- character: Column number (1-based)
- includeDeclaration: Include the declaration itself (optional)
Find implementations of an interface or abstract method.
Operation: goToImplementation
Parameters:
- filePath: Path to the file
- line: Line number (1-based)
- character: Column number (1-based)
Get documentation and type information for a symbol.
Operation: hover
Parameters:
- filePath: Path to the file
- line: Line number (1-based)
- character: Column number (1-based)
Get all symbols in a document.
Operation: documentSymbol
Parameters:
- filePath: Path to the file
Search for symbols across the workspace.
Operation: workspaceSymbol
Parameters:
- query: Search query string
- limit: Maximum results (optional)
Get the call hierarchy item at a position.
Operation: prepareCallHierarchy
Parameters:
- filePath: Path to the file
- line: Line number (1-based)
- character: Column number (1-based)
Find all functions that call the given function.
Operation: incomingCalls
Parameters:
- callHierarchyItem: Item from prepareCallHierarchy
Find all functions called by the given function.
Operation: outgoingCalls
Parameters:
- callHierarchyItem: Item from prepareCallHierarchy
Get diagnostic messages (errors, warnings) for a file.
Operation: diagnostics
Parameters:
- filePath: Path to the file
Get all diagnostic messages across the workspace.
Operation: workspaceDiagnostics
Parameters:
- limit: Maximum results (optional)
Get available code actions (quick fixes, refactorings) at a location.
Operation: codeActions
Parameters:
- filePath: Path to the file
- line: Start line number (1-based)
- character: Start column number (1-based)
- endLine: End line number (optional, defaults to line)
- endCharacter: End column (optional, defaults to character)
- diagnostics: Diagnostics to get actions for (optional)
- codeActionKinds: Filter by action kind (optional)
Code action kinds:
quickfix - Quick fixes for errors/warningsrefactor - Refactoring operationsrefactor.extract - Extract to function/variablerefactor.inline - Inline function/variablesource - Source code actionssource.organizeImports - Organize importssource.fixAll - Fix all auto-fixable issuesLSP servers are only started in trusted workspaces by default. This is because language servers run with your user permissions and can execute code.
trustRequired: false is set in the server configurationTo mark a workspace as trusted, use the /trust command.
You can override trust requirements for specific servers in their configuration:
{
"safe-server": {
"command": "safe-language-server",
"args": ["--stdio"],
"trustRequired": false,
"extensionToLanguage": {
".safe": "safe"
}
}
}
--experimental-lsp flag: Make sure you're using the flag when starting Qwen Codeclangd --version) to verifyPATH, or specified as an absolute path (e.g. /opt/llvm/bin/clangd). Relative paths that escape the workspace are blocked/trust)[LSP] entries in the debug log (see Debugging section below)ps aux | grep <server-name> to verify the server process is runningnode_modules and other large directoriesstartupTimeout in server configuration for slow servers--background-index is in the args and a compile_commands.json (or compile_flags.txt) exists in the project root or a parent directory. Use --compile-commands-dir=<path> if it is in a build subdirectoryps aux | grep <server-name> to verify the server is actually runningLSP debug logs are automatically written to session log files in ~/.qwen/debug/. To check LSP-related entries:
# View the latest session log
grep '\[LSP\]' ~/.qwen/debug/latest
# Common error messages to look for:
# "command path is unsafe" → relative path escapes workspace, use absolute path or add to PATH
# "command not found" → server binary not installed or not in PATH
# "requires trusted workspace" → run /trust first
You can also verify the server process is running:
ps aux | grep clangd # or typescript-language-server, jdtls, etc.
Extensions can provide LSP server configurations through the lspServers field in their plugin.json. This can be either an inline object or a path to a .lsp.json file. Qwen Code loads these configs when the extension is enabled. The format is the same language-keyed layout used in project .lsp.json files.
.lsp.jsonUse the --experimental-lsp flag when starting Qwen Code:
qwen --experimental-lsp
Check the debug log for [LSP] entries (grep '\[LSP\]' ~/.qwen/debug/latest), or verify the process directly with ps aux | grep <server-name>.
Yes, but only one will be used for each operation. The first server that returns results wins.
LSP servers run outside the sandbox to access your code. They're subject to workspace trust controls.