MCPcopy Index your code
hub / github.com/blackwell-systems/agent-lsp

github.com/blackwell-systems/agent-lsp @v0.15.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.15.0 ↗ · + Follow
2,196 symbols 7,800 edges 278 files 1,329 documented · 61%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

agent-lsp

CI Coverage Languages mcp-assert: passing Agent Skills downloads

LSP 3.17 License Awesome MCP Servers Blackwell Systems

Code intelligence infrastructure for AI agents. 65 tools, 30 CI-verified languages, 24 agent workflows. Single Go binary.

curl -fsSL https://raw.githubusercontent.com/blackwell-systems/agent-lsp/main/install.sh | sh && agent-lsp init

What is it?

agent-lsp is an MCP server that orchestrates existing LSP servers (gopls, rust-analyzer, jdtls, etc.) into agent-native workflows.

Not an LSP server — it's an orchestration layer that manages language servers and exposes batch operations, speculative editing, and multi-step workflows via MCP tools.

Architecture: - Language servers (gopls, rust-analyzer, etc.) → provide code intelligence - agent-lsp (MCP server) → orchestrates workflows, maintains warm runtime - AI agents → consume via MCP protocol

Why agent-lsp?

Persistent warm runtime
Language servers stay indexed across agent sessions. First session: indexes workspace (~10s for typical projects). Subsequent sessions: instant. No cold-start penalty on each request.

Batch operations
blast_radius → one call returns all exports + all callers (test vs non-test partitioned). Without orchestration: 20+ sequential LSP calls.

Speculative editing
simulate_edit → preview changes in memory, check diagnostic delta, apply or discard. Test edits before touching disk.

Workflow orchestration
24 skills that chain LSP operations into complete pipelines: - /lsp-refactor → impact analysis → preview → apply → verify build → run tests - /lsp-safe-edit → preview → diagnostic diff → apply if safe - /lsp-verify → LSP diagnostics → build → test suite

Multi-language, single session
One agent-lsp process routes .go to gopls, .ts to tsserver, .py to pyright. No reconfiguration between projects. Session persists across files and repositories.

[!TIP] Token-optimized output: Tool responses encoded in GCF instead of JSON. 30-84% fewer tokens depending on tool (up to 92.7% with session dedup). 90.7% LLM comprehension accuracy where JSON averages 53.6%. See below for measured savings per tool.

How the pieces fit together: LSP (Language Server Protocol) is how editors get code intelligence: completions, diagnostics, go-to-definition. MCP (Model Context Protocol) is the standard way AI tools like Claude Code discover and call external tools. agent-lsp bridges the two: language server intelligence, accessible to AI agents.

Use it when

  • Building agentic code generation systems
  • Automating refactors across large codebases
  • CI tooling that needs programmatic code intelligence
  • Any workflow where sequential LSP calls are too slow or complex

What agents say

We asked AI agents to evaluate agent-lsp across 10 coding tasks (find callers, rename safely, preview edits, detect dead code) and write an honest assessment. Four different models, four independent evaluations, same conclusion:

Claude (Opus 4.6): "I would recommend agent-lsp for any workflow involving refactoring, impact analysis, or safe editing. The standout tools are blast_radius (blast radius in one call, with test/non-test partitioning that would take 5-10 grep commands to replicate), go_to_implementation (type-checked interface satisfaction that grep simply cannot do), and the simulation session workflow (speculative type-checking without touching disk, which has no grep/read equivalent at all)."

Cursor (auto): "I would recommend agent-lsp for heavy refactors and code navigation because the rename, references, implementations, call hierarchy, and simulation tools remove a lot of brittle grep/manual-edit work and make changes safer."

GPT-5.5 (via Codex): "I would recommend agent-lsp for symbol-aware work: references, implementations, rename previews, diagnostics, and large-file structure are materially faster and less error-prone than grep/read loops."

Gemini 2.5 Pro (via Gemini CLI): "I would highly recommend agent-lsp because it provides a level of semantic awareness that standard text-searching tools simply cannot match. The ability to perform high-confidence renames, find interface implementations, and preview the diagnostic impact of edits without writing to disk significantly reduces the risk of introducing regressions."

Tested, not assumed

Every other MCP-LSP implementation lists supported languages in a config file. None of them run the actual language server in CI to verify it works.

agent-lsp CI runs 30 real language servers against real fixture codebases on every push: Go, Python, TypeScript, Rust, Java, C, C++, C#, Ruby, PHP, Kotlin, Swift, Scala, Zig, Lua, Elixir, Gleam, Clojure, Dart, Terraform, Nix, Prisma, SQL, MongoDB, and more. When we say "works with gopls," that's a verified, automated claim, not a hope.

Speculative execution

Simulate changes in memory before writing to disk. No other MCP-LSP implementation has this.

preview_edit previews the diagnostic impact of any edit. You see exactly what breaks before the file is touched. simulate_chain evaluates a sequence of dependent edits (rename a function, update all callers, change the return type) and reports which step first introduces an error.

8 speculative execution tools. See docs/guide/speculative-execution.md for the full workflow.

Token savings

Structured LSP responses use 5-34x fewer tokens than grep/read on the same tasks. On HashiCorp Consul (319K lines), a blast-radius analysis uses 17.7MB via grep vs 841KB via LSP, reducing 5,534 tool calls to 119. Savings scale with codebase size. See docs/guide/token-savings.md for the full experiment across five codebases.

Token-optimized output (GCF)

Tool responses are encoded in GCF (Graph Compact Format) instead of JSON. GCF eliminates field-name repetition, identifier repetition, and per-record structural overhead.

Profile Tools Savings vs JSON
Tabular All 66 tools 30-51%
Graph blast_radius, find_callers, explore_symbol, find_references, type_hierarchy, cross_repo, detect_changes, list_symbols 79-84%
Graph + session dedup Same, via gcf-proxy --session 92.7% (5th call)

GCF is enabled by default. To revert to JSON:

export AGENT_LSP_OUTPUT_FORMAT=json

Benchmark: go run scripts/gcf-benchmark.go. See docs/guide/gcf-integration.md for architecture details.

GCF: gcformat.com · Spec · Go · Python · TypeScript · Playground

Why orchestration matters

AI agents make incorrect code changes because they can't see the full picture: who calls this function, what breaks if I rename it, does the build still pass. Language servers have the answers, but raw LSP tools require 20+ sequential calls and complex orchestration logic.

agent-lsp solves this by encoding correct multi-step operations into single calls and skills. blast_radius does what would take an agent 20+ calls in one. /lsp-refactor chains impact → preview → apply → verify → test without per-prompt orchestration.

Persistent daemon mode

Python and TypeScript projects need minutes of background indexing before find_references works. agent-lsp automatically spawns a persistent daemon broker that survives between sessions, so the workspace stays indexed. First session: daemon starts and indexes (~10s for FastAPI). Subsequent sessions: instant connection to the warm daemon. Auto-exits after 30 minutes of inactivity. Go, Rust, and other fast-indexing languages bypass this entirely (zero overhead).

Phase enforcement

Skills tell agents the correct order of operations. Phase enforcement makes the runtime block violations instead of trusting the agent to follow instructions.

When an agent activates a skill, every tool call is checked against the current phase's permissions. Calling apply_edit during blast-radius analysis doesn't silently proceed; it returns an error with specific recovery guidance ("complete the blast_radius phase first, allowed tools: [blast_radius, find_references]"). Phases advance automatically as the agent calls tools from later phases.

No other MCP tool provider enforces workflow ordering at runtime. See docs/guide/phase-enforcement.md.

Concurrency analysis

The inspector includes 4 concurrency checks that work across 25 languages in 4 concurrency families (goroutine, thread, async, actor):

  • Unrecovered concurrent entry: goroutines/threads/tasks without recovery
  • Unchecked shared state: bare type assertions on sync.Map, ConcurrentHashMap
  • Channel never closed: channels/queues created but never closed (goroutine leaks)
  • Shared field without sync: fields accessed from concurrent contexts without synchronization

blast_radius annotates symbols with sync_guarded: true when the parent type has a mutex. find_callers with cross_concurrent: true traces call chains through goroutine/thread boundaries. The /lsp-concurrency-audit skill produces a field-level safety report for any type.

Auto-diagnostics

Symbol edit tools (replace_symbol_body, insert_after_symbol, insert_before_symbol, safe_delete_symbol) automatically return errors_after and warnings_after counts. Agents know immediately whether an edit broke something without a separate get_diagnostics call.

safe_apply_edit combines preview + apply in one call: previews speculatively, applies to disk only if net_delta == 0 (no new errors). One tool call instead of three.

