Skip to content

LSP Code Intelligence

📝 Course Notes

Key concepts from this lesson:

5.19 LSP Server Notes


When AI helps you modify code, does it not know where functions are defined, which variables reference what, or which interfaces have implementations?

LSP (Language Server Protocol) solves this problem. It gives AI an "IDE brain," upgrading AI from "reading text" to "understanding code structure."

🤔 What is LSP?

LSP is a standard protocol proposed by Microsoft for communication between editors and language servers. The "Go to Definition" and "Find References" features you use in VS Code work through LSP.

OpenCode brings the same capabilities to terminal AI assistants.

What You'll Learn

🎯 Lesson Objectives

  • Understand how LSP gives AI code intelligence
  • Use 9 LSP operations: go to definition, find references, hover info, etc.
  • Learn about OpenCode's 30+ built-in language servers
  • Customize or disable LSP servers
  • Troubleshoot LSP connection issues

Your Current Challenges

  • "AI doesn't know where this function is defined, it can only guess"
  • "Want to know where a variable is used, but AI can't find them all"
  • "AI doesn't understand dependencies when modifying code, prone to errors"
  • "Wish I could quickly navigate and view definitions like in an IDE"

When to Use This Feature

  • Need to understand the structure of a large codebase
  • Need to find definitions and references of functions/variables
  • Want to understand impact scope before refactoring
  • Need to get type information and documentation comments

🎒 Prerequisites

  • [ ] Completed 5.1a Configuration Basics
  • [ ] Can start OpenCode normally
  • [ ] Have code files in your project (OpenCode will automatically detect language type)

Core Concept

The LSP workflow is simple:

  1. OpenCode detects the file type you open (e.g., .ts, .py, .go)
  2. Automatically starts the corresponding language server
  3. When AI needs to understand code, it sends requests to the language server
  4. Language server returns precise code intelligence data

Most of the time you don't need any configuration, it works out of the box.

AspectPlain Text Search (grep)LSP Code Intelligence
Search MethodString matchingSemantic symbol matching
AccuracyMay have false positives (same-name variables)Precise positioning
ScopeDoesn't understand scopeUnderstands scope and import relationships
Type InformationNoneProvides complete type signatures
Overload DistinctionCannot distinguishCan distinguish function overloads

Built-in Language Servers

OpenCode has 30+ language servers built-in, ready to use.

Mainstream Languages

LSP ServerExtensionsRequirements
typescript.ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .ctstypescript dependency in project
pyright.py, .pyiAuto-installs pyright
gopls.gogo command available
rust (rust-analyzer).rsrust-analyzer command available
jdtls.javaJava SDK installed (21+)
kotlin-ls.kt, .ktsAuto-downloads and installs
clangd.c, .cpp, .cc, .cxx, .c++, .h, .hpp, .hh, .hxx, .h++Auto-downloads and installs
csharp (csharp-ls).cs.NET SDK installed
fsharp (fsautocomplete).fs, .fsi, .fsx, .fsscript.NET SDK installed
sourcekit-lsp.swift, .objc, .objcppSwift installed (Xcode on macOS)
dart.dartdart command available

Other Languages

LSP ServerExtensionsRequirements
ruby-lsp (rubocop).rb, .rake, .gemspec, .ruruby and gem commands available
elixir-ls.ex, .exselixir command available
zls.zig, .zonzig command available
lua-ls.luaAuto-downloads and installs
php intelephense.phpAuto-installs intelephense
ocaml-lsp.ml, .mliocamllsp command available
gleam.gleamgleam command available
clojure-lsp.clj, .cljs, .cljc, .ednclojure-lsp command available
nixd.nixnixd command available
haskell-language-server.hs, .lhshaskell-language-server-wrapper command available
deno.ts, .tsx, .js, .jsx, .mjsdeno command available (auto-detects deno.json)

Frontend Frameworks

LSP ServerExtensionsRequirements
vue.vueAuto-installs vue-language-server
svelte.svelteAuto-installs svelte-language-server
astro.astroAuto-installs astro-language-server

Tools and Configuration

LSP ServerExtensionsPurpose
eslint.ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .vueCode linting
oxlint.ts, .tsx, .js, .jsx, etc. + .vue, .astro, .svelteFast linter
biome.ts, .tsx, .js, .jsx, .json, .css, .vue, .astro, .svelte, etc.Formatting + linter
yaml-ls.yaml, .ymlYAML support
bash.sh, .bash, .zsh, .kshShell scripts
terraform.tf, .tfvarsIaC configuration
prisma.prismaDatabase schema
texlab.tex, .bibLaTeX documents
tinymist.typ, .typcTypst typesetting
dockerfile.dockerfile, DockerfileDocker configuration

Auto-Installation Notes

