vs-token-safer
This server provides a token-efficient way (~97–99% fewer tokens than grep) to search, navigate, and edit large codebases (C++, C#, JS/TS, Python) using language server indexes (clangd, Roslyn, tsserver, pyright) instead of raw text searching.
Search & Navigation
search_symbol— Find declarations by name/substring semanticallyfind_references— Locate every usage/call site of a symbol by namegoto_definition— Jump to a symbol's definition (also supportstype_definition,implementation,declaration)hover— Get type/signature info at a position without opening the whole filedocument_symbols— Outline a file's classes, functions, and types as a token-cappedfile:linelistfind_files— Find files by name substring or glob — token-capped replacement forfind -namesearch_text— Raw text/regex search for non-symbol content (strings, comments, config keys) — capped replacement forgrep
Semantic Editing (by symbol name, not line numbers)
replace_symbol_body— Replace an entire declaration (signature + body) by naming itinsert_before_symbol/insert_after_symbol— Insert code before/after a named declarationsafe_delete— Delete a declaration, refusing if still referenced (force=trueoverrides)rename— Rename a symbol project-wide across every reference
VCS Integration (read-only, compacted output)
vts_git— Run read-only git commands (status,log,diff) with token-capped outputvts_p4— Run read-only Perforce commands with compacted output; mutating commands refused
Configuration & Admin
vts_setup— Configure project path, backend, max results, and clangd binaryvts_config— Show current effective settingsvts_warmup— Pre-build the language server index for fast subsequent searchesvts_gen_compile_db— Generatecompile_commands.jsonfor Unreal projects via UBTvts_savings/vts_savings_reset— Track/reset cumulative tokens saved vs raw responsesvts_discover— Scan recent transcripts to find searches that bypassed vts (missed savings)
Provides read-only Git operations (status, log, diff) with token-capped output to avoid context flooding.
Provides code search and editing for .NET projects using the Roslyn language server, enabling semantic queries and symbol-level edits.
Provides read-only Perforce operations (opened, status, changes, reconcile) with token-capped output.
Provides code search and editing for Python projects using pyright, enabling semantic queries and symbol-level edits.
Provides code search and editing for TypeScript projects using tsserver, enabling semantic queries and symbol-level edits.
Provides log analysis for Unity editor logs, including parsing, deduplication, classification, search, and diff.
Provides code search and editing for Unreal Engine C++ codebases using clangd, and log analysis for Unreal Engine editor logs.
vs-token-safer
English · 한국어
A token-saving code layer for Claude Code, for any codebase. TypeScript, JavaScript, and Python work with zero setup; C# and C++ add a language server; and 30+ more languages come in on the built-in tree-sitter tier. Proven up to a 26k-translation-unit Unreal Engine monorepo — so your web, backend, or data repo is the easy case.
Your coding agent has a small context window. Your repo is large. vs-token-safer sits in between.
Ask where something is, what calls it, or even "how does the auth flow work?" when the name escapes you — and instead of pasting a wall of source into the chat, it replies with a short
file:linelist.
Builds normally? The answers are exact — it reads the same code index your editor relies on.
No toolchain set up? It still locates your functions and classes.
Forgot the name, only remember what it does? It finds it from the vocabulary your own code already uses — no AI model, nothing uploaded.
Markdown or a config file? Jump straight to one section by its heading instead of opening the whole file.
A companion plugin does the same for giant editor and build logs. None of it leaves your machine.
# Claude tries to grep code → the hook REWRITES it to the indexed query, in place:
$ grep -rn "createSession" src/
↻ [vs-token-safer] Rerouted → search_symbol "createSession" # semantic, not a text match
func createSession (in AuthService) @ src/auth/session.ts:142 (+2 more)
→ ~120 tokens (grep would have dumped thousands of lines)
# Editing that symbol? Name it — no Read-the-whole-file, no line counting:
$ replace_symbol_body symbol="createSession" body="…" # preview; apply=true writes
replace_symbol_body "createSession" — PREVIEW at src/auth/session.ts:142-160Same flow on TypeScript, Python, C#, C++, Go and more (clangd · Roslyn · tsserver · pyright · tree-sitter). VTS_REWRITE=0 blocks instead of rewriting.
Why
Keep the context lean.
grepon a large repo — a TypeScript/Python monorepo, a C#/.NET solution, even a 26k-TU Unreal C++ tree — floods the context. The language-server index stays token-capped — ~97–99% smaller (benchmarks).Claude keeps reaching for
grep. The hook doesn't just block it — it rewrites the command to the indexed query in place, so the search still runs and the flow never breaks.Edit by symbol, not by line. Replace/insert-around/delete a declaration by naming it — the index supplies the span, so you skip reading the whole file into context.
Review a diff by its blast radius, not by eye.
detect_changesmaps agit diffto the symbols it changed, walks each one's callers, and scores the risk LOW/MED/HIGH — from the blast radius, the caller-cascade depth, and which historically co-changed files this diff left out. A review starts from "what does this actually touch," capped tofile:line, nothing uploaded. It's the code-review-context idea done the vs-token-safer way: the official language server for the blast radius and your own git history for the coupling — no persistent graph database, no embeddings.You can't tell how much grep still slips through.
vts discoverreads your recent sessions and reports exactly which searches bypassed the index and what they cost.The language server runs headlessly — no editor open, unlike an IDE-proxy approach.
Related MCP server: Symbol Delta Ledger
Quickstart
# 1) Install (also auto-installs the gamedev-log-analyzer sibling)
/plugin marketplace add JSungMin/vs-token-safer
/plugin install vs-token-safer@vs-token-safer
/reload-plugins # first run auto-installs the server deps (no manual npm)
# 2) Configure — detects the backend, asks for the project path, writes the config
/vs-token-safer:setupThen restart the Claude Code session (the vs-search MCP server only starts on a fresh session).
Verify the tools appear and that grep src/**/*.cpp is rerouted to the index. Prerequisites: Node ≥ 18
and a language server — clangd (C/C++) / Roslyn (C#) you install; JS/TS + Python auto-install. Details in
Prerequisites below.
Want only the log analyzer?
/plugin install gamedev-log-analyzer@vs-token-safer.
How it works
vs-token-safer isn't a search box — it's a precision ladder. You ask where something is, what calls it, or "how does the auth flow work?" when the name escapes you, and it answers at the highest precision it can reach, then tells you which rung the answer came from:
EXACT — you know the name and the project builds → the official language server (clangd / Roslyn / tsserver / pyright), the semantic ground truth.
SYNTACTIC — no toolchain set up → a tree-sitter parse (36 grammars bundled, no native build; 19 languages with tuned declaration extraction, the rest via a generic parse) still returns real declarations, not a grep.
FUZZY — you only remember what the code does → a concept dictionary mined from the repo's own identifiers + comments (no AI model, nothing uploaded).
SECTION — it's a doc or config, not code → Markdown / TOML / YAML / CSS / HTML addressed by heading.
The rungs aren't a one-time pick — they connect, and vts switches between them as it learns more. Start
on FUZZY when you only know the intent; the moment concept_search surfaces a real name, vts climbs to
EXACT to confirm it against the semantic index (and an exact search that misses drops back down to FUZZY).
The hooks steer that hand-off in both directions, so "I don't know the name" turns into a precise,
semantically-verified file:line instead of a dead end.
Graceful degradation — a locate never hard-errors on a cold or missing toolchain. When clangd is
missing, cold, or still indexing, a locate degrades to the SYNTACTIC (tree-sitter) tier with a one-line
advisory instead of erroring or blocking, then climbs to EXACT once clangd warms. If a committed
.vts-index has drifted from the source, the answer is still served but labeled SYNTACTIC · STALE (with a
climb: vts index hint). And on a cold locate over a large tree, vts auto-builds the .vts-index/ in the
background so the next query (or the same session, once the build finishes) is instant — you never wait on
it. So vts index below is best thought of as auto-built in the background; commit it to share, not a
manual step you have to remember.
Every answer comes back capped to file:line (never source bodies) and carries a one-line completeness
certificate naming the rung — so the model always knows whether it got the semantic truth or a fallback.
On a 3-language, 150-file benchmark that's 87% fewer tokens than grep (~138× on a real Unreal Engine 5
tree). Underneath, four mechanisms make Claude actually use the ladder instead of reaching for grep:
Layer | Effect |
Rewrite/enforcement hook | Covers four surfaces. Bash grep/rg/ |
Token-capping core | Turns LSP results into |
Symbol-level editing |
|
Headless LSP client | A fully-owned LSP client spawns the official engine over stdio. The project root is resolved per call (explicit |
Savings + discover | A local ledger records every search's tokens-saved ( |
Engine = official, glue = ours. clangd (LLVM) and Roslyn (Microsoft) do the analysis; this repo only writes the LSP↔MCP glue. No third-party MCP server runs over your source. Local-only, nothing uploaded.
Tools
All search/edit goes through an official language-server index — clangd (C/C++), Roslyn (C#/.NET),
tsserver (JS/TS), pyright (Python) — and comes back as a compact, capped file:line list (never
source bodies). MCP server vs-search; same tools as the vts CLI.
Search / navigate
Tool | CLI | Does |
|
| Find a symbol declaration by name/substring (semantic, not text). |
|
| Every call site of a symbol. Takes the name directly ( |
|
| Return the source of one named declaration (its span) — not the whole file. The read-side twin of |
|
| Jump to the definition at a position. |
|
| Type/signature at a position. |
|
| Outline a file (classes/functions/types as |
|
| Compiler/linter errors + warnings as a token-capped |
|
| Find files by name/glob — token-capped stand-in for |
|
| Raw text/regex search — capped stand-in for |
|
| Fuzzy search for a concept you can't name ( |
Edit (symbol-level — name it, don't line-count) — preview by default, apply=true writes.
Tool | CLI | Does |
|
| Semantic project-wide rename (every reference, not a text sed). |
|
| Replace a whole declaration (signature + body) by name — the index supplies the span. |
|
| Insert text next to a declaration — |
|
| Delete a declaration — refuses while it's still referenced unless |
Docs & config too (structure tier). Point any of
document_symbols/read_symbol/replace_symbol_body/insert_symbol/safe_deleteat a Markdown / AsciiDoc / reST / TOML / INI / YAML / JSON / text file and the "symbol" is a section (heading,[section], or key): outline a 2000-lineCLAUDE.mdin ~30 lines, read or replace one## Sectionby name without Reading the whole file. No language server, no new tools — same token-safer move, for documents.
Admin / meta — one MCP tool vts_admin {op, params} (folded to keep the per-session tool-definition
cost small; the CLI keeps the bare subcommands):
| CLI | Does |
|
| Run a read-only |
|
| Configure / show settings (projectPath, backend, maxResults, clangdCmd, genCompileDb). |
|
| Token-savings ledger (graph/daily/history) / clear it. |
|
| Pre-build the language-server index. |
|
| Build the clangd index ahead of the first query (big-tree cold start). |
|
| Build/refresh the committable |
|
| Find code searches that bypassed vts (missed savings). |
|
| Generate the Unreal clangd compile DB (UBT). |
e.g. vts_admin {op:"git", params:{argv:["status","-s"]}}. Or hand a whole "where is X / what calls Y /
find file W" lookup to the code-locator subagent — it searches in its own context and returns only
the file:line table.
Dashboard — vts serve. A local, interactive view of what vts knows + how much it saved: the
savings trend, language mix, per-tool savings, and an interactive 3D graph (WebGL / Three.js) with two
modes — the include graph (files sized by include fan-in) and an on-demand call graph (type a symbol
→ its transitive callers/callees, traced live through LSP callHierarchy — no persistent index; shows
call counts per node/edge). Nodes are laid out on a spherical shell (so they spread out, not clump);
drag/WASD to orbit, wheel/+-- to zoom, R to fit, hover for file:line. Symbol search has live
autocomplete (/symbols); color by connected-component groups · repo (which repository each
node is from, with a legend) · heat; click a node to drill into its group (Esc/Backspace to pop
out); a focus/maximize toggle, a highlight filter, and a node/edge metrics overlay.
Easiest via the slash commands: /vs-token-safer:viz (open) and /vs-token-safer:viz-stop (close).
Or the CLI:
vts serve --open # → http://127.0.0.1:8731/ (launches the browser; --port N to change)
vts serve --stop # stop it (or Ctrl-C the process)It's 127.0.0.1-only and serves a fully self-contained page — CSS/JS inlined and Three.js vendored
locally (server/vendor/, served same-origin, never a CDN), so nothing leaves the machine; it renders
with the network unplugged. Same trust model as the rest of vts. Built on Node's stdlib http (no
web-framework dependency), and it runs only when you invoke it — the MCP server never starts it, so the
steady-state package stays a thin stdio client. The 3D graph caps at VTS_VIZ_MAX_NODES (200) for smoothness.
$ vts symbol --q createSession --projectPath ./app
3 symbol(s) matching "createSession" (backend: typescript, root: ./app):
func createSession (in AuthService) @ app/src/auth/session.ts:142
method createSessionToken (in TokenStore) @ app/src/auth/token.ts:88
func createSessionCookie @ app/src/http/cookies.ts:31
✓ Saved ~4,200 tokens here (96.8% / 31× smaller than the raw index response).The two plugins
Plugin | Does | Needs |
vs-token-safer (this page) | Force code search/edit through the clangd/Roslyn/tsserver/pyright index over Bash grep, token-capped to | Node + a language server (clangd / Roslyn you install; JS/TS + Python auto). No IDE. |
Parse/dedup/classify huge Unreal/Unity/Godot/MSVC-UBT logs, search + diff + extract scalars | Node only |
vs-token-safer declares gamedev-log-analyzer as a dependency, so one install pulls in both. Used
together: the log analyzer emits file:line per entry → hand it to goto_definition/find_references
to open the code, without grepping or dumping the raw log. The handoff runs in reverse too — a code search
aimed at a log (Logs/, .log/.jsonl) points you back at gamedev-log instead of an empty result.
Combined savings (measured) | Bash / raw | Plugin | Reduction |
Symbol search on a real UE5 repo ( | ~282,194 tok | ~2,048 tok | ~99.3% (~138×) |
Raw index response → capped list (eval, 1,000 symbols) | ~57,308 tok | ~1,515 tok | ~97.4% |
Read a ~1 MB editor log ( | ~267,000 tok | ~130 tok | ~99.95% |
Companion: drive vs-search with a local model
vts-local-orchestrator — a separate, optional
companion that lets any local LLM (Ollama, full-GPU — model-agnostic, default gemma4:e4b, chosen by
benchmark) drive these same vs-search tools. Claude delegates cheap, high-volume code-location to the
free local model and receives only the compact file:line answer, so the raw search output never enters
Claude's context.
CLI (
qvts) + a live web dashboard with a 3-way token-savings panel (this method vs CC-using-vs-search vs CC-using-grep), plus a delegation-routing skill for Claude Code.Token-savers: a persistent savings ledger (
qvts --savings), a locate cache (zero-cost repeats), batch delegation (--batch), and terse repo-relativefile:lineoutput.Fully local — nothing transmitted off-machine, same as this plugin's charter.
Install: clone it next to this repo, npm install, then bash setup-macos.sh (Windows: setup.ps1). See
that repo's README for the pipeline, the model benchmark, and the savings model.
Performance
The token win scales with repo size and is language-agnostic — a TypeScript service or a Python codebase
sees the same shape (the deterministic 3-language benchmark cuts ~87%; details in
BENCHMARK.md). The most extreme case we've measured is a large Unreal Engine 5 project:
finding one public engine symbol (FGameplayTag) via Bash grep-and-paste vs this plugin. No project source
is reproduced, only aggregate counts.
Bash grep-and-paste (whole repo) | Plugin (clangd index, capped) | |
What the model receives | 5,654 lines / 1,010 files | 47 semantic decls ( |
Tokens to the model | ~282,194 | ~2,048 |
~99.3% fewer (~138×). grep returns the full text of every matching line and matches by text (comments,
strings, unrelated identifiers); the plugin returns one file:line per semantic hit, capped. The mock-LSP
eval (node eval/run.mjs, no toolchain) gates this on every commit: ~57,308 → ~1,515 tok = 97.4%
(92 checks).
Syntactic tier vs clangd — same location, no cold wait. On a second real UE5 game module (3,143 files,
133,890 symbols; aggregate counts only), the tree-sitter tier returned the same file:line as clangd's
EXACT answer on every sampled symbol (line delta 0), in ~240 ms vs clangd's ~127 s cold-to-first-answer
— a ~530× gap the semantic tier doesn't close for a locate. That's why the ladder answers tree-sitter-first
while clangd warms, then climbs to EXACT. One-time index build ~62 s; details in BENCHMARK.md.
Recall: the plugin returns the top
N(cap), not every textual occurrence — the withheld tail is mostly comments/includes/substring noise. Need exhaustive? RaisemaxResults, or use grep.Precision: grep matches every substring (
Fooalso hitsFooBar); the index returns distinct semantic declarations.
So for navigation (a definition plus representative usages) the plugin is both more accurate and far cheaper. For an exhaustive occurrence audit, raise the cap or fall back to grep on purpose.
clangd indexes asynchronously, so the first search pays a one-time warm-up. vts handles this like an IDE:
the MCP server pre-warms at boot (VTS_PREWARM, on when projectPath is set) and keeps the client
cached for the session, so you pay it once. vts warmup builds the on-disk index up front (CLI/CI), and
VTS_CLANGD_REMOTE points clangd at a shared prebuilt index server.
Ordering matters: clangd boosts the priority of files you open, so vts warms query-history-first, then
what you're editing now (git status / p4 opened), then git-log recency, then include-centrality, then
mtime. On a huge tree you can only warm a small slice, so this is what makes the warm window contain what
you search for. Measured lift (node eval/bench-hitrate.mjs, 2,000 files):
warm-up cap | arbitrary order | history-ordered | lift |
3% of files | 1.5% | 54.3% | 36× |
5% | 7.8% | 56.5% | 7.3× |
10% | 11.3% | 62.5% | 5.6× |
20% | 24.8% | 68.5% | 2.8× |
50% | 46.3% | 80.5% | 1.7× |
The smaller the slice you can afford to warm, the bigger the win.
On a huge monorepo (e.g. a full Unreal Engine source tree, ~26k translation units) the cold index is the one real cost. Two opt-in levers cut it — both stay local, nothing is transmitted:
1. Scope — index a subtree, not the whole tree. See what you'd scope, then set it:
vts scope --projectPath /path/to/UE # shows current scope, kept/total TUs, and top-level dirs to pick
vts setup --scope "MyGame,Plugins" # persist it (or set VTS_SCOPE="MyGame,Plugins"); then reload/restartclangd then indexes only the in-scope translation units (live UE5: MyGame → 3,377 of 26,488 TUs, 13%),
and every backend's warm-up is scoped with it. No scope set = whole-tree behavior, unchanged.
2. Pre-index — build the index ahead of the first query.
vts preindex --projectPath /path/to/UE # honors the scope aboveWith the full LLVM release installed (it bundles clangd-indexer next to clangd), this builds a
monolithic static index offline and clangd loads it via --index-file — a local file, no server — so the
first query is instant instead of waiting on the lazy background crawl. Without clangd-indexer it falls
back to a warm pass (and tells you to install full LLVM). Override the binary with VTS_CLANGD_INDEXER_CMD.
clangd background indexing scales by tree size (RAM/CPU tiering). To keep a huge tree from pinning your
machine, background indexing is auto-tiered by translation-unit count: FULL at ≤ 4,000 TUs (normal
priority), SAFE at 4k–15k (idle CPU priority, throttled), and OFF above 15,000 TUs (no whole-tree
crawl — project-wide search_symbol/find_references fall to the syntactic tier, while single-file
read_symbol/hover/outline stay cheap). A one-line advisory names the tier so you know search degraded on
purpose; the bounded fix is to vts setup --scope <module> then vts preindex. Knobs:
VTS_CLANGD_BG_INDEX (force full/off), VTS_CLANGD_BG_INDEX_SOFT_TUS (4000),
VTS_CLANGD_BG_INDEX_HARD_TUS (15000), VTS_CLANGD_HUGE_WARM_CAP (8).
3. Zero-setup tier — works before any toolchain, on any repo. No compile DB, no language server, no
wait? vts still answers search_symbol from a tree-sitter parse (an official standard parser; 36 grammars
bundled as wasm — no native build; 19 languages with tuned declaration extraction, the rest via a generic parse) —
real declarations, not a usage grep, in the same token-capped file:line shape. Make it instant and shareable by committing an index:
vts index --projectPath /path/to/repo # writes .vts-index/symbols.jsonl (commit it!)
vts index --status # show the current committed indexYou rarely have to run this by hand: on a cold locate over a large tree vts auto-builds .vts-index/ in
the background (VTS_AUTO_INDEX, on by default) so a later query is instant. .vts-index/symbols.jsonl is
plain, git-committable, and portable — commit it so teammates (and your own cold starts) get instant symbol
search with zero setup. A language server, once it indexes, automatically
supersedes it (the syntactic tier locates decls; the LSP adds reference/overload/type resolution on top).
Benchmark (150-file symbol search): grep 4917 → tree-sitter 53 tokens = 98.9%, no toolchain.
Do existing users need to re-run setup? For default (whole-tree) behavior, no — just update the
plugin and /reload-plugins. You only run vts setup --scope … (once) if you want to opt into scoping;
the clangd-indexer path needs no vts setup at all (it's auto-detected — you just need full LLVM installed).
Each search records the tokens it saved vs forwarding the raw index response. Check it with
/vs-token-safer:savings, vts savings (--graph/--daily/--history), or reset via vts savings-reset.
vs-token-safer savings (local, 1 search(es))
total saved: ~4,200 tokens vs forwarding raw index responses
raw → output: 4,340 → 140 tok (~31× smaller)
est. value: ~$0.01 (@ $3/Mtok — set VTS_USD_PER_MTOK)That's the caught side. vts discover scans recent sessions for searches that went around the index:
$ vts discover --since 1
86 code search(es) bypassed vts (Grep×48, Glob×18, grep×12, find×8)
catch-rate: ~770,333 tok caught (via vts) vs ~28,692 still bypassing → 96.4% routed through vts(Searches the hook blocked don't count as bypasses.) discover is local and read-only — it reads
transcript metadata and tool I/O sizes, never ships any of it anywhere. --learn feeds the files past
searches hit into the warm-up set, so each session leaves the index warmer.
Prerequisites (details)
Node.js ≥ 18 on PATH.
C/C++ → clangd ≥ 22 (releases). The clangd 19.1.x bundled with Visual Studio deadlocks indexing real Unreal TUs in server mode; vts warns on an older one. Needs a
compile_commands.json. Prefer the full LLVM release — it bundlesclangd-indexeralongsideclangd, whichvts preindexuses for an instant static index (see Big trees: scope & pre-index).C#/.NET → a Roslyn LSP. Install the VS Code C# extension (
ms-dotnettools.csharp) — vts auto-detectsMicrosoft.CodeAnalysis.LanguageServerand its runtime from the bundle. Fallback:dotnet tool install --global csharp-ls. Needs a.sln/.csproj.JS/TS → typescript-language-server, Python → pyright. Ship as plugin deps, install automatically on the first session (one-time ~50 MB; JS/TS wants Node 20+, skipped on 18).
Mixed repo? A query that targets a file uses that file's own language backend — a
.py/.tsinside a C++/C# (clangd/roslyn-rooted) tree gets pyright/typescript automatically, so vts works in a UE tree with a Python tooling dir without a manualbackend=. This even overrides a pinnedbackend/VTS_BACKENDwhen they conflict: one global server serves every repo you touch, so abackend:"clangd"set for a C++ project never sends another repo's.js/.cs/.pyto clangd (which would answer-32001 invalid AST). A query with no file target (e.g.search_symbolby name) keeps the pinned backend.
clangd needs a compile database:
Unreal:
<UE>/Engine/Build/BatchFiles/RunUBT … -mode=GenerateClangDatabase. If targets build with clang-cl, add-Compiler=VisualCppor it fails clang-toolchain validation.CMake:
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON.
No compile DB yet? You still get answers — search_symbol falls back to a bounded literal text
search, labeled as such, and the first result carries a one-time advisory. The one-command fix:
vts_admin {op:"gen_compile_db"} (CLI vts gen-compile-db) assembles the exact UBT command (finds the .uproject,
derives the <Name>Editor target, locates the engine, adds -Compiler=VisualCpp). Dry-run by default;
apply=true runs UBT and parks the DB outside the source tree (~/.vs-token-safer/db/<project>, with
clangd's .cache/ next to it, so git/p4 reconcile never see an artifact). inTree=true keeps the
classic project-root layout, protected by a VCS-ignore guard.
Not published to npm — install vts from a clone:
git clone https://github.com/JSungMin/vs-token-safer
cd vs-token-safer/server && npm install && npm link # provides `vts`
# or run directly: node /path/to/vs-token-safer/server/cli.js symbol --q SpawnActor --projectPath /path/to/projConfiguration
Settings live in ~/.vs-token-safer/config.json (read at startup — /reload-plugins after changes).
Configure via /vs-token-safer:setup (guided), vts_admin {op:"setup"} / {op:"config"}, or vts setup --projectPath <root> --backend clangd. Backend auto-detects from the root. Precedence: env (VTS_*) >
config file > default.
Updating: Claude Code caches the marketplace, so new commits aren't auto-fetched:
/plugin marketplace update vs-token-safer
/plugin update vs-token-safer
/reload-plugins
# then RESTART the session — REQUIRED.⚠️ A new version only takes full effect after a session restart.
/reload-pluginsupdates hooks/commands/skills, but the runningvs-searchMCP server serves the old tool code until you quit and reopen. Version history: Releases.
Precedence: VTS_* env > ~/.vs-token-safer/config.json > default.
Config key | Env var | Default | Meaning |
|
| cwd | Project root (where the compile DB / |
|
| auto |
|
|
|
| Cap on returned |
— |
|
|
|
— |
|
| Max concurrently-live language servers (LRU-evict past the cap). |
— |
|
| Idle language server shut down after this ( |
|
|
| clangd executable (persist via |
— |
| auto | Path to a specific |
— |
| auto → | Override the C# LSP. |
— |
| bundled | Override the JS/TS / Python LSP. |
— |
|
| Files the JS/TS / Python warm-up opens. |
— |
|
| Per-request LSP timeout. Raise for a cold, large index. |
— |
|
| How long the clangd warm-up waits for background-index completion. |
— |
|
| Files the cold warm-up opens to prime clangd. |
— |
|
| Open cap when a persisted |
— |
|
| Cap on how long a query polls a still-loading persisted index. |
— |
|
| Brief floor before the first query starts polling. |
— |
|
| clangd background-index priority ( |
— |
|
| clangd async/index workers ( |
— |
| auto | Force clangd background indexing |
— |
|
| ≤ this many TUs → FULL background index; above it → SAFE (idle-priority, throttled). |
— |
|
| Above this many TUs → background index OFF (no whole-tree crawl; falls to the syntactic tier). |
— |
|
| Warm-up open-cap in SAFE/OFF mode (a large tree's warm-up is itself a parse spike). |
— |
| on (if | MCP server pre-warms at boot; |
— |
| auto |
|
— |
|
| Adaptive warm-up open-cap (fraction of a language's files, clamped). |
— |
| — | Address of a shared/prebuilt clangd index server. |
— |
|
| Warm-up ordering caches. |
— |
|
| Include-centrality scan bounds ( |
— |
|
|
|
— |
|
|
|
— |
|
|
|
— |
|
|
|
— |
|
|
|
— |
|
|
|
— |
|
| Opt-in. Set ≥1 to escalate the warn to a one-time block on a safe insert after that many consecutive ignored nudges (then it resets — fire-once, not a wall). Default off: a persistent block trapped the agent (it fought the wall with Edit retries instead of switching). A replace always stays a warn; |
— |
| — | Comma list of executables to exempt (also |
— |
|
|
|
|
| auto | Hook message language: |
— |
|
| Recovery file for a capped |
— |
|
| $/Mtok rate for the estimated-value line (informational). |
|
|
| Cumulative-saving threshold (tokens) past which |
— |
|
|
|
— |
|
|
|
— |
|
| A symbol-edit / |
— |
|
| Perforce CLI used for the auto-checkout above ( |
— |
|
| On an EMPTY clangd result, append a why-advisory: the file isn't in |
— |
|
| Where |
— |
|
| Out-of-tree home for generated compile DBs. |
— |
| on (→ | Shows the one-line |
— |
|
| Auto-build |
— |
|
| Min tree size (files) that triggers the background auto-index. |
— |
|
| Cross-process lock TTL for the auto-index build (default 30 min). |
— |
|
| Label a drifted committed index |
— |
|
| On a big-file Read, nudge toward |
— |
|
| Min file size (bytes) that triggers the Read → |
— |
|
| When a local orchestrator (qvts) is on PATH, redirect LOCATE + Bash/Grep code-search to |
— |
|
|
|
— |
|
| Window in which an identical re-issued locate passes (post-delegation fallback); default 3 min. |
— |
|
| After a delegated locate comes up dry, the window where Claude may search directly; default 2 min. |
Symptom | Cause | Fix |
| Plugin not installed (only marketplace added), or stale |
|
First clangd query very slow | Per-spawn clangd cost on a UE-scale tree (cold index, or re-validating a persisted one) | Keep the MCP server running so clangd spawns once. Tune |
clangd query never returns (hangs) on UE | clangd 19.1.x bundled with VS deadlocks on UE TUs | Install clangd ≥ 22, point |
| Targets build with clang-cl | Add |
clangd resolves only header-free symbols | Compile DB has no include dirs | Use a UBT-generated DB (it includes the paths). |
No C# results / "No backend resolved" | Roslyn engine not found | Install the VS Code C# extension, or |
No JS/TS or Python results | Bundled LSP didn't install (offline first run) | Re-run the session, or set |
Code search blocked when you wanted plain grep | The hook is steering you to the index |
|
Locate / grep redirected to | A local orchestrator (qvts / vts-local-orchestrator) is on PATH, so the LOCATE tools + Bash/Grep code-search are delegated to it | Run the suggested |
Wrong backend picked | Multiple project files under the root | Pin |
| A | Fixed in 0.28.4 — the file's own backend now wins on conflict; update the plugin ( |
clangd finds nothing on a symbol you KNOW exists | The compile DB doesn't cover that module, OR the background index isn't built yet (vts prints which — see | If "not in compile_commands.json": build the editor target + regenerate the DB. If "index N% complete": keep the server warm so indexing finishes, or scope the DB to your game modules (a 26k-TU full-engine DB indexes slowly — exclude |
Status & safety
clangd & Roslyn live-verified —
search_symbol/find_references/goto_definitionconfirmed against real clangd (incl. a real Unreal 5.x game project end-to-end) and Microsoft.CodeAnalysis.LanguageServer. Needs clangd ≥ 22 and a correct compile DB.Local-only, nothing uploaded. The hook only inspects the command string (honors
VTS_ENFORCE=0); the language server runs over stdio; the only outbound call is the first-runnpm installof the MCP SDK. It writes only its config + a local savings ledger under~/.vs-token-safer/. See SECURITY.md and PRIVACY.md.Savings/benchmark numbers are response-shaping (raw index → capped); savings vs grep are larger (BENCHMARK.md).
Contributing
Issues and PRs welcome — bug reports, new backends/engines, language mappings, docs. Keep PRs small,
evidence-backed, and free of proprietary data (real paths/symbols/project IDs); add an eval/run.mjs guard
for any new code path. See CONTRIBUTING.md. If this saved you tokens, a star helps
others find it. ⭐
Acknowledgments
vs-token-safer stands on ideas from the open-source code-intelligence community. With gratitude to:
codebase-memory-mcp (DeusData) — the tree-sitter
tags.scmcall-site approach, the multi-hop call-hierarchy (trace_path) shape, and content-hash-keyed caching. Our difference: we keep the official language server as the semantic source of truth and use tree-sitter only as a zero-setup syntactic tier below it — no reimplemented type-resolution layer, no persistent semantic DB; everything stays local and nothing is transmitted.Codeix (montanetech) — the idea of a plain, git-committable JSONL symbol index. Our difference: ours is a cold-start accelerator that a language server automatically supersedes once it has indexed.
Code Context Engine (elara-labs) — the token-savings framing for AI code search. Our difference: no embeddings/vectors (so no nearest-but-wrong retrieval) — exact
file:line, token-capped.Serena — symbol-level editing (
replace_symbol_body/insert_symbol/safe_delete), here layered on the LSP with preview-by-default.The tree-sitter project and tree-sitter-wasms for the prebuilt grammars that power the syntactic tier.
Each of these made vs-token-safer better. Thank you. (Reuse here always keeps our charter: official engines do
the analysis, output is token-capped file:line, and nothing leaves your machine.)
References & related work
The design choices here have academic backing, and the field is moving fast. The companion papers carry the
full treatment — paper/vs-token-safer.tex and the fuzzy-retrieval follow-up paper/fuzzy-concept-dictionary.tex.
Key references:
Foundations we build on
HyperAgent — Phan et al., arXiv:2409.16299. Generalist software-engineering agents; motivates giving the model structured tools instead of raw grep.
Codebase-Memory: Tree-Sitter Knowledge Graphs for LLM Code Exploration via MCP — arXiv:2603.27277. The closest sibling. Our difference: official-LSP ground truth + capped
file:line, no persistent semantic DB, nothing transmitted.Dead-code lineage — Rapid Type Analysis (Bacon & Sweeney, OOPSLA'96) and demand-driven reachability (the Go
deadcodemodel) underpinvts dce's preview-only call-graph reachability.
Related & subsequent work (2024–2026) — two of these are now migrated into vs-token-safer (marked Migrated).
LARGER: Lexically Anchored Repository Graph Exploration and Retrieval — Hu et al., arXiv:2605.16352. Formalizes "lexical anchor → structural expansion" — the academic shape of our fuzzy→climb-to-exact ladder, also without embeddings. Migrated →
concept_searchnow expands the import-graph neighbourhood only from high-confidence lexical anchors (a neighbour lifts a symbol only if its own match clears a fraction of the strongest one;VTS_CONCEPT_ANCHOR_MIN), so a weak/cross-cutting neighbour can't drag its imports up the ranking.Pseudo-relevance feedback (RM3) — Lavrenko & Croft, SIGIR 2001 (the classical embedding-free retrieval-feedback technique). Migrated →
concept_searchruns a second pass that mines expansion terms from the top results' own identifiers + comments and re-scores — bridging a synonym the query couldn't reach lexically ("warm" → the warmset'swarming/dominant; "reachable" → the dead-code module'sfixpoint/cascades). Drift-guarded (terms need a ≥2-result consensus, idf-ranked, capped) and the climb seed stays the pre-feedback exact match, so it widens recall without chasing the feedback.VTS_CONCEPT_PRF=0reverts to single-shot.Rethinking Agentic Search with Pi-Serini: Is Lexical Retrieval Sufficient? — Hsu, Yang & Lin, arXiv:2605.10848. Empirical case that lexical retrieval suffices inside the agent loop — backing for our no-embeddings charter.
One Tool Is Enough: RL for Repository-Level LLM Agents (RepoNavigator) — Zhang et al., arXiv:2512.20957. A single jump-to-definition tool, RL-trained, beats large multi-tool agents — a strong recent endorsement of LSP navigation over grep.
DCE-LLM: Dead Code Elimination with Large Language Models — arXiv:2506.11076. LLM-judged dead code. Our difference:
vts dcestays preview-only static reachability — deterministic, no model judgment, withsafe_deleteas the disposal backstop.cAST: Structural Chunking via Abstract Syntax Tree — Zhang et al., arXiv:2506.15655. Tree-sitter chunking for code RAG — the neighbor of our SYNTACTIC tier. Migrated →
read_symbolnow cuts an over-budget body at a whole-child AST boundary (the end of a complete member/statement), never mid-statement, so the returned source stays syntactically whole (falls back to the plain line cap when tree-sitter is absent).RepoGraph (arXiv:2410.14684) and LocAgent (arXiv:2503.09089) — repository code-graph localization; we reach the same call/dependency structure via live LSP call-hierarchy, with no prebuilt graph and no embeddings.
License
MIT © 2026 JSungMin
Available Tools
16 toolsconcept_searchA
FUZZY search for a concept you can't name ("how does auth work"). Mines a dictionary from the repo's own identifier+comment co-occurrence (no embeddings, nothing sent) → ranked file:line. Use when you don't know the symbol name. flow=true traces the top hit's call graph.
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | Concept/intent phrase (concrete nouns work best). | |
| flow | No | Also trace the top hit along the call graph. | |
| maxResults | No | ||
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, and it handles it well. It discloses the internal mechanism (dictionary mined from identifier+comment co-occurrence), privacy characteristics (no embeddings, nothing sent), the return format (ranked `file:line`), and the optional call-graph behavior of flow=true. This gives the agent a clear picture of what happens when invoked.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: it states what the tool does, how it works, what it returns, and the flow option, all in a few sentences. Every clause adds information, and there is no filler or repetition of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search tool with no output schema and no annotations, this is quite complete: it explains the fuzzy matching approach, privacy, output format, and the flow toggle. The main gap is the undocumented optional parameters maxResults and projectPath, which could affect how the agent invokes the tool for non-default behaviors.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 50%, with maxResults and projectPath lacking any description in both the schema and the description. The description does add useful meaning for q ("concrete nouns work best") and flow (traces the top hit's call graph), but it doesn't compensate for the two undocumented optional parameters, leaving their defaults and scope ambiguous.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb (fuzzy search) and resource (a concept you can't name), and the output is concrete: ranked `file:line`. It distinguishes itself from symbol-based searches by saying to use it when you don't know the symbol name, which sets it apart from siblings like search_symbol.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says "Use when you don't know the symbol name," giving agents a clear triggering condition and implicitly contrasting with symbol search. It doesn't name alternative tools explicitly or describe when not to use it, but the primary use case is well specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
detect_changesA
Review a diff by IMPACT: git diff → changed symbols → blast radius (callers) + LOW/MED/HIGH risk. → capped [risk] symbol file:line, no bodies (semantic blast + git co-change, nothing sent). Use before committing. staged=true (index) / base="".
| Name | Required | Description | Default |
|---|---|---|---|
| base | No | Compare vs this git ref (e.g. main, HEAD~3). | |
| depth | No | Caller hops (default 2). | |
| staged | No | Staged index instead of the working tree. | |
| backend | No | ||
| maxResults | No | ||
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that no code bodies are sent and nothing is transmitted, implying privacy. However, it does not clarify required permissions, side effects, or prerequisites like git repository access. Given no annotations, some behavioral gaps remain.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, using dense symbols and keywords to pack information. It is front-loaded with the core purpose and key usage. Slightly cryptic but efficient for those familiar with git and impact analysis.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 6 parameters, no output schema, and no annotations, the description covers the core workflow and output format but leaves several parameters (depth, backend, maxResults, projectPath) unexplained. Sufficient for basic use, incomplete for full parameter understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%; the description adds meaning for 'staged' and 'base' beyond the schema. Other params (backend, maxResults, projectPath) lack schema descriptions and are not explained in the tool description, so partial compensation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reviews a diff by impact, performing git diff, identifying changed symbols, and assessing blast radius and risk. It distinguishes from siblings like find_references and diagnostics by focusing on impact analysis and risk levels.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly suggests use before committing and explains the staged parameter for index vs working tree, as well as base ref. Lacks explicit when-not-to-use or alternatives, but the context is clear enough for appropriate selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagnosticsA
Compiler/linter errors + warnings (semantic) → capped file:line:col severity [code]: message, sorted error→hint with a count — the compact stand-in for raw build output. Empty = clean. Default = one path; scope="directory" scans the project.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | File to check (or, with scope=directory, the subtree to scan; default = root). | |
| scope | No | `file` (default) | `directory` (scan project). | |
| backend | No | ||
| maxResults | No | ||
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries full burden. It discloses output format (capped, sorted, with count) and that empty output means clean. However, it does not mention side effects, rate limits, or auth requirements, leaving some behavioral aspects unclear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, conveying purpose, format, and defaults in a single sentence. It could be structured more clearly (e.g., separate sentences for parameters), but overall it is not verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description explains return values (format, sorted, count). It covers main parameters but leaves some (backend, maxResults) undocumented. Siblings are many, but the description sufficiently distinguishes the tool's purpose.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 40% (2 of 5 parameters described). The description adds context for path and scope (defaults and interaction). But projectPath, backend, and maxResults are unexplained in both schema and description, failing to compensate for low coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns compiler/linter diagnostics in a specific format (file:line:col severity [code]: message), sorted by severity with a count. It distinguishes from sibling tools like symbol or search tools by specifying its role as a 'compact stand-in for raw build output'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use (as a compact stand-in for raw build output) and explains default behavior and scope options. However, it does not explicitly state when not to use or provide alternatives among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
document_symbolsA
Outline a file — classes/functions/types as a capped kind name :line list. Cheaper than reading the whole file for its structure. scope="directory" builds a signatures-only skeleton of every code file under path.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | File to outline (or, with scope=directory, the subtree; default = root). | |
| scope | No | `file` (default) | `directory` (skeleton of every file under it). | |
| backend | No | ||
| maxResults | No | ||
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so description fills gap. Discloses output is a capped list, cost advantage, and scope behavior. Does not mention error conditions or parameter effects beyond path/scope.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two efficient sentences. First sentence defines core purpose and output format; second adds usage tip and scope option. No fluff, front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 5 parameters (0 required) and no output schema, description covers core behavior and directory scope. Missing documentation for three less critical parameters, but overall sufficient for typical use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 40% (only path and scope have descriptions). Description adds meaning for path and scope (e.g., subtree behavior) but ignores projectPath, backend, and maxResults. Partially compensates but incomplete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description explicitly states it outlines a file listing classes/functions/types in a capped 'kind name :line' format. It distinguishes itself from siblings like 'read_symbol' by highlighting it's cheaper for structure overview.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly states when to use (cheaper than reading full file) and explains scope='directory' behavior. Lacks explicit exclusions or alternatives but provides clear context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_filesA
Find files by name (substring or glob like *Manager.cpp) — replaces Bash find -name. → capped file list; walk-bounded (skips node_modules/build, time-boxed).
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | Filename substring or glob (* ? supported). | |
| maxResults | No | ||
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses key behavioral traits: capped file list, walk-bounded (skips node_modules/build, time-boxed). With no annotations provided, this adds significant transparency beyond the basic purpose. It does not cover all aspects like permissions or side effects, but the disclosed traits are valuable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that front-loads the core action and key behavioral constraints. Every part adds value, with no redundant or extraneous words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 3 parameters, no output schema, and no annotations, the description covers purpose, usage hint, and behavioral boundaries. However, it lacks details on return value format, error conditions, or permission requirements, leaving some gaps for an agent to infer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaning to the `q` parameter by explaining it supports substring and glob patterns. It also hints at `maxResults` with 'capped file list'. However, `projectPath` is entirely undocumented, and schema coverage is low (33%). The description partially compensates but not fully.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: finding files by name using substring or glob patterns. It also distinguishes itself by mentioning it replaces Bash `find -name` and describes its bounded behavior, making it distinct from sibling tools like search_text or concept_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides some guidance by stating it replaces Bash `find -name`, implying usage in place of shell commands. However, it lacks explicit when-to-use vs. alternatives like search_text or concept_search, and does not mention when not to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_referencesA
Every call site of a symbol (semantic, not grep) — pass symbol (a name); resolves the decl + returns all refs in one call. → capped file:line; detail=file|dir for a blast-radius summary; direction=callers|callees switches to a multi-hop call hierarchy. Use before changing a function.
| Name | Required | Description | Default |
|---|---|---|---|
| line | No | 0-based line. | |
| path | No | Source file (+line/character for an exact position, or with `symbol` to disambiguate an overload). | |
| depth | No | Call-hierarchy hops (default 2). | |
| detail | No | `file`|`dir` blast-radius summary. | |
| symbol | No | Symbol NAME — resolved via the index, no position needed. | |
| backend | No | ||
| character | No | 0-based column. | |
| direction | No | callers|callees call hierarchy. | |
| maxResults | No | ||
| projectPath | No | ||
| includeDeclaration | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries full weight. It mentions resolving declaration, returning all refs in one call, and capping output at file:line. Does not disclose error handling, performance implications, or limitations (e.g., on large projects). Adequate but not thorough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, packed with information but front-loaded. The first sentence is dense with multiple ideas; could be split for clarity. Nonetheless, no wasted words and all content is relevant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 11 parameters and no output schema, the description covers core functionality and provides a usage hint. However, it omits details on many parameters and does not fully explain return format beyond 'capped file:line'. Incomplete for a complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 64%. The description adds meaning for 'symbol' (resolved via index) and 'detail'/'direction' (purpose). But several parameters (includeDeclaration, depth, projectPath, etc.) are not explained in the description, relying on schema. Baseline 3, with modest added value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool finds semantic call sites of a symbol, distinguishing from grep. Mentions alternative modes (blast-radius, call hierarchy). However, does not explicitly differentiate from sibling tools like 'search_symbol' or 'goto_definition', leaving some ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a clear usage recommendation ('Use before changing a function') and explains alternative modes (detail, direction). Lacks explicit when-not-to-use guidance or comparison to siblings, but the given context is helpful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
goto_definitionA
Jump from a 0-based position to a definition (semantic). kind: definition (default)|type_definition|implementation|declaration. → capped file:line. For usages, use find_references.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | definition (default)|type_definition|implementation|declaration. | |
| line | Yes | 0-based line. | |
| path | Yes | Source file containing the symbol. | |
| backend | No | ||
| character | Yes | 0-based column. | |
| maxResults | No | ||
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds some behavioral context by noting the output is 'capped `file:line`', indicating a result limit and format. However, no annotations exist, and the description does not disclose error handling, permission requirements, or details about the cap (e.g., max results). This is adequate but minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: two sentences and a note. Every part is essential, and key information is front-loaded. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 7 parameters, no output schema, and no annotations, the description falls short of full completeness. It does not explain the return value structure beyond 'file:line', nor does it cover optional parameters like projectPath, backend, or maxResults. However, for a focused navigation tool, the core behavior is captured.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaning to the 'kind' parameter by listing its options and default value. Other parameters (path, line, character, projectPath, backend, maxResults) are not elaborated beyond their schema descriptions. Since schema coverage is 57%, the description partially compensates but leaves gaps for non-kind parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Jump from a 0-based position to a definition (semantic)'. It distinguishes from sibling tool 'find_references' by explicitly stating 'For usages, use find_references'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use context: navigation to definitions, type definitions, implementations, or declarations. It also gives a clear alternative for usages (find_references), guiding the agent on tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hoverC
Type/signature of the symbol at a 0-based position (hover) — a few lines, no file open.
| Name | Required | Description | Default |
|---|---|---|---|
| line | Yes | 0-based line. | |
| path | Yes | Source file. | |
| backend | No | ||
| character | Yes | 0-based column. | |
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility. It mentions the tool does not open a file, but does not disclose side effects, required permissions, or error behavior (e.g., when symbol not found). Very limited transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, front-loading the core purpose. Every word adds value with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 5 parameters and no output schema, the description is far too brief. It does not explain what 'type/signature' means, how results are formatted, or what happens on errors. Incomplete for effective use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 60% (3/5 parameters described). The description does not add any parameter-specific meaning; it only restates that position is 0-based, which is already in the schema. No compensation for the two undocumented parameters (projectPath, backend).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it retrieves type/signature at a position (hover). It distinguishes itself from siblings by mentioning it returns only a few lines and does not open a file, but does not explicitly name alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives like goto_definition or read_symbol. The description implies it is for quick lookup without opening a file, but no explicit conditions or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
insert_symbolA
Insert text next to a named declaration — position=after (default)|before. The outline gives the point (no Read). PREVIEW by default; apply=true writes. Use instead of Read-then-Edit to add a declaration.
| Name | Required | Description | Default |
|---|---|---|---|
| line | No | 0-based line; disambiguate same-named (optional). | |
| path | No | File holding the symbol (else resolved via the index). | |
| text | Yes | Text to insert (own line). | |
| apply | No | Write to disk (default false = preview). | |
| symbol | Yes | Declaration to insert next to. | |
| backend | No | ||
| position | No | `after` (default) | `before`. | |
| maxResults | No | ||
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses preview mode by default, write when apply=true, and that it uses outline without read step. No annotations provided, so description carries burden well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with key information front-loaded; every clause adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, so description should explain return values or errors, but does not. Lacks details on preview output format and error handling for symbol resolution.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds meaning for key parameters (symbol, text, position, apply) but does not describe path, line, projectPath, backend, maxResults beyond schema. Schema coverage 67% so moderate compensation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Insert text next to a named declaration' with position option, and distinguishes from siblings like 'Read-then-Edit' and other modification tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use instead of Read-then-Edit to add a declaration' and notes preview default vs. apply=true, but does not list when to avoid using it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_symbolA
USE INSTEAD OF Read on a file when you only need ONE function/class — returns just that named declaration's source (its span), not the whole file (the read twin of replace_symbol_body). signatureOnly = head only; body capped by VTS_SYMBOL_MAX_LINES.
| Name | Required | Description | Default |
|---|---|---|---|
| line | No | 0-based line; disambiguate same-named (optional). | |
| path | No | File holding the symbol (else resolved via the index). | |
| symbol | Yes | Declaration name to read. | |
| backend | No | ||
| projectPath | No | ||
| signatureOnly | No | Return just the declaration head. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It discloses that the result is just the named declaration's span, that signatureOnly returns the head only, and that the body is capped by VTS_SYMBOL_MAX_LINES. This is meaningful behavioral context beyond the tool name.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence with the most important usage instruction front-loaded. Every clause adds value: when to use it, what it returns, how it differs from Read, the signatureOnly behavior, and the line cap.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read tool with no output schema, the description adequately explains the return value (named declaration source/span) and key behavior. However, it does not clarify the optional backend and projectPath parameters or error behavior, which are minor completeness gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67%, and the description adds meaning only to signatureOnly ('head only'). The schema already explains line, path, and symbol, but backend and projectPath remain undocumented in both schema and description, leaving a gap in parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'read' a named symbol and return its source span, not the whole file. It also distinguishes itself from Read and positions itself as the read twin of replace_symbol_body, making its purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use this tool instead of Read: when only one function/class is needed. It also names the sibling twin replace_symbol_body, giving an agent clear routing guidance without needing to inspect other tool definitions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
renameA
Rename the symbol at a 0-based position project-wide (semantic — every reference, not a sed). PREVIEW by default (affected file:line); apply=true writes. Use instead of editing call sites by hand.
| Name | Required | Description | Default |
|---|---|---|---|
| line | Yes | 0-based line. | |
| path | Yes | Source file containing the symbol. | |
| apply | No | Write to disk (default false = preview). | |
| backend | No | ||
| newName | Yes | New name. | |
| character | Yes | 0-based column. | |
| maxResults | No | ||
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but the description fully discloses key behaviors: default preview mode showing affected file:line, and apply=true to write. It also clarifies semantic scope (every reference).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences that are front-loaded with the core purpose and behavior. Every sentence adds essential information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains the main workflow (preview vs. apply) and scope but lacks output format details and does not cover optional parameters. No annotations or output schema exist, so more completeness would be beneficial, but core functionality is clear.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 63% (5 of 8 parameters described in schema). The description adds the preview/apply behavior to the apply parameter but does not explain projectPath, backend, or maxResults. It refers to 0-based position, which matches schema descriptions of line and character.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool renames a symbol at a 0-based position project-wide, emphasizing semantic rename (every reference) and distinguishing from a simple sed replacement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly recommends using this tool 'instead of editing call sites by hand,' providing a clear usage context. However, it does not mention when not to use or compare with sibling tools like replace_symbol_body or safe_delete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
replace_symbol_bodyA
Change a whole function/class/method by NAMING it — USE INSTEAD OF Read-the-file + Edit (the outline gives the span, so you skip the whole-file Read and exact-match line-counting). PREVIEW by default; apply=true writes in ONE call.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | New full text (signature + body). | |
| line | No | 0-based line; disambiguate same-named (optional). | |
| path | No | File holding the symbol (else resolved via the index). | |
| apply | No | Write to disk (default false = preview). | |
| symbol | Yes | Declaration name to replace. | |
| backend | No | ||
| maxResults | No | ||
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses key behaviors: preview by default, apply=true writes in one call. Lacks details on error handling or side effects but covers the main behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two efficient sentences that front-load purpose and usage, with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex replace operation, description covers main behavior but lacks return value info and error handling. Undocumented params not addressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 63%; description adds meaning for key params (symbol, body, apply) but doesn't explain projectPath, backend, maxResults. Adequate for required params but incomplete overall.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it changes functions/classes/methods by naming them, and distinguishes itself from sibling tools like read_symbol and insert_symbol by positioning as a replacement for read-file + edit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'USE INSTEAD OF Read-the-file + Edit' and explains preview vs apply behavior, giving clear context on when and how to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
safe_deleteA
Delete a named declaration — USE INSTEAD OF Edit-deleting it; REFUSES while still referenced (lists the refs, force=true overrides) so a delete can't silently orphan call sites. PREVIEW by default; apply=true writes.
| Name | Required | Description | Default |
|---|---|---|---|
| line | No | 0-based line; disambiguate same-named (optional). | |
| path | No | File holding the symbol (else resolved via the index). | |
| apply | No | Write to disk (default false = preview). | |
| force | No | Delete even if referenced (default false = refuse). | |
| symbol | Yes | Declaration to delete. | |
| backend | No | ||
| maxResults | No | ||
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
In the absence of annotations, the description fully discloses key behaviors: it refuses deletion if the symbol is still referenced (listing references), allows override via force=true, and operates with a preview mode by default (apply=true writes to disk). This transparency helps the agent understand the tool's safety mechanisms.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, packing critical information into two sentences. It uses capitalization for emphasis and front-loads the key purpose ('Delete a named declaration') while efficiently conveying behavioral details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the main behavior and key parameters but lacks explanation of the return value (e.g., what the preview returns) and omits descriptions for three parameters (projectPath, backend, maxResults). While the essential safety features are well-documented, the overall completeness is hindered by these gaps, especially given the tool's complexity with 8 parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers 63% of parameters with descriptions. The description adds value by explaining the semantics of 'force' (overrides refusal) and 'apply' (writes to disk), which are not fully detailed in the schema. However, it does not address the remaining 37% (projectPath, backend, maxResults), leaving some ambiguity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it deletes a named declaration, using the verb 'Delete' and specifying the resource. It also distinguishes itself from alternative actions like 'Edit-deleting' by emphasizing safety features, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells when to use this tool ('USE INSTEAD OF Edit-deleting it') and explains its behavior under different conditions (refuses if referenced, force overrides, preview vs. apply). This provides clear guidance on usage and when to apply force or apply modes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_symbolA
Find a symbol DECLARATION (class/function/type/var) by name/substring — semantic index, not grep. → capped kind name @ file:line, no bodies. Use instead of grep/rg to locate a symbol.
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | Symbol name or substring. | |
| path | No | Scope to a file/class (basename or path substring). An inherited symbol not declared there is reported tree-wide. | |
| backend | No | ||
| maxResults | No | ||
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does a solid job: it discloses semantic indexing, capped results, the output format, and that bodies are not returned. It does not mention exact cap limits or backend behavior, but the core behavioral profile is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two tight sentences with the main purpose front-loaded and an efficient arrow-style output spec. Every phrase earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The definition provides the core usage rule, the output shape, and the distinction from grep, which is enough for basic invocation. However, with no annotations, no output schema, and several undocumented optional parameters, it is adequate but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 40%, and the description mostly reinforces the meaning of q and vaguely gestures at cap behavior. Parameters like backend, maxResults, and projectPath remain unexplained, so the description does not compensate for the schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: find a symbol DECLARATION by name/substring. It also clarifies the semantic-index nature and distinguishes itself from grep-style search, though it does not explicitly name sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use this instead of grep/rg to locate a symbol, giving a clear substitution rule. It does not fully spell out when to prefer find_references or search_text, but the declaration-oriented wording implies the boundary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_textA
Raw text/regex search (string literals, comments, config — what the symbol index can't answer). Replaces Bash grep when you need text, not symbols. → capped file:line: line. For code symbols prefer search_symbol.
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes | String or regular expression. | |
| docs | No | With no path/glob, widen the sweep to docs/config text (md/json/yaml/…). | |
| glob | No | Only files matching this basename glob (e.g. *.md). | |
| path | No | Search ONE file (any extension auto-included). | |
| maxResults | No | ||
| projectPath | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the output format as 'capped `file:line: line`' and mentions widening the search for docs/config text via the docs parameter. However, it lacks explicit statements about safety (read-only) or potential limitations like rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: two sentences plus an arrow note. Every sentence adds value and is front-loaded with the core purpose. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description partially covers return format ('capped file:line: line'). It covers key parameters and usage context but omits details on maxResults and projectPath. For a search tool with 6 parameters, it is fairly complete but not exhaustive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67%; the description adds value beyond the schema by explaining the 'docs' parameter behavior ('widen the sweep to docs/config text') and clarifying that 'path' searches one file and 'glob' filters basename. It does not cover projectPath or maxResults, but those are somewhat self-explanatory. The total value added is moderate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool performs raw text/regex search, specifies the resource (text like string literals, comments, config), and distinguishes it from sibling search_symbol. The verb 'search' and resource 'text' are explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells when to use this tool ('when you need text, not symbols') and when not to ('For code symbols prefer search_symbol'). It also mentions it replaces Bash grep, providing clear alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vts_adminA
vs-token-safer admin/meta ops (rarely needed reflexively) — set op, put that op's args in params:
setup·config·savings{graph|daily|history}·savings_reset — configure / settings / tokens saved
discover{since,learn} — code searches that BYPASSED vts · warmup·preindex — pre-build the index
scope — indexing scope + TU stats · index{status} — build the committable .vts-index (cold-start tier)
gen_compile_db{apply,…} — generate the UE clangd compile DB
git·p4{argv} — run a READ-ONLY VCS command, output compacted (mutating REFUSED)
| Name | Required | Description | Default |
|---|---|---|---|
| op | Yes | Which admin op (see description). | |
| params | No | Args for the op, e.g. {"argv":["status"]} for git, {"since":30} for discover. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It does reveal important traits: VCS commands are READ-ONLY, output is compacted, mutations are refused, and discover targets code searches that BYPASSED vts. However, it does not disclose side effects or persistence behavior for setup, config, savings_reset, or gen_compile_db{apply,...}, which are potentially mutating operations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but efficient, front-loading the core 'rarely needed reflexively' warning before enumerating operations. The grouping and examples pack substantial information into a compact space, though the telegraphic separators and brace syntax like savings{graph|daily|history} require careful parsing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the high complexity of a 12-op dispatcher with nested params and no output schema, the description provides a solid overview and several examples but leaves gaps. Sub-op syntax for savings/discover/gen_compile_db is not fully specified, return values are not described, and side effects for several mutating-looking operations are omitted. It is adequate for orientation but not fully self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides only an op enum and a generic params object, so the description adds real meaning by explaining the calling convention: 'set op, put that op's args in params'. Concrete examples such as {"argv":["status"]} and {"since":30} clarify the expected param shape beyond what the schema alone provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource ('vs-token-safer') and the function ('admin/meta ops'), then enumerates concrete operations such as setup, index, discover, git, and p4. It is clearly distinguishable from the sibling code-manipulation tools, especially by the 'rarely needed reflexively' framing. It is a multi-op dispatcher rather than a single-verb tool, so it misses a 5 slightly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete when-to-use context: admin/meta setup, index building, discovery of bypassed searches, and executing READ-ONLY VCS commands. It also explicitly warns that mutations are REFUSED for git/p4, and 'rarely needed reflexively' discourages using this tool as a default. It does not name sibling tools explicitly, but the usage boundaries are clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
4 tool updates
v1.1.5- Added
concept_search - Added
read_symbol - Added
search_symbol - Added
vts_admin
5 tool updates
v1.1.2- Removed
concept_search - Added
detect_changes - Removed
read_symbol - Removed
search_symbol - Removed
vts_admin
1 tool update
v0.42.21- Changed
search_symbol1 field changed- added
Input schema / properties / pathAdded value: +{ + "description": "Scope to a file/class (basename or path substring). An inherited symbol not declared there is reported tree-wide.", + "type": "string" +}
TDQS
Each tool has a clearly distinct purpose: find_files (file search), search_text (text/regex), find_references (symbol references), goto_definition (definitions), diagnostics (errors), hover (type info), document_symbols (outline), safe_delete (declaration removal), rename, replace_symbol_body, insert_symbol (editing), and detect_changes (diff impact). No confusing overlap.
All tool names follow a consistent snake_case pattern, predominantly in verb_noun form (find_files, search_text, find_references, replace_symbol_body, insert_symbol, detect_changes). Even safe_delete and document_symbols fit the pattern. No mixed conventions.
12 tools is a well-scoped number for a code manipulation and analysis server. It covers navigation, search, diagnostics, and safe editing without being bloated or too sparse. Each tool earns its place.
The set covers core navigation, diagnostics, and safe editing operations (delete, rename, replace, insert). However, it lacks some common refactoring operations like moving symbols or changing signatures, which is a minor gap for comprehensive code manipulation.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Code intelligence for coding agents: semantic, AST, graph, and full-text search. 279+ languages.
Token-efficient search for coding agents over public and private documentation.
Ask a codebase what calls what: search, blast radius, paths between symbols, and diffs.
Codebase intelligence for agents: 152 structured artifacts across 21 programs, one call.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceFast semantic code search for AI agents — find symbols, references, and callers across any codebase.9Apache 2.0
- AlicenseNot gradedqualityAmaintenanceEnables AI coding agents to efficiently query code context via a symbol graph, reducing token usage by up to 20x.1,223469-
- FlicenseNot gradedqualityAmaintenanceLocal-first code retrieval for AI agents — cuts codebase context from thousands of tokens to a few hundred, with zero hallucinated file paths.3-
- AlicenseNot gradedqualityBmaintenanceEnables LLM agents to efficiently understand and navigate a codebase by providing semantic search over symbols and a reference graph, replacing expensive grep/glob calls with structured tools like definition lookup, caller/callee queries, and change-impact analysis.1MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/JSungMin/vs-token-safer'
If you have feedback or need assistance with the MCP directory API, please join our Discord server