Skip to content

reindervdw-cmi/opencode-tools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

agentic-lsp

OpenCode custom tools that expose LSP capabilities to AI agents.

Overview

This project provides OpenCode custom tools that give AI agents the same language-aware capabilities an IDE has. The tools act as LSP (Language Server Protocol) clients — they spawn existing language servers (like gopls, typescript-language-server, ty, rust-analyzer) as child processes and communicate via stdio JSON-RPC.

With these tools, an agent can:

  • Jump to symbol definitions across a codebase
  • Find all references to a variable, function, or type
  • Get type information and documentation on hover
  • Rename symbols safely across an entire workspace
  • List and execute code actions (quick fixes, refactorings)

How It Works

The tools use a warm server pool architecture for performance. Language servers are spawned on first use and kept alive for 5 minutes after the last request. During that window, subsequent requests reuse the same server instance — no cold-start delay. Each server is keyed by (language server ID, workspace root), so different projects get isolated servers.

When the idle timeout expires, the server is gracefully shut down to free resources.

Supported Languages

Language Language Server Install
Go gopls go install golang.org/x/tools/gopls@latest
TypeScript / JavaScript typescript-language-server npm install -g typescript-language-server typescript
Python ty pip install ty
Rust rust-analyzer rustup component add rust-analyzer

Installation

  1. Copy (or symlink) the .opencode/ directory into your project root, or place it in ~/.config/opencode/ for global use.

  2. Run npm install in the agentic-lsp directory to install dependencies:

    cd path/to/agentic-lsp
    npm install
  3. Install the language servers you need (see table above).

Tools Reference

lsp_definition

Purpose: Find where a symbol is defined.

Argument Type Required Description
file string Yes Absolute path to the file containing the symbol
line number Yes Zero-based line number
character number Yes Zero-based character offset on the line

Example:

lsp_definition(file="/home/user/project/src/main.go", line=42, character=15)
→ /home/user/project/src/handler.go:10:5

lsp_references

Purpose: Find all references to a symbol across the workspace.

Argument Type Required Description
file string Yes Absolute path to the file containing the symbol
line number Yes Zero-based line number
character number Yes Zero-based character offset on the line
includeDeclaration boolean No Include the symbol's declaration in results (default: true)

Example:

lsp_references(file="/home/user/project/src/utils.ts", line=5, character=16)
→ Found 3 references:
  /home/user/project/src/utils.ts:6:17
  /home/user/project/src/index.ts:12:8
  /home/user/project/src/tests/utils.test.ts:8:22

lsp_hover

Purpose: Get type information and documentation for a symbol.

Argument Type Required Description
file string Yes Absolute path to the file containing the symbol
line number Yes Zero-based line number
character number Yes Zero-based character offset on the line

Example:

lsp_hover(file="/home/user/project/src/server.ts", line=20, character=10)
→ (method) http.Server.listen(port: number, callback?: () => void): http.Server
  
  Start a server listening for connections.

lsp_rename

Purpose: Rename a symbol across the entire workspace.

Argument Type Required Description
file string Yes Absolute path to the file containing the symbol to rename
line number Yes Zero-based line number
character number Yes Zero-based character offset on the line
newName string Yes The new name for the symbol
apply boolean No If true, apply changes to disk; if false (default), preview only

Example (preview):

lsp_rename(file="/home/user/project/src/api.ts", line=8, character=9, newName="fetchUserData")
→ Rename preview - files affected:
  src/api.ts: 2 edits
  src/routes/users.ts: 4 edits
  src/tests/api.test.ts: 3 edits

  Use apply=true to apply these changes.

Example (apply):

lsp_rename(file="/home/user/project/src/api.ts", line=8, character=9, newName="fetchUserData", apply=true)
→ Rename applied successfully. Modified files:
  - src/api.ts (2 edits)
  - src/routes/users.ts (4 edits)
  - src/tests/api.test.ts (3 edits)

lsp_codeactions

Purpose: Get available code actions (quick fixes, refactorings) for a range.

Argument Type Required Description
file string Yes Absolute path to the file
startLine number Yes Zero-based start line of the range
startCharacter number Yes Zero-based start character of the range
endLine number Yes Zero-based end line of the range
endCharacter number Yes Zero-based end character of the range
execute number No If provided, execute the action at this index (1-indexed)

Example (list actions):

lsp_codeactions(file="/home/user/project/src/main.go", startLine=15, startCharacter=0, endLine=15, endCharacter=50)
→ Available code actions:
  1. [quickfix] Organize imports
  2. [refactor.extract] Extract function
  3. [refactor.inline] Inline variable

Example (execute action):

lsp_codeactions(file="/home/user/project/src/main.go", startLine=15, startCharacter=0, endLine=15, endCharacter=50, execute=1)
→ Executed "Organize imports". Modified files:
  - src/main.go

Architecture

.opencode/tools/
├── lib/
│   ├── types.ts           # Shared LSP types
│   ├── language-config.ts # Language server spawn configs
│   ├── lsp-client.ts      # Core LSP JSON-RPC client
│   └── server-pool.ts     # Warm server pool (5 min idle timeout)
├── lsp_definition.ts      # Go to Definition
├── lsp_references.ts      # Find References
├── lsp_hover.ts           # Hover / type info
├── lsp_rename.ts          # Rename symbol
└── lsp_codeactions.ts     # Code actions / quick fixes

Library Components

  • types.ts — Shared TypeScript type definitions for LSP positions, ranges, locations, text edits, code actions, and diagnostics.

  • language-config.ts — Configuration for each supported language server, including the command to spawn it, supported file extensions, and LSP language ID.

  • lsp-client.ts — The core LSP client that spawns a language server process, establishes a JSON-RPC connection over stdio, sends the LSP initialize handshake, and provides methods for opening documents and sending requests.

  • server-pool.ts — Manages a pool of warm language server instances. Servers are reused for subsequent requests to the same workspace and automatically shut down after 5 minutes of inactivity.

Note on Positions

All line and character arguments are zero-based, as per the LSP specification:

  • Line 0 is the first line of the file
  • Character 0 is the first character on a line

Output locations (in tool results) are formatted as 1-based for human readability (e.g., file.ts:10:5 means line 10, column 5).

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors