Serena is the strongest technical challenge on this site. It reaches semantic understanding through the Language Server Protocol rather than through its own parsers, so on resolution accuracy it is exact where TokenSave is guessing, and it refactors properly. What that exactness costs — a language server per language, minutes of cold indexing, gigabytes resident — is the other half of the comparison.
TokenSave v7.12.1 · Serena (oraios/serena), Sep 2026
TokenSave resolves cross-file edges with ReferenceResolver, which matches unresolved reference
names against known node and qualified names. That is a string-matching heuristic, and
TokenSave's own design document is blunt about where it breaks:
Config in different modules. The
resolver picks the one in the same file or the first match, which is often wrong.
Method dispatch. validator.check(input) could resolve to any check
method. Without type information, the resolver guesses based on proximity.
Re-exports and aliases. use crate::auth::User as AuthUser — the resolver
tries suffix matching but can still miss. Cross-crate references. Unresolvable from AST
alone."
docs/LSP-INTEGRATION.md, TokenSave's own design doc
A language server has none of these problems, because it has the type information. One
textDocument/definition request returns the exact target. Serena is built on that from the
start; TokenSave has an LSP pass designed to fix this and it is not shipped —
there is currently no LSP code in the MCP server at all. On resolution accuracy in principle,
Serena is ahead, and stays ahead until that design doc becomes code.
"More accurate" is only half a comparison. The other half is what the accuracy costs and how often it changes an answer — and on both counts the case for LSP is weaker than the theory suggests.
Language servers are slow, structurally. Not slow in the sense of a badly optimised function — slow because a server must build its own model of the project before it can answer anything. On a large workspace that cold index runs into minutes and the resident process can hold gigabytes; rust-analyzer and the Java language server are the well-known offenders, but the shape is general. Switch branches and much of that work happens again. Serena inherits this: its first useful answer waits on a server that is still thinking, and it needs one such server per language in the repo.
TokenSave pays its indexing cost once, ahead of time, into a file on disk. A query afterwards is a database lookup — a quarter of a second for the whole process, cold, including startup. That is not a small constant-factor difference; it is the difference between a tool you can call on every turn and a tool you call when you have decided it is worth waiting for.
And the accuracy delta is unmeasured. TokenSave's design doc lists where its heuristic fails; it does not say how often. A resolver that keys on qualified names, import aliases and file proximity gets the overwhelming majority of ordinary references right — the failures cluster in genuinely ambiguous code: repeated type names across modules, heavy dynamic dispatch, deep re-export chains. Whether that is 0.5% of your edges or 15% depends entirely on the codebase, and neither project publishes the number.
Config types and heavy dynamic dispatch, the subset is big
enough that Serena's exactness earns its keep. Measure your own repo before assuming which one you
are.
The place the argument is unambiguous is refactoring. A rename that is 98% correct is not 98% of a rename — it is a broken build. That is why the concession below on Serena's atomic rename, move and inline stands without qualification, even though the concession on read-path accuracy does not.
| Dimension | TokenSave | Serena |
|---|---|---|
| Semantic backend | Tree-sitter ASTs + heuristic resolution | Language servers (LSP), real type info |
| Resolution accuracy | Heuristic; documented failure modes, unmeasured rate | Compiler-grade, at a latency cost |
| Implementation | Rust, single static binary | Python 3.13+ with uv |
| Runtime deps | None | Python, uv, plus a language server per language |
| Cold start | ~0.24 s, precomputed graph | Minutes on a large workspace; GBs resident |
| License | MIT | GPL-3.0-or-later (app), MIT (SolidLSP); CLA required |
| Adoption | ~640 stars | ~29,500 stars |
| Languages | 60, no server needed | 40+, each needing its language server |
| Refactoring | rename_preview — graph-derived, advisory | Atomic rename, move, inline, safe delete |
| Symbol editing | Anchor-based and AST rewrite primitives | Symbol-level: replace body, insert before/after |
| Diagnostics | None | Live, from the language server |
| Aggregate analytics | Health score, Gini, DSM, hotspots, dead code, test-risk | Not the model |
| Multi-branch | Per-branch graphs, cross-branch diff | No |
| Memories | Decisions, code areas, FTS recall | Memories + onboarding, cross-project |
| Commercial component | None | Optional paid JetBrains backend |
Config and heavy dynamic dispatch, it buys a lot.rename_preview shows you what its graph believes would be affected and leaves the editing to you — and its graph is the heuristic one. This is the single biggest capability gap on this page.replace_symbol and insert_at_symbol too, but resolved through the heuristic graph rather than a language server.PreToolUse hook that fires on every Agent, Grep and Bash call. You cannot put a cold language server there.you refactor often and want it atomic and correct, your codebase is genuinely ambiguous enough that heuristic resolution misfires, you work mainly in one or two languages with good language servers, and you can absorb the cold-start and memory cost. GPL must be acceptable in your setting.
you want questions answered about the whole codebase rather than one symbol, you work across many languages or in CI where a server per language is impractical, you need branch-aware graphs, or you want lookups cheap enough to run on every single tool call — which rules out waiting on a language server by construction.
Every TokenSave figure on this page was verified against the source at origin/master
(v7.12.1), not taken from its own README:
test_tool_definitions_complete in src/mcp/tools/handlers/mod.rs; 86 when the optional ast-grep binary is absent from PATH.[features] tiers in Cargo.toml: 11 lite, 9 medium, 40 full. The README's "50+" is conservative.real time for a complete tokensave status invocation, best of repeated runs on an Apple Silicon Mac. Your hardware and repo size will differ.otool -L on the released binary; system frameworks only.oraios/serena repository metadata and README, September 2026. Tool categories and refactoring claims are Serena's own and were not independently benchmarked here.docs/LSP-INTEGRATION.md. That document describes a design, not shipped behaviour: at v7.12.1 there is no LSP code in the MCP server, confirmed by searching src/mcp/.