Reflex
OfficialReflex is a local-first code search server that lets you search code, analyze dependencies, and manage its index via MCP tools.
Full-text, regex, and AST-based code search with filters for language, file, glob, symbol kind, and coverage of lock/generated files.
Symbol-aware search: find definitions, all references/callers, and count usages.
Minimal-output tools: list every occurrence location or get total counts without loading previews.
Dependency analysis: imports, reverse dependents, transitive dependencies, hotspots, circular chains, unused files, and disconnected islands.
Codebase orientation: gather structure, frameworks, entry points, config files, and project type.
Index management: build/update the index, check freshness/staleness, and force full rebuilds.
Freshness reporting on every response so you know when results may be incomplete due to uncommitted edits.
Supports natural language code search and codebase analysis using OpenAI's models as the AI provider.
Reflex
Instant local code search — CLI, scripts, and AI agents
Reflex is a local-first, full-text code search engine. Use it from the command line, pipe it into scripts, or connect it to AI coding assistants (Claude Code, Cursor, and any MCP-compatible tool) for instant symbol lookup, dependency analysis, and codebase exploration — fully offline, fully deterministic, no cloud required.
Quick start
1. Install
# Via NPM
npm install -g reflex-search
# Or via Cargo
cargo install reflex-search2. Index and search
# From your project root
rfx index
# Full-text search
rfx query "extract_symbols"
# Symbol definitions only
rfx query "CacheManager" --symbols
# JSON output for scripting
rfx query "TODO" --json --limit 203. (Optional) Connect to an AI agent via MCP
With Claude Code:
# every project
claude mcp add-json --scope user reflex '{"type":"stdio","command":"rfx","args":["mcp"],"alwaysLoad":true}'
# this project only (writes .mcp.json)
claude mcp add-json --scope project reflex '{"type":"stdio","command":"rfx","args":["mcp"],"alwaysLoad":true}'"alwaysLoad": true makes Claude Code load Reflex's tool schemas at session start, so the
agent can call Reflex at once instead of first spending a turn on ToolSearch. The plain
claude mcp add --scope user reflex -- rfx mcp also works, without it.
For other MCP clients, register a stdio server with command rfx and args ["mcp"].
Your AI assistant can now call search_code, find_references, get_dependencies, and more.
See Claude Code + Reflex MCP Quickstart for MCP setup, key tools, and troubleshooting.
Related MCP server: codeix
Why Reflex vs. built-in search tools
Capability | grep / ripgrep | Built-in AI search | Sourcegraph | Reflex |
Full-text search | ✅ | ✅ | ✅ | ✅ |
Symbol-aware filtering | ❌ | Partial | ✅ | ✅ |
Dependency analysis | ❌ | ❌ | Partial | ✅ |
Deterministic results | ✅ | ❌ | ✅ | ✅ |
Local-first / offline | ✅ | ❌ | ❌ | ✅ |
MCP server built-in | ❌ | — | ❌ | ✅ |
JSON output for agents | Manual | ✅ | ✅ | ✅ |
Measured efficiency (A/B vs. built-in AI search)
The A/B harness in benches/efficacy/ runs Claude Code on the same
code-search tasks with Reflex (via MCP) and with its built-in Grep/Glob, paired per task,
on pinned checkouts of Reflex, ripgrep and tokio. Measured on Reflex 2.0.3, 2026-09-28,
8 trials per task and arm. Ratios are Reflex ÷ built-in, so > 1.0 means Reflex costs more.
Tasks | Model | Tokens (95% CI) | Cost | Turns (median) | Accuracy |
9 find-all-usages | Opus 5.5 | 1.66 [1.05, 1.69] | 1.27× | 2 → 3 | equal (both near-perfect) |
9 find-all-usages | Sonnet 5 | 1.65 [1.06, 2.25] | 2.07× | 2 → 4 | Reflex more complete on 6 of 9 tasks |
13 comprehension / cross-module | Opus 5.5 | 1.26 [1.07, 1.30] | 1.10× | 6 → 6 (B more in 55 of 104 pairs, fewer in 27) | equal recall |
What drives the cost. It is round-trips, not payload. Claude Code defers MCP tool
schemas, so the first Reflex call costs an extra ToolSearch turn; Sonnet 5 also added
check_index_status calls. Trials where the agent ignored Reflex cost the same as the
control (1.04–1.07×); trials that used it cost 1.55–1.68×. Columnar results already save
about 20% of bytes per call, which the extra turns outweigh.
Honest reading. Reflex does not save tokens over built-in search in these agent runs.
Its value is capability: symbol-aware search, dependency analysis, find_references in one
call, exact counts without loading content, and more complete answers from weaker models on
large result sets. Full method, per-task tables and limits: .context/EFFICACY-2.0.3.md.
Performance
Measured on a Kubernetes checkout (27,448 indexed files, 245 MB of text) on a 16-core machine with an NVMe disk, release build:
before 2.0.0 | 2.0.0 | |
| 532 s | 7.7 s |
Background symbol pass | 44.9 s | 3.4 s |
Symbol cache on disk | 256 MB | 29 MB |
Peak memory while indexing | 1.37 GB | 1.05 GB |
The index files are byte-identical before and after, so query results and latency did not change with the indexing rewrite. On the Linux kernel, the symbol pass that used to stall part-way now completes in seconds.
Query latency on the 30 MB latency-harness corpus (2.0.0 medians, through a real rfx mcp round-trip): zero-hit search 0.07 ms, common-word first page 2.7 ms, regex fn (get|set)_\w+ 10 ms, find_references 6.2 ms.
For a plain one-off scan of a mid-size repository, ripgrep remains a strong choice. Reflex is built for what a linear scan cannot do — symbol and dependency queries, and "every occurrence" on very large trees where scanning every file is the slow part.
MCP tools
When connected via MCP, your AI assistant gets these tools:
Tool | What it does |
| Full-text or symbol search with line numbers and context; |
| Regex pattern matching across the codebase |
| Fast file+line discovery (minimal tokens) |
| Symbol definition + all usage sites in a single call; the primary code-navigation tool for AI agents |
| Structure-aware search via Tree-sitter AST queries (slow; always pass |
| Imports of a file; |
| Import-graph analysis: |
| Codebase structure and project-type summary |
| Force an index run (rarely needed: every tool updates the index first) |
| Report whether the index matches the files on disk, without updating it |
Eight older tool names still work but are deprecated: count_occurrences (use search_code with mode: "count"), get_dependents and get_transitive_deps (use get_dependencies with reverse / depth), and find_hotspots, find_circular, find_unused, find_islands, analyze_summary (use analyze with kind).
No rfx index needed after edits. Every command and MCP tool updates a stale index before it answers (only the changed files) and builds a missing one; pass --no-update (rfx mcp --no-update) to answer from the index as it is.
Three behaviours agents rely on:
Whole identifiers by default.
verify_csrfdoes not matchverify_csrf_form_field; passcontains: truefor substring matching (grep -F) orignore_case: trueforrg -i. A zero result names the substring count in ahint.Freshness on search responses.
statusandcan_trust_resultscompare the working tree (size, mtime, content hash) with what the index holds; the index is updated before each call, socan_trust_results: falseappears only when that update could not run (warningssays why).Lock and generated files stay out of the way. They are indexed but excluded from results unless you pass
include_locks/include_generated; a zero result caused only by them says so.
See docs/mcp-tool-cheatsheet.md for a decision tree by agent intent.
CLI usage
Reflex also works as a standalone CLI for humans and shell scripts.
# Full-text search (finds every occurrence)
rfx query "extract_symbols"
# Symbol definitions only (faster, uses tree-sitter)
rfx query "extract_symbols" --symbols
# Filter by language and symbol kind
rfx query "parse" --lang rust --kind function --symbols
# Regex search
rfx query "fn.*test" --regex
# Case-insensitive (like rg -i); still uses the trigram index
rfx query "realmid" -i
rfx query "(?i)realm_?id" --regex
# Patterns that start with `-`
rfx query --pattern '-> Result<'
# Count only, with per-phase timings on stderr
rfx query "unwrap" --count --timing
# Include lock files / generated files, or search the plain-text tier only
rfx query "1.0.190" --include-locks
rfx query "timeout" --lang text
# JSON output for programmatic use
rfx query "unwrap" --json --limit 10
# Pipe file paths to other tools
vim $(rfx query "TODO" --paths)Interactive TUI mode — run rfx query with no pattern to launch live search with keyboard navigation.
Dependency analysis
rfx deps src/main.rs # Show direct imports
rfx deps src/config.rs --reverse # What imports this file
rfx deps src/api.rs --depth 3 # Transitive dependencies
rfx analyze --circular # Find circular dependency chains
rfx analyze --hotspots # Most-imported files
rfx analyze --unused # Files with no incoming dependenciesNatural language search
rfx ask "Find all TODOs in Rust files" # Translate to rfx query and run
rfx ask "How does authentication work?" --agentic # Multi-step codebase reasoning
rfx ask # Interactive chat modeRequires an AI provider configured via rfx llm config (OpenAI, Anthropic, OpenRouter, or any OpenAI-compatible endpoint).
Other commands
rfx index # Build / update the search index (then spawns the symbol pass)
rfx index --force # Full rebuild from scratch
rfx index status # Background symbol indexing status
RUST_LOG=info rfx index # Per-phase timings (read/extract, database, trigram write)
rfx watch # Auto-reindex on file changes
rfx stats # Index statistics
rfx list-files # Every indexed file
rfx clear # Delete the local cache
rfx context # Codebase context for AI prompts
rfx snapshot # Structural snapshots for change tracking
rfx pulse generate # Documentation site (static HTML) from the index
rfx pulse serve # Preview it locally
rfx pulse map # Architecture diagram (Mermaid / D2)
rfx serve --port 7878 # Local HTTP API serverRun rfx <command> --help for full options.
Documentation sites (Pulse)
rfx pulse generate builds a two-tab docs site from the index: Docs (overview,
guides, CLI and API reference for Rust, Python and Go, a changelog page per release) and
Internals (architecture, dependency map, module pages). The output is plain HTML for
any static host. It needs Node 22.12+ to build; the site runtime downloads once. An
optional LLM adds prose, and a deterministic gate drops any sentence the index does not
support. A GitHub Action is included. See docs/features/PULSE.md.
Installation
NPM (recommended)
npm install -g reflex-searchCargo
cargo install reflex-searchSetup note: run rfx commands from your project root directory. Add .reflex/ to your .gitignore to exclude the search index from version control.
Supported languages
Full symbol extraction (functions, classes, methods, types, etc.) for 15 languages:
Systems: Rust, C, C++, Zig
Backend: Python, Go, Java, C#, PHP, Ruby, Kotlin
Frontend: TypeScript, JavaScript, Vue, Svelte
Swift is temporarily disabled (tree-sitter-swift 0.7.x grammar incompatibility).
rfx query --lang swiftemits a warning; full-text search still works.
Coverage
Coverage matches ripgrep's defaults: every non-binary file that is not gitignored and not under a dot-directory (.github/, .githooks/, .cargo/ …). Hidden paths are not indexed unless [index] hidden = true. Lock and generated files are indexed but left out of results unless you pass include_locks / include_generated. Select the non-code tier with --lang text; select lock or generated files alone with --lang lock / --lang generated. [index] mode = "allowlist" indexes only code plus a fixed docs/config extension list; [index] hidden = true indexes dot-directories (never .git/ or .reflex/). A zero result names its cause in excluded_reason (hidden, not_indexed, lock_or_generated, whole_identifier) and a hint. Files without a symbol parser (the text tiers, Swift) are fully text-searchable but yield no --symbols results.
Configuration
# .reflex/config.toml (project-level)
[index]
languages = [] # Empty = all supported languages
mode = "tracked" # ripgrep's defaults; "allowlist" = code + a fixed docs/config extension list
hidden = false # true walks dot-directories (never .git/ or .reflex/)
text_tier = true # index docs, config and data files as `text`
max_file_size = 10485760 # 10 MB
# Optional, gitignore rules (a `/` anchors at the root; bare names match anywhere):
# include.patterns = ["src/**/*.rs"]
# exclude.patterns = ["vendor/**"]
[performance]
parallel_threads = 0 # indexing and query pools; 0 = auto (80% of cores, max 32)
symbol_threads = 0 # background symbol pass; 0 = auto (50% of cores, max 32)Environment variables, mostly for benchmarking and CI: REFLEX_INDEX_BATCH_FILES / REFLEX_INDEX_BATCH_BYTES (batch bounds while indexing, default 5000 files / 48 MiB), REFLEX_SYMBOL_THREADS, REFLEX_FRESHNESS_TTL_MS (how long rfx mcp memoises the freshness verdict), REFLEX_MCP_TIMING=1 (a timings object on search responses), REFLEX_SQLITE_JOURNAL=delete (for network filesystems that cannot do WAL).
For AI provider configuration (rfx ask, rfx pulse), run rfx llm config.
Architecture
Reflex uses a trigram-based inverted index with a background symbol cache:
Indexing: a thread pool reads and hashes every file, extracts imports with tree-sitter, and extracts trigram postings. Each batch is built per trigram shard in parallel and partial batches are merged by byte copy, so the output is identical whatever the batch boundaries.
trigrams.binandcontent.binare written to a temp file, synced and renamed, never left short.Symbols:
rfx indexspawns a detached pass that parses every file once with one combined tree-sitter query per language and stores compressed symbol lists inmeta.db. Queries parse cache misses on demand, so--symbolsworks before the pass has finished.Full-text queries: intersect trigram posting lists → verify candidate lines in parallel. Freshness is judged by file content (size, mtime, hash), not by commit, so a commit of already-indexed files is not "stale".
Symbol queries: trigrams narrow the candidates → their symbols are read from the cache; only cache misses are parsed.
.reflex/
meta.db # SQLite: file metadata, symbol cache, dependency graph, stats
trigrams.bin # Inverted index (memory-mapped)
content.bin # Full file contents (memory-mapped)
config.toml # Index settingsSecurity
rfx serve binds to 127.0.0.1:7878 by default — loopback only, no authentication. Do not expose it to the network. See CLAUDE.md for the full threat model.
Contributing
cargo build --release # Build
cargo test # Test
cargo clippy --all-targets # Lint
REFLEX_LATENCY_BUDGET=1 cargo test --release --test latency_budget -- --ignored --test-threads=1 # Query latency budgets
rfx index # Refresh index after code changesSee CONTRIBUTING.md for guidelines.
License
MIT — see LICENSE for details.
Fast code search for developers — works standalone, in scripts, and with AI coding agents
Available Tools
10 toolsanalyzeA
Import-graph analysis. kind: summary (counts), hotspots (most-imported files), circular (import cycles), unused (files nothing imports; entry points included), islands (disconnected groups). Answers are paginated with limit/offset.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | ||
| sort | No | asc or desc | |
| limit | No | Max results (default 200) | |
| offset | No | Skip this many results (next page) | |
| min_dependents | No | hotspots/summary: minimum importers | |
| max_island_size | No | islands: maximum files | |
| min_island_size | No | islands: minimum files |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does add useful behavior: pagination semantics ("paginated with limit/offset") and the notable nuance that unused includes entry points, which prevents misreading results. However it omits whether an index is required, error behavior, or return shape for a 7-parameter analysis tool.
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 tight sentences: purpose front-loaded, then a dense but scannable kind enumeration, closing with the pagination note. No filler and nothing buried.
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 and no annotations, so the description must fully frame the tool. It covers modes and pagination but leaves output format per kind, index prerequisites (surprising given index_project/check_index_status siblings), and default behavior for optional filters unaddressed.
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 86%, so the schema already documents sort, limit, offset, min_dependents, and the island-size bounds. The description only reinforces the kind enum and the limit/offset pagination pairing, adding little beyond the structured fields. Baseline 3 applies.
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?
States the resource precisely ("Import-graph analysis") and enumerates all five modes with parenthetical definitions (summary=counts, hotspots=most-imported, circular=cycles, unused=files nothing imports, islands=disconnected groups). This makes each operation concrete, though it never distinguishes itself from the conceptually adjacent sibling get_dependencies.
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 kind definitions imply which mode answers which question, but there is no explicit when-to-use guidance, no statement of prerequisites (e.g., whether an index must exist), and no routing against siblings like get_dependencies or find_references. Usage is inferable but not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_index_statusA
Report whether the index matches the files on disk, without updating it. Rarely needed: every other tool updates the index first.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden, and it does disclose the critical trait: this reads status without mutating the index, unlike every sibling. It does not describe the shape of the result, but the core safety/mutation profile is covered.
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 short sentences, front-loaded with the action and immediately followed by the routing caveat. Every clause earns its place.
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 zero-parameter, no-output-schema status check, the description conveys the operation, its non-mutating nature, and the rarity of use. The only mild gap is that it does not hint at what the report looks like (e.g., boolean vs. list of drifted files), but no output schema exists to defer to.
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 tool takes zero parameters, so per the rubric the baseline is 4. There is nothing for the description to add or omit.
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?
States a specific verb and resource: reports whether the index matches files on disk, and explicitly notes it does so without updating. This clearly separates it from siblings like index_project and the search tools that mutate the index first.
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?
Gives explicit when/when-not guidance: 'Rarely needed: every other tool updates the index first.' The agent knows this is an exception path and that the default choice among siblings is a search/index tool, not this one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_referencesA
A symbol's definition and every usage in one call, in code files only; matches in strings and comments are left out (include_strings:true keeps them). Answer: {definition, references, total_references, returned_count, filtered_out, pagination}; mode:"count" returns the count after filtering.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Only paths containing this substring | |
| glob | No | Only paths matching (gitignore rules) | |
| kind | No | Symbol kind of the definition | |
| lang | No | Language filter: rust, python, typescript, text, … | |
| mode | No | count: {count, files} only | |
| force | No | Run a pattern too broad to run by default | |
| limit | No | Max results (default 200, at most 500) | |
| offset | No | Skip this many results (next page) | |
| exclude | No | Skip paths matching (gitignore rules) | |
| pattern | Yes | Text to find | |
| contains | No | Substring match (grep -F) instead of whole identifiers | |
| ignore_case | No | Case-insensitive (rg -i) | |
| include_locks | No | Also search lock files | |
| include_strings | No | Keep matches in strings and comments | |
| include_generated | No | Also search generated files |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does meaningful work: it discloses that only code files are searched, that string/comment matches are filtered by default, and it exposes filtered_out plus pagination fields. It omits any mention of the 'force' safeguard for overly broad patterns, which is a notable behavioral gap.
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 behavior and scope come first, followed by the return shape, so it is well front-loaded. It is dense and reads as a run-on, but nearly every clause carries information an agent needs.
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 exists, and the description compensates by enumerating the answer fields (definition, references, total_references, returned_count, filtered_out, pagination). For a 15-parameter read tool with fully documented schema, the only real gap is the undocumented 'force' safeguard.
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 100%, so the schema already documents all 15 parameters, including include_strings and mode. The description restates those two behaviors (include_strings keeps string/comment matches; mode:'count' returns counts after filtering) without adding syntax or format detail beyond the schema, so the baseline of 3 is appropriate.
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 a specific verb+resource ('a symbol's definition and every usage in one call') and scopes it ('in code files only'), which clearly separates it from a generic grep-style sibling like search_code or search_regex. It stops short of naming which sibling to use instead, so it earns a 4 rather than a 5.
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?
Usage is implied through the default filtering behavior (strings/comments excluded, include_strings overrides) and the count-mode variant, but there is no explicit when-to-use-this-vs-siblings guidance or statement of prerequisites. Adequate but leaves the routing decision to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gather_contextC
Project overview: structure, file types, frameworks, entry points, test layout, config files. Pass flags to pick sections (default: all).
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Subdirectory | |
| depth | No | Tree depth | |
| framework | No | ||
| structure | No | ||
| file_types | No | ||
| test_layout | No | ||
| config_files | No | ||
| entry_points | No | ||
| project_type | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden and largely fails it. It never states that this is a read-only inspection, whether it touches the filesystem beyond reading, or what the response contains. For a 9-parameter tool with zero annotation coverage this is thin.
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 compact sentences, front-loaded with the content list followed by the flag behavior. Efficient, though the terse telegraphic style leaves some ambiguity about what each section returns.
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 read-only overview tool with no output schema, the description covers the section flags adequately but leaves path, depth, project_type, return shape, and index prerequisites unexplained. Adequate as a minimum but incomplete for a 9-parameter 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?
With only 22% schema description coverage, the description does add value by mapping the section names to the boolean flags (structure, file_types, framework, entry_points, test_layout, config_files). However it omits project_type entirely and gives no meaning for path or depth, leaving real 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?
Names the resource (project overview) and enumerates the sections it covers: structure, file types, frameworks, entry points, test layout, config files. Clearly distinguishes itself from search/index siblings, though the verb itself only comes from the tool name rather than the description.
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 only guidance is 'Pass flags to pick sections (default: all).' There is no statement of when to reach for this tool versus analyze, index_project, or check_index_status, and no prerequisites such as whether the project must be indexed first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_dependenciesA
The imports of a file: path, line, internal/external/stdlib. reverse:true lists the files that import it instead; depth:N follows imports N levels (a list of {path, depth}). Static imports only; path may be a fragment or file name.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path, fragment or name | |
| depth | No | Follow imports this many levels | |
| reverse | No | Files that import this file |
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 does well: it discloses the result shape (path, line, classification) and that depth returns a {path, depth} list. It also flags a meaningful constraint, 'Static imports only.' It stops short of any performance or indexing caveats.
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?
A single dense sentence cluster with no filler; the core behavior and the reverse alternative are front-loaded. The semicolon stacking is compact but slightly terse, and 'counter' terminology is never defined.
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 3-parameter read tool with no output schema, the description covers the return fields, the mode parameters, and the static-import limitation. An agent can call it correctly; only cross-tool routing against find_references is left unaddressed.
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 100%, so the baseline is 3, but the description earns more by explaining both optional parameters' actual effect: reverse inverts the query direction, and depth changes the return type to a {path, depth} list. It also adds that path may be a fragment or file name, useful caller-facing detail.
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?
States a specific resource ('The imports of a file') and enumerates the returned fields (path, line, internal/external/stdlib), so the agent knows exactly what it retrieves. It does not, however, differentiate itself from sibling find_references, which the reverse:true mode overlaps with.
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 clarifies the two mode-switching parameters ('reverse:true lists the files that import it instead; depth:N follows imports N levels') and notes the 'Static imports only' limitation, which is real usage guidance. It never states when to prefer this over find_references or analyze, leaving cross-tool selection inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
index_projectA
Force an index run. Rarely needed: every tool updates the index before it answers. force:true rebuilds a corrupted index.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | Full rebuild | |
| languages | No | Only these languages |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose meaningful behavior: every other tool auto-updates the index before answering, and force triggers a full rebuild for corruption. It omits cost/duration, whether the rebuild blocks concurrent tools, or whether the operation is reversible.
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 tight sentences, front-loaded with the action and the caveat, with zero filler. The corruption case is placed right where the agent needs it.
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 and only two optional params, so the description need not explain returns. It covers purpose, the normal-case discouragement, and the force semantics; the languages parameter is left entirely to the schema but that is acceptable given 100% coverage.
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 100% so both parameters are already documented ('Full rebuild', 'Only these languages'). The description still adds value by tying force:true to the specific scenario of a corrupted index, which the schema alone does not convey.
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?
States a specific verb+resource ('Force an index run') and immediately scopes it with 'Rarely needed', which separates it from the search/analysis siblings that read the index. It does not name check_index_status explicitly, so differentiation is implicit rather than 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?
Gives a clear when-not-to-use signal ('Rarely needed: every tool updates the index before it answers') and a concrete when-to-use trigger ('force:true rebuilds a corrupted index'). It stops short of naming the alternative tool (check_index_status) for diagnosing index health.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_locationsA
Where does X occur? Every match as {path, line}: the cheapest search, no limit. preview:true adds each matching line (trimmed, 120 chars). Same matching as search_code.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Only paths containing this substring | |
| glob | No | Only paths matching (gitignore rules) | |
| lang | No | Language filter: rust, python, typescript, text, … | |
| force | No | Run a pattern too broad to run by default | |
| exclude | No | Skip paths matching (gitignore rules) | |
| pattern | Yes | Text to find | |
| preview | No | Add each matching line (120 chars) | |
| contains | No | Substring match (grep -F) instead of whole identifiers | |
| ignore_case | No | Case-insensitive (rg -i) | |
| dependencies | No | Attach each file's imports | |
| include_locks | No | Also search lock files | |
| include_generated | No | Also search generated files |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose key traits: unbounded result set ('no limit'), the return shape {path, line}, and preview's trimming to 120 chars. It omits ordering, permissions, and broad-pattern guarding, but covers the main behavioral surprises.
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?
Three compact clauses, front-loaded with the core question and result shape, then preview behavior, then matching semantics. 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?
For a 12-parameter search tool with a fully documented schema and no output schema, the description supplies what the schema cannot: the result shape and the 'no limit' behavior. It doesn't attempt to summarize the many filter parameters, but the schema handles those.
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 100%, so the baseline is 3; every parameter including preview is already documented in the schema. The description adds only marginal detail ('trimmed, 120 chars') beyond the schema's own preview text.
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?
Names a specific operation (find every occurrence of a pattern) and its output shape {path, line}. 'The cheapest search, no limit' plus 'Same matching as search_code' gives some sibling differentiation against search_code/search_regex, though the misleading tool name list_locations isn't explicitly reconciled.
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?
Implies usage via 'the cheapest search, no limit', suggesting it's the go-to for exhaustive cheap matching. It references search_code for matching semantics but never states when NOT to use it or which sibling to prefer for regex/AST/reference searches.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_astA
Tree-sitter structural search, e.g. (function_item) @fn. Slow: parses every file that lang and glob select, so always pass glob. Prefer search_code with symbols:true.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Only paths containing this substring | |
| glob | No | Only paths matching (gitignore rules) | |
| lang | Yes | Language of the query | |
| force | No | Run without a glob | |
| limit | No | Max results (default 200, at most 500) | |
| paths | No | Return file paths only | |
| offset | No | Skip this many results (next page) | |
| exclude | No | Skip paths matching | |
| pattern | Yes | Tree-sitter query (S-expression) | |
| dependencies | No | Attach each file's imports |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose a key cost trait: it parses every file selected by lang and glob, hence slow. It implies the glob requirement (with force as the escape hatch, per schema). It does not mention read-only safety or result-return behavior, but the performance disclosure is the important one here.
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?
Three short sentences, front-loaded with the core purpose and the adversative 'Slow:' constraint immediately after the example. Nothing is wasted and the alternative is the last item.
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 10-parameter tool with no annotations and no output schema, the description covers the operative pitfalls (slowness, glob requirement, alternative tool). Details like pagination via limit/offset and the paths/dependencies toggles are left to the schema, which is acceptable.
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 100%, so baseline would be 3, but the description adds real intent for `glob` ('always pass glob') and implies when `force` is relevant. It does not elaborate on the other eight parameters, though the schema documents them 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?
States a specific verb and resource ('Tree-sitter structural search') and grounds it with a concrete query example `(function_item) @fn`, which immediately conveys the S-expression pattern semantics. It is clearly distinguishable from search_code and search_regex siblings.
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 routes the agent elsewhere ('Prefer search_code with symbols:true') and gives a hard usage rule ('always pass glob'), plus the performance rationale behind it. Both when-to-use and when-to-prefer-an-alternative are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_codeA
Search code for a literal pattern: every match with path, line and preview (for path and line only, list_locations is cheaper). Whole identifiers by default; contains:true for substrings; symbols:true for definitions only (kind narrows them). Answer: {columns, rows} (each row aligns with columns) plus pagination; when has_more, fetch the next page with offset. total_count is exact only when total_is_exact.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Only paths containing this substring | |
| glob | No | Only paths matching (gitignore rules) | |
| kind | No | Symbol kind: function, struct, class, trait, … | |
| lang | No | Language filter: rust, python, typescript, text, … | |
| mode | No | count: {count, files} only | |
| exact | No | Exact symbol name | |
| force | No | Run a pattern too broad to run by default | |
| limit | No | Max results (default 200, at most 500) | |
| paths | No | Return file paths only | |
| expand | No | Whole symbol body | |
| offset | No | Skip this many results (next page) | |
| exclude | No | Skip paths matching (gitignore rules) | |
| pattern | Yes | Text to find | |
| symbols | No | Definitions only | |
| contains | No | Substring match (grep -F) instead of whole identifiers | |
| ignore_case | No | Case-insensitive (rg -i) | |
| dependencies | No | Attach each file's imports | |
| include_locks | No | Also search lock files | |
| preview_length | No | Preview characters (default 180) | |
| include_generated | No | Also search generated files |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does substantial work: it describes the return shape ({columns, rows}), pagination via has_more/offset, and the caveat that total_count is exact only when total_is_exact. It omits any note on cost/performance or broad-pattern refusal beyond the schema's 'force' hint.
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?
Front-loaded with purpose, then matching modes, then return/pagination behavior, in a dense telegraphic style with no filler. Every clause carries information and suits a tool with 20 parameters.
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 20-parameter search tool with no output schema and no annotations, the description covers matching semantics, result shape, and pagination — the key things an agent needs. It could say more about when broad patterns are rejected and how total_count relates to pagination limits, but nothing critical is missing.
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 100%, so the baseline is 3, but the description adds real semantics beyond the schema: whole-identifier matching is the default, contains switches to substring, symbols restricts to definitions, and kind narrows them. It leaves the remaining ~17 filters unexplained, which the schema already covers.
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?
States a specific verb and resource ('Search code for a literal pattern') and immediately characterizes the output each match carries (path, line, preview). It also distinguishes itself from search_regex by saying 'literal' and from list_locations by naming that sibling as the cheaper path-and-line-only option.
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?
Gives one explicit routing rule ('for path and line only, list_locations is cheaper') and clarifies the default vs alternative matching modes (contains:true, symbols:true). It doesn't address the other siblings (search_ast, find_references), so it is clear but not fully exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_regexB
Search code with a regular expression (Rust regex): alternation, classes, anchors, e.g. fn (get|set)_\w+ or ->with\(. In JSON double each backslash. Same filters and answer as search_code.
| Name | Required | Description | Default |
|---|---|---|---|
| file | No | Only paths containing this substring | |
| glob | No | Only paths matching (gitignore rules) | |
| lang | No | Language filter: rust, python, typescript, text, … | |
| mode | No | count: {count, files} only | |
| force | No | Run a pattern too broad to run by default | |
| limit | No | Max results (default 200, at most 500) | |
| paths | No | Return file paths only | |
| offset | No | Skip this many results (next page) | |
| exclude | No | Skip paths matching (gitignore rules) | |
| pattern | Yes | Text to find | |
| ignore_case | No | Case-insensitive (rg -i) | |
| dependencies | No | Attach each file's imports | |
| include_locks | No | Also search lock files | |
| include_generated | No | Also search generated files |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It discloses useful regex-specific behavior: Rust regex syntax, examples, and JSON backslash escaping. It also says 'Same filters and answer as search_code,' which conveys some result semantics by reference. However, it does not state read-only nature, output format details, or pagination behavior explicitly.
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 front-loaded with purpose and stays compact. Each sentence adds value: regex syntax details, escaping instructions, and a reference to search_code for filters and answer shape. It avoids unnecessary length while remaining readable.
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 14 parameters, no annotations, and no output schema, the description is adequate but not fully complete. The schema covers parameter semantics well, and the description handles regex syntax and escaping. However, because there is no output schema, the description's reference to 'answer as search_code' leaves return format details dependent on another tool's definition.
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 100%, so the schema documents all 14 parameters. The description adds meaningful context for the required pattern parameter by clarifying that it is a Rust regular expression with alternation, classes, and anchors, and by explaining JSON backslash doubling. This goes beyond the schema's vague 'Text to find' for the most important parameter.
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: 'Search code with a regular expression (Rust regex).' It also names the regex engine and gives examples. However, it does not explicitly distinguish search_regex from the sibling search_code beyond saying 'Same filters and answer as search_code,' leaving the choice between them to inference.
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 explicit when-to-use guidance or comparison with alternatives. The reference to search_code implies similarity but does not say when to use regex search instead of plain code search. No exclusions or prerequisites are provided.
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.
17 tool updates
v2.0.3- Added
analyze - Removed
analyze_summary - Removed
count_occurrences - Removed
find_circular - Removed
find_hotspots - Removed
find_islands - Changed
find_references15 fields changed- changed
Input schema / properties / contains / descriptionPrevious value: -"Substring matching, like `grep -F`. DEFAULT IS FALSE, which matches WHOLE IDENTIFIERS ONLY: pattern \"verify_csrf\" does NOT match \"verify_csrf_form_field\", and \"jwks_rps\" does NOT match \"jwks_rps_limit\". Pass true to find a pattern anywhere inside a longer identifier. If a search returns 0, check the response `hint` — it reports how many substring matches exist."New value: +"Substring match (grep -F) instead of whole identifiers" - changed
Input schema / properties / exclude / descriptionPrevious value: -"Exclude files matching glob patterns (e.g., ['target/**', 'tests/**']) Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /."New value: +"Skip paths matching (gitignore rules)" - added
Input schema / properties / fileAdded value: +{ + "description": "Only paths containing this substring", + "type": "string" +} - changed
Input schema / properties / force / descriptionPrevious value: -"Force execution of potentially expensive queries (bypasses broad query detection)"New value: +"Run a pattern too broad to run by default" - changed
Input schema / properties / glob / descriptionPrevious value: -"Include files matching glob patterns (e.g., ['src/**/*.rs']) Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /."New value: +"Only paths matching (gitignore rules)" - changed
Input schema / properties / ignore_case / descriptionPrevious value: -"Match letters regardless of case, like `rg -i` (`ignore_case` + `contains` is `rg -i -F`). Default false. The trigram index is still used, so this costs about the same as a case-sensitive search."New value: +"Case-insensitive (rg -i)" - added
Input schema / properties / include_generatedAdded value: +{ + "description": "Also search generated files", + "type": "boolean" +} - added
Input schema / properties / include_locksAdded value: +{ + "description": "Also search lock files", + "type": "boolean" +} - changed
Input schema / properties / include_strings / descriptionPrevious value: -"Include matches inside string literals and comments (default: false). By default these are excluded to focus on real call sites."New value: +"Keep matches in strings and comments" - changed
Input schema / properties / kind / descriptionPrevious value: -"Filter definition lookup by symbol kind (function, class, struct, trait, etc.)"New value: +"Symbol kind of the definition" - changed
Input schema / properties / lang / descriptionPrevious value: -"Filter by language (rust, typescript, python, go, etc.)"New value: +"Language filter: rust, python, typescript, text, …" - changed
Input schema / properties / limit / descriptionPrevious value: -"Max references per page (default: 200, max: 500). The 200-result default covers most find-all tasks in a single call. Pagination applies to references only."New value: +"Max results (default 200, at most 500)" - changed
Input schema / properties / mode / descriptionPrevious value: -"Response mode: \"list\" (default) returns full results with definition + references; \"count\" returns only {count, pattern}: every reference AFTER string/comment filtering (all pages, not one); with include_strings:true it is the raw total and equals list-mode total_references."New value: +"count: {count, files} only" - changed
Input schema / properties / offset / descriptionPrevious value: -"Pagination offset for references (skip first N). Use with limit."New value: +"Skip this many results (next page)" - changed
Input schema / properties / pattern / descriptionPrevious value: -"Symbol name or text pattern to find references for (e.g., 'CacheManager', 'extract_symbols')"New value: +"Text to find"
- Removed
find_unused - Changed
gather_context9 fields changed- removed
Input schema / properties / config_files / descriptionRemoved value: -"List important configuration files" - changed
Input schema / properties / depth / descriptionPrevious value: -"Tree depth for structure (default: 2)"New value: +"Tree depth" - removed
Input schema / properties / entry_points / descriptionRemoved value: -"Show entry point files" - removed
Input schema / properties / file_types / descriptionRemoved value: -"Show file type distribution" - removed
Input schema / properties / framework / descriptionRemoved value: -"Detect frameworks and conventions" - changed
Input schema / properties / path / descriptionPrevious value: -"Focus on specific directory path"New value: +"Subdirectory" - removed
Input schema / properties / project_type / descriptionRemoved value: -"Detect project type (CLI/library/webapp/monorepo)" - removed
Input schema / properties / structure / descriptionRemoved value: -"Show directory structure" - removed
Input schema / properties / test_layout / descriptionRemoved value: -"Show test organization pattern"
- Changed
get_dependencies3 fields changed- added
Input schema / properties / depthAdded value: +{ + "description": "Follow imports this many levels", + "type": "integer" +} - changed
Input schema / properties / path / descriptionPrevious value: -"File path (supports fuzzy matching: 'Controllers/FooController.php' or just 'FooController.php')"New value: +"File path, fragment or name" - added
Input schema / properties / reverseAdded value: +{ + "description": "Files that import this file", + "type": "boolean" +}
- Removed
get_dependents - Removed
get_transitive_deps - Changed
index_project2 fields changed- changed
Input schema / properties / force / descriptionPrevious value: -"Force full rebuild (ignore incremental)"New value: +"Full rebuild" - changed
Input schema / properties / languages / descriptionPrevious value: -"Languages to include (empty = all)"New value: +"Only these languages"
- Changed
list_locations12 fields changed- changed
Input schema / properties / contains / descriptionPrevious value: -"Substring matching, like `grep -F`. DEFAULT IS FALSE, which matches WHOLE IDENTIFIERS ONLY: pattern \"verify_csrf\" does NOT match \"verify_csrf_form_field\", and \"jwks_rps\" does NOT match \"jwks_rps_limit\". Pass true to find a pattern anywhere inside a longer identifier. If a search returns 0, check the response `hint` — it reports how many substring matches exist."New value: +"Substring match (grep -F) instead of whole identifiers" - changed
Input schema / properties / dependencies / descriptionPrevious value: -"Include dependency information (imports) in results. Only extracts static imports."New value: +"Attach each file's imports" - changed
Input schema / properties / exclude / descriptionPrevious value: -"Exclude files matching patterns (e.g., ['vendor/**', 'tests/**']) Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /."New value: +"Skip paths matching (gitignore rules)" - changed
Input schema / properties / file / descriptionPrevious value: -"Filter by file path substring (e.g., 'Controllers')"New value: +"Only paths containing this substring" - changed
Input schema / properties / force / descriptionPrevious value: -"Force execution of potentially expensive queries (bypasses broad query detection)"New value: +"Run a pattern too broad to run by default" - changed
Input schema / properties / glob / descriptionPrevious value: -"Include files matching patterns (e.g., ['app/**/*.php']) Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /."New value: +"Only paths matching (gitignore rules)" - changed
Input schema / properties / ignore_case / descriptionPrevious value: -"Match letters regardless of case, like `rg -i` (`ignore_case` + `contains` is `rg -i -F`). Default false. The trigram index is still used, so this costs about the same as a case-sensitive search."New value: +"Case-insensitive (rg -i)" - changed
Input schema / properties / include_generated / descriptionPrevious value: -"Also search generated files by name (*.pb.go, *.min.js, *.min.css, *.map, *_generated.*). Indexed but left out unless asked for; `lang: \"generated\"` selects them alone. Default false."New value: +"Also search generated files" - changed
Input schema / properties / include_locks / descriptionPrevious value: -"Also search lock files (Cargo.lock, package-lock.json, *.lock, go.sum). They are indexed but left out unless asked for; `lang: \"lock\"` selects them alone. Default false."New value: +"Also search lock files" - changed
Input schema / properties / lang / descriptionPrevious value: -"Filter by language: rust, typescript, javascript, go, java, php, kotlin, python, c, cpp, csharp, ruby, vue, svelte, zig — or \"text\" for the plain-text tier (every other non-binary file: docs, config, templates, extensionless), \"lock\" for lock files, \"generated\" for generated files (the last two are excluded unless named or include_locks / include_generated is set)."New value: +"Language filter: rust, python, typescript, text, …" - changed
Input schema / properties / pattern / descriptionPrevious value: -"Search pattern (text to find)"New value: +"Text to find" - added
Input schema / properties / previewAdded value: +{ + "description": "Add each matching line (120 chars)", + "type": "boolean" +}
- Changed
search_ast10 fields changed- changed
Input schema / properties / dependencies / descriptionPrevious value: -"Include dependency information (imports) in results. Only extracts static imports."New value: +"Attach each file's imports" - changed
Input schema / properties / exclude / descriptionPrevious value: -"Exclude files matching glob patterns (e.g., ['target/**', 'node_modules/**']) Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /."New value: +"Skip paths matching" - changed
Input schema / properties / file / descriptionPrevious value: -"Filter by file path (substring)"New value: +"Only paths containing this substring" - changed
Input schema / properties / force / descriptionPrevious value: -"Force execution of potentially expensive queries (bypasses broad query detection)"New value: +"Run without a glob" - changed
Input schema / properties / glob / descriptionPrevious value: -"Include files matching glob patterns (STRONGLY RECOMMENDED to limit scope, e.g., ['src/**/*.rs']) Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /."New value: +"Only paths matching (gitignore rules)" - changed
Input schema / properties / lang / descriptionPrevious value: -"Language (REQUIRED: rust, typescript, javascript, python, go, java, c, cpp, csharp, php, ruby, kotlin, zig)"New value: +"Language of the query" - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of results (use with offset for pagination)"New value: +"Max results (default 200, at most 500)" - changed
Input schema / properties / offset / descriptionPrevious value: -"Pagination offset (skip first N results after sorting)"New value: +"Skip this many results (next page)" - changed
Input schema / properties / paths / descriptionPrevious value: -"Return only unique file paths"New value: +"Return file paths only" - changed
Input schema / properties / pattern / descriptionPrevious value: -"AST pattern (Tree-sitter S-expression, e.g., '(function_item) @fn')"New value: +"Tree-sitter query (S-expression)"
- Changed
search_code20 fields changed- changed
Input schema / properties / contains / descriptionPrevious value: -"Substring matching, like `grep -F`. DEFAULT IS FALSE, which matches WHOLE IDENTIFIERS ONLY: pattern \"verify_csrf\" does NOT match \"verify_csrf_form_field\", and \"jwks_rps\" does NOT match \"jwks_rps_limit\". Pass true to find a pattern anywhere inside a longer identifier. If a search returns 0, check the response `hint` — it reports how many substring matches exist."New value: +"Substring match (grep -F) instead of whole identifiers" - changed
Input schema / properties / dependencies / descriptionPrevious value: -"Include dependency information (imports) in results. **IMPORTANT:** Currently only supported for Rust files — passing this with any other language (typescript, python, go, etc.) will produce no dependency data. Only extracts static imports (string literals); dynamic imports are filtered. See CLAUDE.md for details."New value: +"Attach each file's imports" - changed
Input schema / properties / exact / descriptionPrevious value: -"Case-sensitive exact-identifier match. NOTE: substring matching is already OFF by default — use `contains: true` to turn it ON, not this flag."New value: +"Exact symbol name" - changed
Input schema / properties / exclude / descriptionPrevious value: -"Exclude files matching glob patterns (e.g., 'target/**') Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /."New value: +"Skip paths matching (gitignore rules)" - changed
Input schema / properties / expand / descriptionPrevious value: -"Show full symbol body (not just signature)"New value: +"Whole symbol body" - changed
Input schema / properties / file / descriptionPrevious value: -"Filter by file path (substring)"New value: +"Only paths containing this substring" - changed
Input schema / properties / force / descriptionPrevious value: -"Force execution of potentially expensive queries (bypasses broad query detection)"New value: +"Run a pattern too broad to run by default" - changed
Input schema / properties / glob / descriptionPrevious value: -"Include files matching glob patterns (e.g., 'src/**/*.rs') Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /."New value: +"Only paths matching (gitignore rules)" - changed
Input schema / properties / ignore_case / descriptionPrevious value: -"Match letters regardless of case, like `rg -i` (`ignore_case` + `contains` is `rg -i -F`). Default false. The trigram index is still used, so this costs about the same as a case-sensitive search."New value: +"Case-insensitive (rg -i)" - changed
Input schema / properties / include_generated / descriptionPrevious value: -"Also search generated files by name (*.pb.go, *.min.js, *.min.css, *.map, *_generated.*). Indexed but left out unless asked for; `lang: \"generated\"` selects them alone. Default false."New value: +"Also search generated files" - changed
Input schema / properties / include_locks / descriptionPrevious value: -"Also search lock files (Cargo.lock, package-lock.json, *.lock, go.sum). They are indexed but left out unless asked for; `lang: \"lock\"` selects them alone. Default false."New value: +"Also search lock files" - changed
Input schema / properties / kind / descriptionPrevious value: -"Filter by symbol kind (function, class, struct, etc.)"New value: +"Symbol kind: function, struct, class, trait, …" - changed
Input schema / properties / lang / descriptionPrevious value: -"Filter by language: rust, typescript, javascript, go, java, php, kotlin, python, c, cpp, csharp, ruby, vue, svelte, zig — or \"text\" for the plain-text tier (every other non-binary file: docs, config, templates, extensionless), \"lock\" for lock files, \"generated\" for generated files (the last two are excluded unless named or include_locks / include_generated is set)."New value: +"Language filter: rust, python, typescript, text, …" - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results per page (default: 200, max: 500). The 200-result default covers most find-all tasks in a single call. IMPORTANT: If response.has_more is true, you MUST fetch more pages using offset parameter."New value: +"Max results (default 200, at most 500)" - changed
Input schema / properties / mode / descriptionPrevious value: -"Response mode: \"list\" (default) returns full match results; \"count\" returns only {count, pattern} — faster, skips match body serialization."New value: +"count: {count, files} only" - changed
Input schema / properties / offset / descriptionPrevious value: -"Pagination offset (skip first N results). ALWAYS paginate when has_more=true. Example: First call offset=0, second call offset=100, third offset=200, etc."New value: +"Skip this many results (next page)" - changed
Input schema / properties / paths / descriptionPrevious value: -"Return only unique file paths: the response is `{status, can_trust_results, paths, total_files}` (plus `has_more` when a `limit` cut the list) instead of `{columns, rows}`. Without `limit`, every matching file is listed."New value: +"Return file paths only" - changed
Input schema / properties / pattern / descriptionPrevious value: -"Search pattern (text to find)"New value: +"Text to find" - changed
Input schema / properties / preview_length / descriptionPrevious value: -"Maximum characters per preview line (default: 180). Use a smaller value (e.g. 60) for wide-result scans where short previews are sufficient."New value: +"Preview characters (default 180)" - changed
Input schema / properties / symbols / descriptionPrevious value: -"Symbol-only search (definitions, not usage)"New value: +"Definitions only"
- Changed
search_regex14 fields changed- changed
Input schema / properties / dependencies / descriptionPrevious value: -"Include dependency information (imports) in results. Only extracts static imports."New value: +"Attach each file's imports" - changed
Input schema / properties / exclude / descriptionPrevious value: -"Exclude files matching glob patterns Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /."New value: +"Skip paths matching (gitignore rules)" - changed
Input schema / properties / file / descriptionPrevious value: -"Filter by file path"New value: +"Only paths containing this substring" - changed
Input schema / properties / force / descriptionPrevious value: -"Force execution of potentially expensive queries (bypasses broad query detection)"New value: +"Run a pattern too broad to run by default" - changed
Input schema / properties / glob / descriptionPrevious value: -"Include files matching glob patterns Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /."New value: +"Only paths matching (gitignore rules)" - changed
Input schema / properties / ignore_case / descriptionPrevious value: -"Match letters regardless of case, like `rg -i` (`ignore_case` + `contains` is `rg -i -F`). Default false. The trigram index is still used, so this costs about the same as a case-sensitive search."New value: +"Case-insensitive (rg -i)" - changed
Input schema / properties / include_generated / descriptionPrevious value: -"Also search generated files by name (*.pb.go, *.min.js, *.min.css, *.map, *_generated.*). Indexed but left out unless asked for; `lang: \"generated\"` selects them alone. Default false."New value: +"Also search generated files" - changed
Input schema / properties / include_locks / descriptionPrevious value: -"Also search lock files (Cargo.lock, package-lock.json, *.lock, go.sum). They are indexed but left out unless asked for; `lang: \"lock\"` selects them alone. Default false."New value: +"Also search lock files" - changed
Input schema / properties / lang / descriptionPrevious value: -"Filter by language: rust, typescript, javascript, go, java, php, kotlin, python, c, cpp, csharp, ruby, vue, svelte, zig — or \"text\" (docs, config and every other non-binary file), \"lock\" (lock files), \"generated\" (generated files by name)."New value: +"Language filter: rust, python, typescript, text, …" - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of results (default: 200, max: 500). Use with offset for pagination."New value: +"Max results (default 200, at most 500)" - changed
Input schema / properties / mode / descriptionPrevious value: -"Response mode: \"list\" (default) returns full match results; \"count\" returns only {count, pattern} — faster, skips match body serialization."New value: +"count: {count, files} only" - changed
Input schema / properties / offset / descriptionPrevious value: -"Pagination offset (skip first N results after sorting)"New value: +"Skip this many results (next page)" - changed
Input schema / properties / paths / descriptionPrevious value: -"Return only unique file paths: the response is `{status, can_trust_results, paths, total_files}` (plus `has_more` when a `limit` cut the list) instead of `{columns, rows}`. Without `limit`, every matching file is listed."New value: +"Return file paths only" - changed
Input schema / properties / pattern / descriptionPrevious value: -"Regex pattern"New value: +"Text to find"
6 tool updates
v2.0.1- Changed
count_occurrences7 fields changed- added
Input schema / properties / containsAdded value: +{ + "description": "Substring matching, like `grep -F`. DEFAULT IS FALSE, which matches WHOLE IDENTIFIERS ONLY: pattern \"verify_csrf\" does NOT match \"verify_csrf_form_field\", and \"jwks_rps\" does NOT match \"jwks_rps_limit\". Pass true to find a pattern anywhere inside a longer identifier. If a search returns 0, check the response `hint` — it reports how many substring matches exist.", + "type": "boolean" +} - changed
Input schema / properties / exclude / descriptionPrevious value: -"Exclude files matching patterns"New value: +"Exclude files matching patterns Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /." - changed
Input schema / properties / glob / descriptionPrevious value: -"Include files matching patterns"New value: +"Include files matching patterns Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /." - added
Input schema / properties / ignore_caseAdded value: +{ + "description": "Match letters regardless of case, like `rg -i` (`ignore_case` + `contains` is `rg -i -F`). Default false. The trigram index is still used, so this costs about the same as a case-sensitive search.", + "type": "boolean" +} - added
Input schema / properties / include_generatedAdded value: +{ + "description": "Also search generated files by name (*.pb.go, *.min.js, *.min.css, *.map, *_generated.*). Indexed but left out unless asked for; `lang: \"generated\"` selects them alone. Default false.", + "type": "boolean" +} - added
Input schema / properties / include_locksAdded value: +{ + "description": "Also search lock files (Cargo.lock, package-lock.json, *.lock, go.sum). They are indexed but left out unless asked for; `lang: \"lock\"` selects them alone. Default false.", + "type": "boolean" +} - changed
Input schema / properties / lang / descriptionPrevious value: -"Filter by language"New value: +"Filter by language: rust, typescript, javascript, go, java, php, kotlin, python, c, cpp, csharp, ruby, vue, svelte, zig — or \"text\" (docs, config and every other non-binary file), \"lock\" (lock files), \"generated\" (generated files by name)."
- Changed
find_references5 fields changed- added
Input schema / properties / containsAdded value: +{ + "description": "Substring matching, like `grep -F`. DEFAULT IS FALSE, which matches WHOLE IDENTIFIERS ONLY: pattern \"verify_csrf\" does NOT match \"verify_csrf_form_field\", and \"jwks_rps\" does NOT match \"jwks_rps_limit\". Pass true to find a pattern anywhere inside a longer identifier. If a search returns 0, check the response `hint` — it reports how many substring matches exist.", + "type": "boolean" +} - changed
Input schema / properties / exclude / descriptionPrevious value: -"Exclude files matching glob patterns (e.g., ['target/**', 'tests/**'])"New value: +"Exclude files matching glob patterns (e.g., ['target/**', 'tests/**']) Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /." - changed
Input schema / properties / glob / descriptionPrevious value: -"Include files matching glob patterns (e.g., ['src/**/*.rs'])"New value: +"Include files matching glob patterns (e.g., ['src/**/*.rs']) Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /." - added
Input schema / properties / ignore_caseAdded value: +{ + "description": "Match letters regardless of case, like `rg -i` (`ignore_case` + `contains` is `rg -i -F`). Default false. The trigram index is still used, so this costs about the same as a case-sensitive search.", + "type": "boolean" +} - changed
Input schema / properties / mode / descriptionPrevious value: -"Response mode: \"list\" (default) returns full results with definition + references; \"count\" returns only {count, pattern} — faster, skips match body serialization."New value: +"Response mode: \"list\" (default) returns full results with definition + references; \"count\" returns only {count, pattern}: every reference AFTER string/comment filtering (all pages, not one); with include_strings:true it is the raw total and equals list-mode total_references."
- Changed
list_locations7 fields changed- added
Input schema / properties / containsAdded value: +{ + "description": "Substring matching, like `grep -F`. DEFAULT IS FALSE, which matches WHOLE IDENTIFIERS ONLY: pattern \"verify_csrf\" does NOT match \"verify_csrf_form_field\", and \"jwks_rps\" does NOT match \"jwks_rps_limit\". Pass true to find a pattern anywhere inside a longer identifier. If a search returns 0, check the response `hint` — it reports how many substring matches exist.", + "type": "boolean" +} - changed
Input schema / properties / exclude / descriptionPrevious value: -"Exclude files matching patterns (e.g., ['vendor/**', 'tests/**'])"New value: +"Exclude files matching patterns (e.g., ['vendor/**', 'tests/**']) Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /." - changed
Input schema / properties / glob / descriptionPrevious value: -"Include files matching patterns (e.g., ['app/**/*.php'])"New value: +"Include files matching patterns (e.g., ['app/**/*.php']) Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /." - added
Input schema / properties / ignore_caseAdded value: +{ + "description": "Match letters regardless of case, like `rg -i` (`ignore_case` + `contains` is `rg -i -F`). Default false. The trigram index is still used, so this costs about the same as a case-sensitive search.", + "type": "boolean" +} - added
Input schema / properties / include_generatedAdded value: +{ + "description": "Also search generated files by name (*.pb.go, *.min.js, *.min.css, *.map, *_generated.*). Indexed but left out unless asked for; `lang: \"generated\"` selects them alone. Default false.", + "type": "boolean" +} - added
Input schema / properties / include_locksAdded value: +{ + "description": "Also search lock files (Cargo.lock, package-lock.json, *.lock, go.sum). They are indexed but left out unless asked for; `lang: \"lock\"` selects them alone. Default false.", + "type": "boolean" +} - changed
Input schema / properties / lang / descriptionPrevious value: -"Filter by language (php, rust, typescript, python, etc.)"New value: +"Filter by language: rust, typescript, javascript, go, java, php, kotlin, python, c, cpp, csharp, ruby, vue, svelte, zig — or \"text\" for the plain-text tier (every other non-binary file: docs, config, templates, extensionless), \"lock\" for lock files, \"generated\" for generated files (the last two are excluded unless named or include_locks / include_generated is set)."
- Changed
search_ast2 fields changed- changed
Input schema / properties / exclude / descriptionPrevious value: -"Exclude files matching glob patterns (e.g., ['target/**', 'node_modules/**'])"New value: +"Exclude files matching glob patterns (e.g., ['target/**', 'node_modules/**']) Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /." - changed
Input schema / properties / glob / descriptionPrevious value: -"Include files matching glob patterns (STRONGLY RECOMMENDED to limit scope, e.g., ['src/**/*.rs'])"New value: +"Include files matching glob patterns (STRONGLY RECOMMENDED to limit scope, e.g., ['src/**/*.rs']) Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /."
- Changed
search_code9 fields changed- added
Input schema / properties / containsAdded value: +{ + "description": "Substring matching, like `grep -F`. DEFAULT IS FALSE, which matches WHOLE IDENTIFIERS ONLY: pattern \"verify_csrf\" does NOT match \"verify_csrf_form_field\", and \"jwks_rps\" does NOT match \"jwks_rps_limit\". Pass true to find a pattern anywhere inside a longer identifier. If a search returns 0, check the response `hint` — it reports how many substring matches exist.", + "type": "boolean" +} - changed
Input schema / properties / exact / descriptionPrevious value: -"Exact match (no substring matching)"New value: +"Case-sensitive exact-identifier match. NOTE: substring matching is already OFF by default — use `contains: true` to turn it ON, not this flag." - changed
Input schema / properties / exclude / descriptionPrevious value: -"Exclude files matching glob patterns (e.g., 'target/**')"New value: +"Exclude files matching glob patterns (e.g., 'target/**') Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /." - changed
Input schema / properties / glob / descriptionPrevious value: -"Include files matching glob patterns (e.g., 'src/**/*.rs')"New value: +"Include files matching glob patterns (e.g., 'src/**/*.rs') Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /." - added
Input schema / properties / ignore_caseAdded value: +{ + "description": "Match letters regardless of case, like `rg -i` (`ignore_case` + `contains` is `rg -i -F`). Default false. The trigram index is still used, so this costs about the same as a case-sensitive search.", + "type": "boolean" +} - added
Input schema / properties / include_generatedAdded value: +{ + "description": "Also search generated files by name (*.pb.go, *.min.js, *.min.css, *.map, *_generated.*). Indexed but left out unless asked for; `lang: \"generated\"` selects them alone. Default false.", + "type": "boolean" +} - added
Input schema / properties / include_locksAdded value: +{ + "description": "Also search lock files (Cargo.lock, package-lock.json, *.lock, go.sum). They are indexed but left out unless asked for; `lang: \"lock\"` selects them alone. Default false.", + "type": "boolean" +} - changed
Input schema / properties / lang / descriptionPrevious value: -"Filter by language (rust, typescript, python, etc.)"New value: +"Filter by language: rust, typescript, javascript, go, java, php, kotlin, python, c, cpp, csharp, ruby, vue, svelte, zig — or \"text\" for the plain-text tier (every other non-binary file: docs, config, templates, extensionless), \"lock\" for lock files, \"generated\" for generated files (the last two are excluded unless named or include_locks / include_generated is set)." - changed
Input schema / properties / paths / descriptionPrevious value: -"Return only unique file paths (not full results)"New value: +"Return only unique file paths: the response is `{status, can_trust_results, paths, total_files}` (plus `has_more` when a `limit` cut the list) instead of `{columns, rows}`. Without `limit`, every matching file is listed."
- Changed
search_regex7 fields changed- changed
Input schema / properties / exclude / descriptionPrevious value: -"Exclude files matching glob patterns"New value: +"Exclude files matching glob patterns Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /." - changed
Input schema / properties / glob / descriptionPrevious value: -"Include files matching glob patterns"New value: +"Include files matching glob patterns Patterns follow gitignore rules: a pattern containing '/' (src/**/*.rs) is anchored at the index root; a bare name (*.rs, Makefile) matches at any depth; **/src/**/*.rs matches src/ anywhere; * does not cross /." - added
Input schema / properties / ignore_caseAdded value: +{ + "description": "Match letters regardless of case, like `rg -i` (`ignore_case` + `contains` is `rg -i -F`). Default false. The trigram index is still used, so this costs about the same as a case-sensitive search.", + "type": "boolean" +} - added
Input schema / properties / include_generatedAdded value: +{ + "description": "Also search generated files by name (*.pb.go, *.min.js, *.min.css, *.map, *_generated.*). Indexed but left out unless asked for; `lang: \"generated\"` selects them alone. Default false.", + "type": "boolean" +} - added
Input schema / properties / include_locksAdded value: +{ + "description": "Also search lock files (Cargo.lock, package-lock.json, *.lock, go.sum). They are indexed but left out unless asked for; `lang: \"lock\"` selects them alone. Default false.", + "type": "boolean" +} - changed
Input schema / properties / lang / descriptionPrevious value: -"Filter by language"New value: +"Filter by language: rust, typescript, javascript, go, java, php, kotlin, python, c, cpp, csharp, ruby, vue, svelte, zig — or \"text\" (docs, config and every other non-binary file), \"lock\" (lock files), \"generated\" (generated files by name)." - changed
Input schema / properties / paths / descriptionPrevious value: -"Return only unique file paths"New value: +"Return only unique file paths: the response is `{status, can_trust_results, paths, total_files}` (plus `has_more` when a `limit` cut the list) instead of `{columns, rows}`. Without `limit`, every matching file is listed."
3 tool updates
v1.6.0- Changed
find_references3 fields changed- added
Input schema / properties / include_stringsAdded value: +{ + "description": "Include matches inside string literals and comments (default: false). By default these are excluded to focus on real call sites.", + "type": "boolean" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Max references per page (default: 100). Pagination applies to references only."New value: +"Max references per page (default: 200, max: 500). The 200-result default covers most find-all tasks in a single call. Pagination applies to references only." - added
Input schema / properties / modeAdded value: +{ + "description": "Response mode: \"list\" (default) returns full results with definition + references; \"count\" returns only {count, pattern} — faster, skips match body serialization.", + "enum": [ + "list", + "count" + ], + "type": "string" +}
- Changed
search_code2 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results per page (default: 100). IMPORTANT: If response.pagination.has_more is true, you MUST fetch more pages using offset parameter."New value: +"Maximum results per page (default: 200, max: 500). The 200-result default covers most find-all tasks in a single call. IMPORTANT: If response.has_more is true, you MUST fetch more pages using offset parameter." - added
Input schema / properties / modeAdded value: +{ + "description": "Response mode: \"list\" (default) returns full match results; \"count\" returns only {count, pattern} — faster, skips match body serialization.", + "enum": [ + "list", + "count" + ], + "type": "string" +}
- Changed
search_regex2 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum number of results (use with offset for pagination)"New value: +"Maximum number of results (default: 200, max: 500). Use with offset for pagination." - added
Input schema / properties / modeAdded value: +{ + "description": "Response mode: \"list\" (default) returns full match results; \"count\" returns only {count, pattern} — faster, skips match body serialization.", + "enum": [ + "list", + "count" + ], + "type": "string" +}
17 tool updates
v1.0.0- First observed
analyze_summary - First observed
check_index_status - First observed
count_occurrences - First observed
find_circular - First observed
find_hotspots - First observed
find_islands - First observed
find_references - First observed
find_unused - First observed
gather_context - First observed
get_dependencies - First observed
get_dependents - First observed
get_transitive_deps - First observed
index_project - First observed
list_locations - First observed
search_ast - First observed
search_code - First observed
search_regex
TDQS
Scored across 10 tools
Most tools target distinct capabilities, but the five search-related tools (search_code, search_regex, list_locations, search_ast, find_references) overlap in purpose. The descriptions clarify boundaries—list_locations is the cheapest path/line search, search_ast is structural, find_references combines definition and usages—but an agent still must read carefully to choose correctly.
Tool names follow a mostly consistent verb_noun snake_case pattern: search_code, get_dependencies, list_locations, find_references, gather_context, index_project, check_index_status. The bare verb 'analyze' is a minor deviation from the pattern, but overall naming is predictable and readable.
Ten tools is well-scoped for a code intelligence server, covering search, dependencies, references, import analysis, project overview, and index management. Each tool has a clear role, and the index-management tools are lightweight and rarely needed but justified for reliability.
The surface covers core code-intelligence workflows: literal/regex/structural search, dependency lookup, reference finding, import-graph analysis, and project overview. However, there is no direct file-content read or symbol-listing tool, which are minor gaps that agents can partially work around using search previews and gather_context.
Maintenance
Related MCP Connectors
Code intelligence for coding agents: semantic, AST, graph, and full-text search. 279+ languages.
Search indexed code, trace dependencies, assess change impact, and recall repository memory.
Ask a codebase what calls what: search, blast radius, paths between symbols, and diffs.
Search independent software the big engines bury: indie apps, open-source repos, and dev tools.
Related MCP Servers
- AlicenseAqualityFmaintenanceProvides intelligent semantic code search using local AI embeddings, enabling natural language queries to find relevant code by meaning rather than exact keywords. Indexes codebases in the background with smart project detection and privacy-first local processing.631 npm200MIT
- AlicenseNot gradedqualityCmaintenanceFast semantic code search for AI agents — find symbols, references, and callers across any codebase.9Apache 2.0
- AlicenseAqualityCmaintenanceExtremely fast local hybrid code search for agents.152MIT
- AlicenseNot gradedqualityCmaintenanceProvides IDE-like code navigation and search for local repositories, enabling AI assistants to perform symbol search, trigram indexing, and semantic navigation.AGPL 3.0