Skip to main content
Glama
reflex-search

Reflex

Official

search_code

Find literal patterns in code and retrieve every match with file path, line number, and preview snippet. Supports whole identifiers, substrings, and definitions.

Instructions

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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
fileNoOnly paths containing this substring
globNoOnly paths matching (gitignore rules)
kindNoSymbol kind: function, struct, class, trait, …
langNoLanguage filter: rust, python, typescript, text, …
modeNocount: {count, files} only
exactNoExact symbol name
forceNoRun a pattern too broad to run by default
limitNoMax results (default 200, at most 500)
pathsNoReturn file paths only
expandNoWhole symbol body
offsetNoSkip this many results (next page)
excludeNoSkip paths matching (gitignore rules)
patternYesText to find
symbolsNoDefinitions only
containsNoSubstring match (grep -F) instead of whole identifiers
ignore_caseNoCase-insensitive (rg -i)
dependenciesNoAttach each file's imports
include_locksNoAlso search lock files
preview_lengthNoPreview characters (default 180)
include_generatedNoAlso search generated files

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed20 schema fields changedv2.0.3
    • changedInput schema / properties / contains / description
      Previous 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"
    • changedInput schema / properties / dependencies / description
      Previous 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"
    • changedInput schema / properties / exact / description
      Previous 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"
    • changedInput schema / properties / exclude / description
      Previous 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)"
    • changedInput schema / properties / expand / description
      Previous value: -"Show full symbol body (not just signature)"New value: +"Whole symbol body"
    • changedInput schema / properties / file / description
      Previous value: -"Filter by file path (substring)"New value: +"Only paths containing this substring"
    • changedInput schema / properties / force / description
      Previous value: -"Force execution of potentially expensive queries (bypasses broad query detection)"New value: +"Run a pattern too broad to run by default"
    • changedInput schema / properties / glob / description
      Previous 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)"
    • changedInput schema / properties / ignore_case / description
      Previous 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)"
    • changedInput schema / properties / include_generated / description
      Previous 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"
    • changedInput schema / properties / include_locks / description
      Previous 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"
    • changedInput schema / properties / kind / description
      Previous value: -"Filter by symbol kind (function, class, struct, etc.)"New value: +"Symbol kind: function, struct, class, trait, …"
    • changedInput schema / properties / lang / description
      Previous 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, …"
    • changedInput schema / properties / limit / description
      Previous 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)"
    • changedInput schema / properties / mode / description
      Previous 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"
    • changedInput schema / properties / offset / description
      Previous 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)"
    • changedInput schema / properties / paths / description
      Previous 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"
    • changedInput schema / properties / pattern / description
      Previous value: -"Search pattern (text to find)"New value: +"Text to find"
    • changedInput schema / properties / preview_length / description
      Previous 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)"
    • changedInput schema / properties / symbols / description
      Previous value: -"Symbol-only search (definitions, not usage)"New value: +"Definitions only"
  2. Changed9 schema fields changedv2.0.1
    • addedInput schema / properties / contains
      Added 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"
      +}
    • changedInput schema / properties / exact / description
      Previous 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."
    • changedInput schema / properties / exclude / description
      Previous 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 /."
    • changedInput schema / properties / glob / description
      Previous 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 /."
    • addedInput schema / properties / ignore_case
      Added 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"
      +}
    • addedInput schema / properties / include_generated
      Added 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"
      +}
    • addedInput schema / properties / include_locks
      Added 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"
      +}
    • changedInput schema / properties / lang / description
      Previous 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)."
    • changedInput schema / properties / paths / description
      Previous 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."
  3. Changed2 schema fields changedv1.6.0
    • changedInput schema / properties / limit / description
      Previous 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."
    • addedInput schema / properties / mode
      Added 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"
      +}
  4. First observedv1.0.0

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.