Most servers will be automatically downloaded and installed on first use, in the ~/.local/share/opencode/bin/ directory.

A few servers (like rust-analyzer, dart, sourcekit-lsp) require you to install the corresponding toolchain in advance.

Set the environment variable OPENCODE_DISABLE_LSP_DOWNLOAD=true to disable auto-download.


9 LSP Operations

OpenCode provides 9 LSP operations that AI will automatically call as needed. You can also explicitly request them in conversations.

1. goToDefinition: Go to Definition

Find the definition location of functions, classes, and variables.

You: Find the definition of the formatDate function on line 15 of src/utils/format.ts

AI will call LSP's goToDefinition and return the file and line number where the definition is located.

2. findReferences: Find References

Find all usages of a symbol throughout the project. Especially useful before refactoring.

You: Find where the User type on line 20 of src/api/user.ts is used

3. hover: Hover Information

Get information like type signatures and documentation comments for symbols.

You: View the type signature of the login function on line 45 of src/services/auth.ts

4. documentSymbol: Document Symbols

List all symbols in a file (functions, classes, variables, etc.) for quick file structure browsing.

You: List all functions and classes in src/controllers/user.ts

Search for symbols across the entire project. Results are filtered to classes, functions, methods, interfaces, variables, constants, structs, and enums, returning up to 10 results.

You: Search for all classes containing "UserService" in the entire project

6. goToImplementation: Go to Implementation

Find concrete implementations of interfaces or abstract classes.

You: Find all implementations of the Repository interface on line 10 of src/interfaces/Repository.ts

7. prepareCallHierarchy: Prepare Call Hierarchy

Get call hierarchy information for a position, preparing for incoming/outgoing call analysis.

8. incomingCalls: Incoming Calls

Find all places that call the current function. Use this to evaluate impact scope before modifying a function.

You: Find where the validateEmail function on line 20 of src/utils/validator.ts is called

9. outgoingCalls: Outgoing Calls

Find all other functions called by the current function for dependency analysis.

You: View which other functions the processPayment function on line 50 of src/services/payment.ts calls
LSP Tool Parameter Description

All LSP operations require three parameters:

  • filePath: File path (absolute or relative)
  • line: Line number (1-based, same as what you see in editor)
  • character: Character offset (1-based)

AI will automatically fill these parameters, you just need to describe your needs in natural language.


Using LSP in Conversations

AI Automatic Usage

Most of the time you don't need to specifically mention LSP, AI will automatically judge when to use it:

You: Where is this formatDate function defined?

AI: [Automatically calls lsp goToDefinition]
    formatDate is defined on line 42 of src/utils/date.ts...

Manual Request

You can also explicitly ask AI to use LSP:

You: Use LSP to find all references to the UserService class
You: Use LSP to view the symbol list of config.ts file
You: Use LSP to analyze the call relationships of the processOrder function

Follow Along: Configuring LSP

Step 1: Verify LSP is Working

Why Most of the time LSP works out of the box, let's verify first.

Enter in an OpenCode conversation:

Help me view the symbol information on line 1 of src/index.ts

You should see: AI returned type information or documentation comments, indicating LSP is working.

If you see No LSP server available for this file type, it means the corresponding language server hasn't started. Check if the "Requirements" column conditions are met.


Step 2: Disable Unneeded Servers

Why Some projects may trigger multiple servers simultaneously (e.g., TypeScript and Deno), causing conflicts.

Disable specific servers in opencode.json:

json
{
  "lsp": {
    "deno": {
      "disabled": true
    }
  }
}

To globally disable all LSP (e.g., when debugging performance issues):

json
{
  "lsp": false
}

You should see: Disabled servers no longer start, logs will show LSP server xxx is disabled.


Step 3: Add Custom LSP Servers

Why If the language you're using doesn't have built-in support, you can configure it yourself.

json
{
  "lsp": {
    "my-lang": {
      "command": ["my-lsp-server", "--stdio"],
      "extensions": [".myl"],
      "env": {
        "MY_ENV": "value"
      }
    }
  }
}

Configuration field description:

FieldTypeRequiredDescription
commandstring[]✅ (when enabling)Startup command and arguments. Can be omitted when disabled, just need { "disabled": true }
extensionsstring[]✅ (custom servers)List of file extensions
disabledbooleanWhether to disable (default false)
envobjectEnvironment variables
initializationobjectLSP initialization parameters

Note

Custom LSP servers must provide the extensions field, otherwise configuration validation will fail: For custom LSP servers, 'extensions' array is required.

Built-in servers can omit extensions since they already have default values.

You should see: When opening .myl files, AI can use LSP operations.


