Overview
Oh My OpenCode provides 6 LSP (Language Server Protocol) tools for code navigation, symbol lookup, diagnostics, and safe renaming. These tools manage their own LSP server processes and provide formatted output optimized for LLM consumption. Source:src/tools/lsp/
Architecture
Custom LSP client stack (does NOT use OpenCode’s built-in LSP):Tools
lsp_goto_definition
Jump to symbol definition.Absolute path to file
Line number (1-based)
Column position (0-based)
Location(s) in format: Returns
{file}:{line}:{char}Example:"No definition found" if symbol has no definition.goto-definition-tool.ts:7
lsp_find_references
Find all usages/references of a symbol across the workspace.Absolute path to file
Line number (1-based)
Column position (0-based)
Include the declaration itself (default:
true)List of locations, one per lineExample:If more than 100 references found (configurable), shows:
find-references-tool.ts:8
Configuration: DEFAULT_MAX_REFERENCES = 100 in constants.ts
lsp_symbols
Get document outline or search workspace symbols.Absolute path to file
Symbol scope:
"document" | "workspace"document: Outline of current fileworkspace: Search across all files
Search query (for workspace scope)Example:
"handleClick" finds all symbols matching patternMax symbols to return (default: 50)
Symbol list with kind and locationExample:
symbols-tool.ts
lsp_diagnostics
Get errors, warnings, and hints from language server BEFORE running build.Absolute path to file
Filter by severity:
"error" | "warning" | "information" | "hint" | "all"Default: "all"Diagnostics list with severity, line, and messageExample:If more than 50 diagnostics (configurable), shows:
diagnostics-tool.ts:8
Configuration: DEFAULT_MAX_DIAGNOSTICS = 50 in constants.ts
lsp_prepare_rename
Validate if rename is possible before applying. Use BEFORElsp_rename.
Absolute path to file
Line number (1-based)
Column position (0-based)
Validation resultSuccess:Failure:
rename-tools.ts:8
lsp_rename
Rename symbol across entire workspace. APPLIES changes to all files.Absolute path to file
Line number (1-based)
Column position (0-based)
New symbol name
Rename result with file changesSuccess:No changes:
rename-tools.ts:32
Server Resolution
LSP servers are resolved using:- Custom config:
.opencode/lsp.json(user overrides) - Built-in definitions: 40+ servers synced from OpenCode’s
server.ts - Language mappings: File extension → language ID → server
.opencode/lsp.json):
Supported Languages
40+ languages with built-in server definitions:- JavaScript/TypeScript:
typescript-language-server - Python:
pylsp,pyright - Go:
gopls - Rust:
rust-analyzer - Java:
jdtls - C/C++:
clangd - Ruby:
solargraph - PHP:
intelephense - …and many more
server-definitions.ts for complete list.
File Lifecycle
LSP requires files to be “opened” before requests:Error Handling
Common errors and solutions:Server Not Found
Server Crashed
/tmp/oh-my-opencode.log for server stderr output.
No Symbol at Position
- Position is not on a symbol
- Symbol is built-in (no source location)
- Language server doesn’t support the feature
Process Management
LSP servers are spawned per language and cleaned up on exit:- Process cleanup:
lsp-manager-process-cleanup.tsreaps orphan processes - Temp directory cleanup:
lsp-manager-temp-directory-cleanup.tsremoves temp files
Implementation Details
Key Files
| File | Purpose |
|---|---|
lsp-client-wrapper.ts | High-level entry: resolve server, open file, run request |
lsp-client.ts | File tracking, document sync (didOpen/didChange) |
lsp-client-connection.ts | JSON-RPC request/response/notification layer |
lsp-client-transport.ts | stdin/stdout byte-stream framing |
lsp-process.ts | Spawn + cleanup of LSP server process |
server-definitions.ts | 40+ builtin servers synced from OpenCode |
server-resolution.ts | Resolve which server handles a file extension |
lsp-formatters.ts | Format LSP responses into human-readable strings |
workspace-edit.ts | Apply WorkspaceEdit results to disk (for rename) |
Server Initialization
Response Formatting
Related Tools
- ast_grep_search: AST-aware pattern search (alternative to workspace symbols)
- grep: Regex search (simpler than LSP for some queries)
- hashline_edit: Safe editing (complement to LSP rename)
Best Practices
✅ Do
- Use
lsp_prepare_renamebeforelsp_renameto validate - Filter diagnostics by severity for focused error fixing
- Use workspace symbols for cross-file symbol search
- Check
/tmp/oh-my-opencode.logfor debugging server issues
❌ Don’t
- Don’t rename without preparation — validate first
- Don’t assume all servers support all features — some only provide diagnostics
- Don’t use for simple text search — use
greporast_grepfor pattern matching