Documentation Index
Fetch the complete documentation index at: https://mintlify.com/QwenLM/qwen-code/llms.txt
Use this file to discover all available pages before exploring further.
Language Server Protocol Integration
Qwen Code includes first-class support for the Language Server Protocol (LSP), enabling precise code navigation, intelligent symbol lookup, and advanced refactoring capabilities.
Overview
LSP provides Qwen Code with:
- Go to Definition: Navigate to where symbols are defined
- Find References: Locate all usages of a symbol
- Hover Information: Get documentation and type information
- Document Symbols: List all symbols in a file
- Workspace Symbols: Search for symbols across the entire codebase
- Go to Implementation: Find implementations of interfaces
- Call Hierarchy: Analyze function call relationships
- Diagnostics: Access compiler/linter errors and warnings
- Code Actions: Get available quick fixes and refactorings
The unified lsp tool supports all LSP operations through a single interface:
// Tool signature from packages/core/src/tools/lsp.ts:49
export interface LspToolParams {
operation: LspOperation;
filePath?: string;
line?: number; // 1-based
character?: number; // 1-based
endLine?: number;
endCharacter?: number;
includeDeclaration?: boolean;
query?: string;
callHierarchyItem?: LspCallHierarchyItem;
serverName?: string;
limit?: number;
diagnostics?: LspDiagnostic[];
codeActionKinds?: LspCodeActionKind[];
}
Supported Operations
type LspOperation =
| 'goToDefinition'
| 'findReferences'
| 'hover'
| 'documentSymbol'
| 'workspaceSymbol'
| 'goToImplementation'
| 'prepareCallHierarchy'
| 'incomingCalls'
| 'outgoingCalls'
| 'diagnostics'
| 'workspaceDiagnostics'
| 'codeActions';
Operation Examples
Go to Definition
Find where a symbol is defined:
{
operation: "goToDefinition",
filePath: "src/index.ts",
line: 42,
character: 15,
limit: 20
}
Response format (from lsp.ts:208):
Definitions for src/index.ts:42:15:
1. src/utils/helper.ts:10:9 [typescript]
2. types/index.d.ts:5:14 [typescript]
Find References
Locate all usages of a symbol:
{
operation: "findReferences",
filePath: "src/api.ts",
line: 10,
character: 8,
includeDeclaration: false, // Exclude the definition itself
limit: 50
}
Response (from lsp.ts:290):
References for src/api.ts:10:8:
1. src/handlers/user.ts:15:3 [typescript]
2. src/routes.ts:42:20 [typescript]
3. tests/api.test.ts:8:12 [typescript]
...
Get documentation and type info:
{
operation: "hover",
filePath: "src/models/user.ts",
line: 25,
character: 10
}
Response (from lsp.ts:332):
Hover for src/models/user.ts:25:10:
```typescript
function getUserById(id: string): Promise<User | null>
Fetches a user by their unique identifier.
@param id - The user’s unique ID
@returns A promise resolving to the User object or null if not found
### Document Symbols
List all symbols in a file:
```typescript
{
operation: "documentSymbol",
filePath: "src/service.ts",
limit: 50
}
Response (from lsp.ts:370):
Document symbols for src/service.ts:
1. UserService (Class) - src/service.ts:5:7 [typescript]
2. constructor (Constructor) in UserService - src/service.ts:8:3 [typescript]
3. getUser (Method) in UserService - src/service.ts:12:9 [typescript]
4. createUser (Method) in UserService - src/service.ts:20:9 [typescript]
...
Workspace Symbol Search
Search for symbols across the workspace:
{
operation: "workspaceSymbol",
query: "handleRequest",
limit: 20
}
Response (from lsp.ts:415):
Found 20 of 45 symbols for query "handleRequest":
1. handleRequest (Function) - src/api.ts:10:9 [typescript]
2. handleRequestError (Function) - src/errors.ts:5:9 [typescript]
3. handleRequestMiddleware (Function) - src/middleware.ts:15:9 [typescript]
...
References for top match (handleRequest):
1. src/routes.ts:25:3 [typescript]
2. src/app.ts:40:8 [typescript]
...
Go to Implementation
Find implementations of an interface or abstract method:
{
operation: "goToImplementation",
filePath: "src/interfaces/storage.ts",
line: 5,
character: 18,
limit: 20
}
Response (from lsp.ts:249):
Implementations for src/interfaces/storage.ts:5:18:
1. src/storage/local.ts:10:7 [typescript]
2. src/storage/s3.ts:8:7 [typescript]
3. src/storage/memory.ts:5:7 [typescript]
Call Hierarchy
Prepare Call Hierarchy - Get callable items at a position:
{
operation: "prepareCallHierarchy",
filePath: "src/utils.ts",
line: 30,
character: 9,
limit: 20
}
Response (from lsp.ts:505):
Call hierarchy items for src/utils.ts:30:9:
1. processData (Function) - src/utils.ts:30:9 [typescript]
Call hierarchy items (JSON):
[
{
"name": "processData",
"kind": "function",
"uri": "file:///workspace/src/utils.ts",
"range": { "start": { "line": 29, "character": 0 }, "end": { "line": 45, "character": 1 } },
"selectionRange": { "start": { "line": 29, "character": 9 }, "end": { "line": 29, "character": 20 } },
"serverName": "typescript"
}
]
Incoming Calls - Find callers of a function:
{
operation: "incomingCalls",
callHierarchyItem: { /* from prepareCallHierarchy */ },
limit: 20
}
Response (from lsp.ts:548):
Incoming calls for processData at src/utils.ts:30:9:
1. handleData (Function) - src/handlers.ts:15:5 (calls at 18:3) [typescript]
2. main (Function) - src/index.ts:10:9 (calls at 25:5) [typescript]
Outgoing Calls - Find functions called by a function:
{
operation: "outgoingCalls",
callHierarchyItem: { /* from prepareCallHierarchy */ },
limit: 20
}
Response (from lsp.ts:602):
Outgoing calls for processData at src/utils.ts:30:9:
1. validateInput (Function) - src/validators.ts:8:9 (calls at 32:3) [typescript]
2. transformData (Function) - src/transform.ts:12:9 (calls at 35:10) [typescript]
3. saveToDatabase (Function) - src/db.ts:20:9 (calls at 40:3) [typescript]
Diagnostics
File Diagnostics - Get errors/warnings for a file:
{
operation: "diagnostics",
filePath: "src/buggy.ts"
}
Response (from lsp.ts:660):
Diagnostics for src/buggy.ts (3 issues):
1. [ERROR] 15:5 (2322) [typescript]: Type 'string' is not assignable to type 'number'.
2. [WARNING] 22:10 (6133) [typescript]: 'unusedVar' is declared but its value is never read.
3. [INFO] 30:1 (80001) [typescript]: File is a CommonJS module; it may be converted to an ES module.
Workspace Diagnostics - Get all diagnostics:
{
operation: "workspaceDiagnostics",
limit: 50
}
Response (from lsp.ts:700):
Workspace diagnostics (15 issues in 5 files):
src/app.ts [typescript]:
[ERROR] 10:3 (2304): Cannot find name 'proces'. Did you mean 'process'?
[WARNING] 25:5 (6133): 'tempVar' is declared but its value is never read.
src/utils.ts [typescript]:
[ERROR] 42:8 (2345): Argument of type 'string[]' is not assignable to parameter of type 'number[]'.
...
Code Actions
Get available quick fixes and refactorings:
{
operation: "codeActions",
filePath: "src/app.ts",
line: 10,
character: 3,
endLine: 10,
endCharacter: 20,
diagnostics: [ /* errors at this location */ ],
codeActionKinds: ["quickfix", "refactor"],
limit: 20
}
Response (from lsp.ts:783):
Code actions at src/app.ts:10:3:
1. Change spelling to 'process' [quickfix] (has edit) [typescript]
2. Add all missing imports [quickfix] (has edit) [typescript]
3. Extract to function [refactor.extract] (has edit) [typescript]
4. Convert to arrow function [refactor.rewrite] (has edit) [typescript]
Configuration
Enabling LSP
LSP is automatically enabled when language servers are configured. The tool checks:
// From lsp.ts:148
const client = this.config.getLspClient();
if (!client || !this.config.isLspEnabled()) {
return {
llmContent: 'LSP is unavailable (LSP disabled or not initialized)',
returnDisplay: 'LSP is unavailable'
};
}
Server Configuration
Language servers are typically configured through:
- IDE Extensions: When running in IDE mode (VS Code, etc.)
- Manual Configuration: Through Qwen Code settings
- Auto-detection: Based on project files
Best Practices
When to Use LSP
The tool description emphasizes (from lsp.ts:1021):
ALWAYS use LSP as the PRIMARY tool for code intelligence queries when available. Do NOT use grep_search or glob first.
Use LSP for:
- Finding symbol definitions
- Analyzing code structure
- Understanding type information
- Refactoring code
- Diagnosing errors
Avoid LSP for:
- Searching file contents by pattern (use grep)
- Finding files by name (use glob)
- Reading file contents (use read)
Parameter Validation
From lsp.ts:1153, the tool validates:
// Location-based operations require filePath + line
if (LOCATION_REQUIRED_OPERATIONS.has(operation)) {
if (!params.filePath || params.filePath.trim() === '') {
return `filePath is required for ${operation}.`;
}
if (typeof params.line !== 'number') {
return `line is required for ${operation}.`;
}
}
// File-based operations require only filePath
if (FILE_REQUIRED_OPERATIONS.has(operation)) {
if (!params.filePath || params.filePath.trim() === '') {
return `filePath is required for ${operation}.`;
}
}
Line/Character Coordinates
Important: LSP uses 1-based line and character numbers in the tool interface, but converts to 0-based internally:
// From lsp.ts:829
const position = {
line: Math.max(0, Math.floor(this.params.line - 1)), // Convert to 0-based
character: Math.max(0, Math.floor((this.params.character ?? 1) - 1))
};
Result Limits
All operations support a limit parameter with sensible defaults:
// From lsp.ts:191, 232, 273, 398
const limit = this.params.limit ?? {
goToDefinition: 20,
findReferences: 50,
documentSymbol: 50,
workspaceSymbol: 20,
// ...
};
Troubleshooting
LSP Not Available
Problem: Tool returns “LSP is unavailable”
Solution: Ensure language servers are configured:
# Check if LSP is enabled
qwen config get lsp.enabled
# Enable LSP
qwen config set lsp.enabled true
No Results Returned
Problem: Operations return empty results
Possible causes:
- Incorrect file path (use workspace-relative or absolute paths)
- Wrong line/character position
- Language server not initialized for file type
- Symbol not indexed yet
Solution:
// Use workspaceSymbol to search first
{ operation: "workspaceSymbol", query: "MyClass" }
// Then use returned location for precise lookup
{
operation: "goToDefinition",
filePath: "src/myclass.ts", // From search result
line: 10,
character: 7
}
Server-Specific Operations
Problem: Need to target specific language server
Solution: Use the serverName parameter:
{
operation: "goToDefinition",
filePath: "src/index.ts",
line: 10,
character: 5,
serverName: "typescript" // Target TypeScript LSP specifically
}
Path Resolution
From lsp.ts:847, paths are resolved as:
private resolveUri(filePath: string, workspaceRoot: string): string | null {
if (!filePath) return null;
// Already a URI
if (filePath.startsWith('file://') || filePath.includes('://')) {
return filePath;
}
// Convert to absolute path
const absolutePath = path.isAbsolute(filePath)
? filePath
: path.resolve(workspaceRoot, filePath);
// Convert to file:// URI
return pathToFileURL(absolutePath).toString();
}
Integration Examples
Symbol Navigation Workflow
// 1. Search for symbol in workspace
{ operation: "workspaceSymbol", query: "UserService" }
// Returns: src/services/user.ts:10:7
// 2. Get documentation
{
operation: "hover",
filePath: "src/services/user.ts",
line: 10,
character: 7
}
// 3. Find all usages
{
operation: "findReferences",
filePath: "src/services/user.ts",
line: 10,
character: 7,
includeDeclaration: false
}
Error Analysis Workflow
// 1. Get all workspace errors
{ operation: "workspaceDiagnostics", limit: 100 }
// 2. Get errors for specific file
{ operation: "diagnostics", filePath: "src/buggy.ts" }
// 3. Get available fixes
{
operation: "codeActions",
filePath: "src/buggy.ts",
line: 15,
character: 5,
endLine: 15,
endCharacter: 20,
codeActionKinds: ["quickfix"]
}
Call Graph Analysis
// 1. Prepare call hierarchy for function
{
operation: "prepareCallHierarchy",
filePath: "src/api.ts",
line: 50,
character: 9
}
// Returns: callHierarchyItem
// 2. Find who calls this function
{
operation: "incomingCalls",
callHierarchyItem: { /* from step 1 */ },
limit: 50
}
// 3. Find what this function calls
{
operation: "outgoingCalls",
callHierarchyItem: { /* from step 1 */ },
limit: 50
}
Source Code References
- LSP tool implementation:
packages/core/src/tools/lsp.ts
- LSP types:
packages/core/src/lsp/types.ts
- Configuration:
packages/core/src/config/config.ts:64