Checklist ✅

  • [ ] Understand LSP's purpose: Upgrade AI from "reading text" to "understanding code structure"
  • [ ] Know OpenCode has 30+ built-in language servers, most work out of the box
  • [ ] Can name at least 3 LSP operations (go to definition, find references, hover info...)
  • [ ] Know how to disable specific LSP servers
  • [ ] Know how to add custom LSP servers

Common Issues

SymptomCauseSolution
No LSP server available for this file typeCorresponding language server not installed or conditions not metCheck "Requirements" column, install corresponding toolchain
LSP server starts in wrong directoryProject root directory detection incorrectEnsure project root has marker files (like package.json, go.mod)
File not found: /path/to/file.tsFile path errorUse path relative to project root
Long wait on first useServer needs initialization and indexing on first startNormal behavior, subsequent use will be much faster
TypeScript and Deno server conflictBoth servers process .ts filesDisable the unneeded one in opencode.json
High LSP memory usageLarge project indexing consumes memoryDisable unneeded servers, or set "lsp": false
Custom server fails to startMissing environment variables or incorrect command pathAdd env field in configuration, use absolute paths

Additional Information

PHP Intelephense License

PHP Intelephense provides advanced features through a license key. You can place the license key in a text file:

  • macOS/Linux: $HOME/intelephense/licence.txt
  • Windows: %USERPROFILE%/intelephense/licence.txt

The file should contain only the license key, nothing else.

Experimental Feature: ty Python Server

Set the environment variable OPENCODE_EXPERIMENTAL_LSP_TY=1 to enable the experimental ty Python server, replacing the default pyright. When enabled, pyright will be automatically disabled.

Experimental Feature

The ty server is still in experimental stage and may change with versions. For production environments, continue using pyright.


Lesson Summary

Core ConceptDescription
LSP PurposeGive AI IDE-level code intelligence to understand code semantics
Auto DetectionAutomatically starts corresponding server based on file extension
Built-in Support30+ language servers, most work out of the box
9 OperationsGo to definition, find references, hover info, symbol search, go to implementation, call hierarchy, etc.
Configurationopencode.json's lsp field, supports disabling and customization

Remember: Most of the time you don't need to configure anything, LSP will work automatically. Only modify configuration when you encounter issues or need customization.


Next Lesson Preview

Next lesson we'll learn about Context Compaction.

You'll learn:

  • Context compaction trigger mechanism
  • What Context percentage means
  • How to manually trigger compaction
  • Impact of compaction on conversation quality


Appendix: Source Code Reference

Click to expand source code locations

Last updated: 2026-02-14

FeatureFile PathLine Numbers
LSP namespace and core logicsrc/lsp/index.ts14-485
LSP client acquisition and server startupsrc/lsp/index.ts177-262
goToDefinition implementationsrc/lsp/index.ts386-395
findReferences implementationsrc/lsp/index.ts397-407
hover implementationsrc/lsp/index.ts303-317
workspaceSymbol (filtering and 10-result limit)src/lsp/index.ts359-369
documentSymbol implementationsrc/lsp/index.ts371-384
goToImplementation implementationsrc/lsp/index.ts409-418
prepareCallHierarchy implementationsrc/lsp/index.ts420-429
incomingCalls implementationsrc/lsp/index.ts431-442
outgoingCalls implementationsrc/lsp/index.ts444-455
diagnostics informationsrc/lsp/index.ts291-301
LSP tool definition (9 operations)src/tool/lsp.ts10-96
LSP tool description textsrc/tool/lsp.txt1-20
LSP configuration Schemasrc/config/config.ts1115-1150
LSPServer interface definitionsrc/lsp/server.ts53-59
TypeScript serversrc/lsp/server.ts89-116
Python server (pyright)src/lsp/server.ts505-557
Go server (gopls)src/lsp/server.ts358-398
Rust server (rust-analyzer)src/lsp/server.ts847-891
Experimental ty Python serversrc/lsp/server.ts441-503
Experimental server filtering logicsrc/lsp/index.ts64-77
SymbolKind filtering (workspaceSymbol)src/lsp/index.ts319-357

Key Types:

  • LSP.Range: Code range (start/end positions)
  • LSP.Symbol: Symbol information (name, type, location)
  • LSP.DocumentSymbol: Document symbol (contains child symbols)
  • LSP.Status: LSP server status (id, name, root, status)
  • LSPServer.Info: Server definition (id, extensions, root, spawn)

Key Constants:

  • operations: Enumerated list of 9 LSP operations (src/tool/lsp.ts lines 10-20)
  • kinds: Symbol types filtered for workspaceSymbol (Class, Function, Method, Interface, Variable, Constant, Struct, Enum)

Environment Variables:

  • OPENCODE_DISABLE_LSP_DOWNLOAD: Disable auto-download of LSP servers
  • OPENCODE_EXPERIMENTAL_LSP_TY: Enable experimental ty Python server