Works with

AI Tool Transport Setup
Claude Code stdio agent-lsp init
Cursor stdio agent-lsp init
Windsurf stdio agent-lsp init
Gemini CLI stdio agent-lsp init
Continue stdio agent-lsp init
Cline stdio agent-lsp init
Any MCP client HTTP+SSE agent-lsp --http --port 8080

See docs/getting-started/mcp-clients.md for copy-paste configs.

Skills

Raw tools get ignored. Skills get used. Each skill encodes the correct tool sequence so workflows actually happen without per-prompt orchestration instructions. Skills are available as AgentSkills slash commands and as MCP prompts via prompts/list / prompts/get for any MCP client.

See docs/guide/skills.md for full descriptions and usage guidance.

Before you change anything

Skill Purpose
/lsp-impact Blast-radius analysis before touching a symbol or file
/lsp-implement Find all concrete implementations of an interface
/lsp-dead-code Detect zero-reference exports before cleanup

Editing safely

Skill Purpose
/lsp-safe-edit Speculative preview before disk write; before/after diagnostic diff; surfaces code actions on errors
/lsp-simulate Test changes in-memory without touching the file
/lsp-edit-symbol Edit a named symbol without knowing its file or position
/lsp-edit-export Safe editing of exported symbols, finds all callers first
/lsp-rename prepare_rename safety gate, preview all sites, confirm, apply atomically

Getting started

Skill Purpose
/lsp-onboard First-session project onboarding: detect languages, map packages, find entry points and hotspots, check diagnostics

Understanding unfamiliar code

Skill Purpose
/lsp-explore "Tell me about this symbol": hover + implementations + call hierarchy + referenc

Extension points exported contracts — how you extend this code

NotificationSender (Interface)
NotificationSender abstracts MCP session notification dispatch. Implemented by mcpNotificationSender in cmd/agent-lsp/no [6 …
internal/notify/hub.go
ClientResolver (Interface)
ClientResolver resolves the appropriate [LSPClient] for a given file path. Implemented by [ServerManager]. [3 implementers]
pkg/lsp/lsp.go
ClientResolver (Interface)
ClientResolver resolves the appropriate LSPClient for a given file path. In single-server mode the manager returns the s [3 …
internal/lsp/resolver.go
Extension (Interface)
Extension is implemented by per-language extension packages. The current interface covers the four methods used by the e [3 …
internal/types/types.go
SessionExecutor (Interface)
SessionExecutor abstracts how a session acquires and releases LSP access. [1 implementers]
pkg/session/session.go
SessionExecutor (Interface)
SessionExecutor abstracts how a session acquires and releases LSP access. [1 implementers]
internal/session/types.go
NotifyFunc (FuncType)
NotifyFunc is called by the subscription handler to send resource update notifications. The caller (Wave 2 server.go) pr
internal/resources/subscriptions.go
Person (Interface)
(no doc)
test/fixtures/typescript/src/example.ts

Core symbols most depended-on inside this repo

ErrorResult
called by 261
internal/types/types.go
Log
called by 156
internal/logging/logging.go
boolPtr
called by 132
cmd/agent-lsp/helpers.go
NewLSPClient
called by 104
internal/lsp/client.go
makeCallToolResult
called by 78
cmd/agent-lsp/server.go
EncodeResult
called by 68
internal/tools/helpers.go
addToolWithPhaseCheck
called by 62
cmd/agent-lsp/server.go
toolArgsToMap
called by 60
cmd/agent-lsp/server.go

Shape

Function 1,663
Method 259
Struct 233
Class 19
Interface 11
TypeAlias 7
FuncType 4

Languages

Go97%
TypeScript1%
Python1%
Rust1%
Java1%
Ruby1%

Modules by API surface

internal/lsp/client.go103 symbols
internal/tools/coverage_round3_test.go48 symbols
test/multi_lang_test.go46 symbols
experiments/token-savings/main.go41 symbols
internal/types/types.go37 symbols
internal/tools/coverage_round7_test.go35 symbols
internal/tools/workspace_test.go34 symbols
internal/tools/coverage_round6_test.go27 symbols
internal/session/manager_test.go27 symbols
internal/tools/coverage_round5_test.go25 symbols
internal/tools/coverage_final_test.go25 symbols
internal/tools/analysis.go25 symbols

For agents

$ claude mcp add agent-lsp \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page