> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/opencode-ai/opencode/llms.txt
> Use this file to discover all available pages before exploring further.

# Language Server Protocol (LSP) integration

> Enable code intelligence features with multi-language LSP support for diagnostics, real-time error checking, and code analysis

OpenCode integrates with Language Server Protocol (LSP) to provide code intelligence features across multiple programming languages. The AI assistant can access diagnostics, errors, and warnings to help you write better code.

## What is LSP?

The Language Server Protocol (LSP) is a standardized protocol that provides language-specific intelligence features:

* **Diagnostics**: Real-time error and warning detection
* **Type checking**: Static analysis and type errors
* **Linting**: Code style and quality issues
* **Semantic analysis**: Language-specific code understanding

<Note>
  OpenCode's LSP client implementation is based on the [mcp-language-server](https://github.com/isaacphi/mcp-language-server) project.
</Note>

## Supported features

OpenCode's LSP integration currently exposes diagnostics to the AI assistant:

<CardGroup cols={2}>
  <Card title="Error detection" icon="circle-exclamation">
    * Syntax errors
    * Type errors
    * Compilation errors
    * Import/reference errors
  </Card>

  <Card title="Warnings" icon="triangle-exclamation">
    * Unused variables
    * Deprecated APIs
    * Potential bugs
    * Code smells
  </Card>

  <Card title="Hints" icon="lightbulb">
    * Optimization suggestions
    * Style improvements
    * Best practices
    * Refactoring opportunities
  </Card>

  <Card title="Real-time feedback" icon="bolt">
    * Instant analysis on file open
    * Updates on file changes
    * Persistent across session
    * Multi-file awareness
  </Card>
</CardGroup>

<Info>
  While the LSP client supports the full protocol (completions, hover, go-to-definition, etc.), only diagnostics are currently exposed to the AI assistant.
</Info>

## Configuration

LSP servers are configured in `.opencode.json` under the `lsp` key:

```json theme={null}
{
  "lsp": {
    "language-id": {
      "disabled": false,
      "command": "path-to-language-server",
      "args": ["--stdio"]
    }
  },
  "debugLSP": false
}
```

### Configuration fields

<ParamField path="disabled" type="boolean" default={false}>
  Whether this language server is disabled
</ParamField>

<ParamField path="command" type="string" required>
  Path to the language server executable
</ParamField>

<ParamField path="args" type="array">
  Command-line arguments to pass to the server (e.g., `["--stdio"]`)
</ParamField>

<ParamField path="debugLSP" type="boolean" default={false}>
  Enable debug logging for LSP operations (top-level config)
</ParamField>

## Language-specific configuration

### Go (gopls)

```json theme={null}
{
  "lsp": {
    "go": {
      "disabled": false,
      "command": "gopls"
    }
  }
}
```

**Installation:**

```bash theme={null}
go install golang.org/x/tools/gopls@latest
```

**Features:**

* Type checking
* Import errors
* Unused variables
* Build errors
* Module issues

***

### TypeScript (typescript-language-server)

```json theme={null}
{
  "lsp": {
    "typescript": {
      "disabled": false,
      "command": "typescript-language-server",
      "args": ["--stdio"]
    }
  }
}
```

**Installation:**

```bash theme={null}
npm install -g typescript-language-server typescript
```

**Features:**

* Type errors
* Missing imports
* Unused code
* Strict mode violations
* TSConfig issues

<Note>
  OpenCode automatically opens `tsconfig.json` and `package.json` to help TypeScript servers initialize properly.
</Note>

***

### JavaScript (typescript-language-server)

```json theme={null}
{
  "lsp": {
    "javascript": {
      "disabled": false,
      "command": "typescript-language-server",
      "args": ["--stdio"]
    }
  }
}
```

Same server as TypeScript, works with `jsconfig.json`.

***

### Python (pyright)

```json theme={null}
{
  "lsp": {
    "python": {
      "disabled": false,
      "command": "pyright-langserver",
      "args": ["--stdio"]
    }
  }
}
```

**Installation:**

```bash theme={null}
npm install -g pyright
```

**Features:**

* Type checking (with type hints)
* Import resolution
* Undefined variables
* Syntax errors

**Alternative: pylsp**

```json theme={null}
{
  "lsp": {
    "python": {
      "command": "pylsp"
    }
  }
}
```

***

### Rust (rust-analyzer)

```json theme={null}
{
  "lsp": {
    "rust": {
      "disabled": false,
      "command": "rust-analyzer"
    }
  }
}
```

**Installation:**

```bash theme={null}
rustup component add rust-analyzer
```

**Features:**

* Borrow checker errors
* Type mismatches
* Lifetime errors
* Cargo build issues
* Macro expansion

***

### Java (jdtls)

```json theme={null}
{
  "lsp": {
    "java": {
      "disabled": false,
      "command": "/path/to/jdtls",
      "args": ["-data", "/path/to/workspace"]
    }
  }
}
```

**Installation:**
Download Eclipse JDT Language Server from [eclipse.org/jdtls](https://projects.eclipse.org/projects/eclipse.jdt.ls)

***

### C/C++ (clangd)

```json theme={null}
{
  "lsp": {
    "c": {
      "disabled": false,
      "command": "clangd"
    },
    "cpp": {
      "disabled": false,
      "command": "clangd"
    }
  }
}
```

**Installation:**

```bash theme={null}
# macOS
brew install llvm

# Ubuntu
sudo apt install clangd
```

## How LSP integration works

<Steps>
  <Step title="Server initialization">
    When OpenCode starts:

    1. Reads LSP configuration from `.opencode.json`
    2. Launches configured language servers
    3. Sends `initialize` request with workspace info
    4. Waits for server to be ready
  </Step>

  <Step title="File operations">
    When AI tools interact with files:

    1. `textDocument/didOpen` sent when file is first accessed
    2. `textDocument/didChange` sent when file is modified
    3. `textDocument/didClose` sent when no longer needed
  </Step>

  <Step title="Diagnostic collection">
    Language servers send diagnostics:

    1. `textDocument/publishDiagnostics` received asynchronously
    2. Diagnostics cached per file URI
    3. Available to AI via `diagnostics` tool
    4. Automatically included after file modifications
  </Step>

  <Step title="Diagnostic display">
    Diagnostics shown in tool responses:

    1. After `view` tool (if file has issues)
    2. After `write` tool (new errors/warnings)
    3. After `edit` tool (validation)
    4. On-demand via `diagnostics` tool
  </Step>
</Steps>

## File lifecycle management

### Automatic file opening

OpenCode intelligently manages file state:

```
AI: view src/main.ts
→ File opened in LSP if not already open
→ Diagnostics collected
→ Shown in response:

<file>
...
</file>

<file_diagnostics>
Error: src/main.ts:42:5 [typescript][2304] Cannot find name 'foo'
</file_diagnostics>
```

### Persistent sessions

Files remain open across multiple operations:

```
1. AI: view src/utils.ts
   → Opens file in LSP
   
2. AI: edit src/utils.ts ...
   → File already open
   → Sends didChange notification
   → New diagnostics published
   
3. AI: write src/utils.ts ...
   → Updates open file
   → Fresh diagnostics
```

### Smart initialization

For TypeScript/JavaScript projects, OpenCode:

1. **Opens configuration files** first:
   * `tsconfig.json`
   * `package.json`
   * `jsconfig.json`

2. **Opens sample source files** to help server index:
   * Finds up to 5 `.ts`/`.tsx`/`.js`/`.jsx` files
   * Skips `node_modules` and build directories
   * Accelerates initial diagnostics

## Server detection and optimization

OpenCode detects server types and optimizes accordingly:

<Tabs>
  <Tab title="TypeScript">
    **Detected by:** Command contains `typescript`, `vtsls`, or `tsserver`

    **Optimizations:**

    * Opens key config files (tsconfig.json, package.json)
    * Opens sample source files to help with indexing
    * Uses document symbol requests for readiness checks
    * Waits longer for initial diagnostics
  </Tab>

  <Tab title="Go">
    **Detected by:** Command contains `gopls`

    **Optimizations:**

    * Opens go.mod and go.sum files
    * Uses workspace/symbol for readiness checks
    * Fast initialization
  </Tab>

  <Tab title="Rust">
    **Detected by:** Command contains `rust-analyzer`

    **Optimizations:**

    * Opens Cargo.toml and Cargo.lock
    * Uses workspace/symbol for readiness checks
    * Handles Cargo metadata loading
  </Tab>

  <Tab title="Generic">
    **Other servers** use standard initialization:

    * Standard LSP initialize sequence
    * Generic readiness checks
    * Basic file lifecycle
  </Tab>
</Tabs>

## Diagnostic format

Diagnostics are displayed in a structured format:

```
<file_diagnostics>
Error: /path/to/file.ts:42:10 [typescript][2304] Cannot find name 'variableName'
Warn: /path/to/file.ts:56:5 [typescript][6133] 'unused' is declared but never used
Hint: /path/to/file.ts:12:8 [typescript] Parameter 'x' can be simplified
</file_diagnostics>

<project_diagnostics>
Error: /path/to/other.ts:12:1 [gopls] expected declaration, found 'IDENT'
</project_diagnostics>

<diagnostic_summary>
Current file: 1 errors, 1 warnings
Project: 1 errors, 0 warnings
</diagnostic_summary>
```

### Severity levels

<AccordionGroup>
  <Accordion title="Error" icon="circle-xmark" defaultOpen>
    Code will not compile or has serious issues

    **Examples:**

    * Syntax errors
    * Type mismatches
    * Undefined references
    * Import failures
  </Accordion>

  <Accordion title="Warning" icon="triangle-exclamation">
    Potential issues or questionable code

    **Examples:**

    * Unused variables
    * Deprecated APIs
    * Type assertions
    * Missing error handling
  </Accordion>

  <Accordion title="Info" icon="circle-info">
    Informational messages

    **Examples:**

    * Documentation
    * Suggestions
    * Code metrics
  </Accordion>

  <Accordion title="Hint" icon="lightbulb">
    Improvement suggestions

    **Examples:**

    * Simplifications
    * Performance tips
    * Style consistency
  </Accordion>
</AccordionGroup>

### Diagnostic tags

Additional metadata:

* **Unnecessary**: Code that can be removed (e.g., unused imports)
* **Deprecated**: Using deprecated APIs or features

## AI tool integration

The AI assistant accesses diagnostics through the `diagnostics` tool:

### Get file diagnostics

```json theme={null}
{
  "tool": "diagnostics",
  "parameters": {
    "file_path": "/path/to/file.ts"
  }
}
```

### Get project diagnostics

```json theme={null}
{
  "tool": "diagnostics",
  "parameters": {
    "file_path": ""
  }
}
```

### Automatic inclusion

Diagnostics are automatically shown:

1. **After view**: If file has errors/warnings
2. **After write**: Shows new diagnostics
3. **After edit**: Validates changes
4. **After patch**: Shows diagnostics for all modified files

## Common workflows

### Debugging errors

<Steps>
  <Step title="Get diagnostics">
    AI: Use `diagnostics` tool to see all errors
  </Step>

  <Step title="Examine code">
    AI: Use `view` on files with errors
  </Step>

  <Step title="Fix issues">
    AI: Use `edit` or `write` to correct errors
  </Step>

  <Step title="Verify fix">
    New diagnostics automatically shown after file modification
  </Step>
</Steps>

### Type error resolution

```
User: Fix the type errors in src/api.ts

AI workflow:
1. diagnostics tool → identify specific errors
2. view src/api.ts → understand code context
3. edit src/api.ts → fix type issues
4. Diagnostics automatically updated
5. If errors remain, iterate
```

### Pre-commit validation

```
User: Check for errors before committing

AI workflow:
1. diagnostics tool (no file_path) → project-wide scan
2. Report errors by severity
3. Suggest fixes for critical issues
4. Verify no errors remain
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Server not starting" icon="power-off">
    Check:

    * Command path is correct: `which gopls`
    * Server is installed and in PATH
    * No conflicting servers running
    * Enable debug logging: `"debugLSP": true`
    * Check logs: `opencode -d`
  </Accordion>

  <Accordion title="No diagnostics appearing" icon="eye-slash">
    Verify:

    * Server initialized successfully (check logs)
    * File is in workspace directory
    * File type matches language ID
    * Server has finished indexing (may take time for large projects)
    * Try closing and reopening file
  </Accordion>

  <Accordion title="Stale diagnostics" icon="clock">
    Possible causes:

    * File modified outside OpenCode
    * Server hasn't processed changes yet
    * Cache not updated

    Solutions:

    * Wait for server to process (5-10 seconds)
    * Use `diagnostics` tool to refresh
    * Restart OpenCode if persistent
  </Accordion>

  <Accordion title="TypeScript server slow" icon="hourglass">
    TypeScript can be slow on large projects:

    * Initial indexing takes time
    * Configure smaller `include` in tsconfig.json
    * Exclude `node_modules` explicitly
    * Use project references for monorepos
    * Consider increasing system resources
  </Accordion>

  <Accordion title="Multiple servers for same language" icon="copy">
    If you have multiple configs for same language:

    * Last configured server wins
    * Disable unused servers: `"disabled": true`
    * Use different language IDs if needed
  </Accordion>
</AccordionGroup>

## Performance considerations

<CardGroup cols={2}>
  <Card title="Lazy file opening" icon="door-open">
    OpenCode opens files on-demand:

    * Only when AI tools access them
    * Reduces memory usage
    * Faster startup
    * Less server load
  </Card>

  <Card title="File closing" icon="door-closed">
    Files remain open until:

    * Session ends
    * Explicit close
    * OpenCode shutdown

    Keeps diagnostics fresh
  </Card>

  <Card title="Diagnostic caching" icon="database">
    Diagnostics are cached:

    * Per-file URI
    * Updated on publishDiagnostics
    * Shared across tools
    * Memory-efficient
  </Card>

  <Card title="Async updates" icon="rotate">
    Diagnostics arrive asynchronously:

    * Non-blocking operations
    * Background processing
    * Timeout after 5 seconds
    * Graceful degradation
  </Card>
</CardGroup>

## Limitations

<Warning>
  Current limitations of LSP integration:
</Warning>

* **Diagnostics only**: Other LSP features (completions, hover, etc.) not exposed to AI
* **Single workspace**: One workspace root per session
* **File-based**: Works with file:// URIs only
* **No refactoring**: Code actions not yet available
* **Limited customization**: Server-specific options not configurable

## Future enhancements

Planned improvements:

* **Code actions**: Enable AI to apply quick fixes
* **Completions**: Suggest completions to AI
* **Hover information**: Provide type info and docs
* **Go to definition**: Navigate code references
* **Workspace symbols**: Better code navigation
* **Semantic tokens**: Enhanced code understanding
* **Server-specific configs**: Per-server initialization options

## Best practices

<CardGroup cols={2}>
  <Card title="Install recommended servers" icon="download">
    Use official language servers:

    * They're well-maintained
    * Best diagnostic quality
    * Regular updates
    * Good documentation
  </Card>

  <Card title="Configure project properly" icon="gear">
    Ensure project config files exist:

    * tsconfig.json for TypeScript
    * go.mod for Go
    * Cargo.toml for Rust
    * Helps servers understand project
  </Card>

  <Card title="Monitor performance" icon="gauge-high">
    Watch for slow servers:

    * Enable debug logging temporarily
    * Check initialization time
    * Monitor memory usage
    * Tune server settings
  </Card>

  <Card title="Use diagnostics proactively" icon="magnifying-glass">
    Check regularly during development:

    * Before commits
    * After major changes
    * When debugging
    * During code review
  </Card>

  <Card title="Keep servers updated" icon="arrows-rotate">
    Update regularly:

    ```bash theme={null}
    go install golang.org/x/tools/gopls@latest
    npm update -g typescript-language-server
    rustup update
    ```
  </Card>

  <Card title="Debug systematically" icon="bug">
    When issues arise:

    1. Enable `debugLSP: true`
    2. Run `opencode -d`
    3. Check server logs
    4. Test server independently
    5. Review configuration
  </Card>
</CardGroup>

## Debug mode

Enable detailed LSP logging:

```json theme={null}
{
  "debugLSP": true,
  "debug": true
}
```

Then run:

```bash theme={null}
opencode -d
```

Debug output includes:

* Server initialization
* File open/close events
* Diagnostic publications
* Server responses
* Error messages

<Note>
  Debug logs are written to `~/.opencode/logs/` and shown in the logs page (`Ctrl+L`)
</Note>

## Next steps

<CardGroup cols={2}>
  <Card title="Diagnostics tool" href="/features/ai-tools#diagnostics" icon="stethoscope">
    Learn how to use the diagnostics tool
  </Card>

  <Card title="Configuration" href="/reference/configuration" icon="gear">
    Complete configuration reference
  </Card>

  <Card title="AI tools" href="/features/ai-tools" icon="wrench">
    Explore all available AI tools
  </Card>

  <Card title="LSP Specification" href="https://microsoft.github.io/language-server-protocol/" icon="book">
    Official LSP documentation
  </Card>
</CardGroup>
