Skip to main content
Glama
semantic-code-mcp
by vrppaul

search_code

Find functions, classes, methods and document sections by the words their code uses; indexes Python, Rust and Markdown projects and returns the best matches first.

Instructions

Find the functions, classes, methods and document sections of a project by the words their code uses.

It matches the words of code: write the identifiers and terms the code would use, and on a miss search again with others. A query that is a name, or a qualified one, brings the chunks of that name first:

  • "retry backoff delay attempts"

  • "parse_args config options"

  • "Stack.push"

For every place a name is used, Grep: this returns only the best matches.

Indexes Python, Rust and Markdown files. Automatically indexes the project if not already indexed, and re-indexes any files that have changed since the last search.

Args: query: The words to find, as code would write them, or a name. project_path: Absolute path to the project, or to a directory inside its git repository, which keeps the search to that directory; left out, the client's workspace root, which must lie in a git repository. limit: Maximum number of results to return. chunk_kinds: Only chunks of these kinds. languages: Only chunks of files in these languages. path_glob: Only files this glob names, read from the directory searched. exclude_glob: No file this glob names, read as path_glob is. include_debug: Also return timings and counts of the search.

Returns: The root of the project whose index answered and the directory the search kept to; then matching chunks, best first, with the file's absolute path, line range, name, kind (module, function, method, class, section), the class, impl, module or heading it belongs to, and content.

Input Schema

NameRequiredDescriptionDefault
limitNo
queryYes
languagesNoOnly chunks of files in these languages.
path_globNoOnly files this glob names, as in a .gitignore: without a slash a name at any depth below the directory project_path names (`*.rs`, and `tests/`, as a trailing slash does not count), with one before a name a path from that directory (`src/**/*.py`, `/tests`); `*` stays within a directory, `**` crosses any number, even inside a name (`src**.py`, where a .gitignore reads it as `*`), `?` is one character, and a directory takes what it holds. No character classes (`[ab]`), braces, escapes, a leading `!`, `..` or more than 1000 characters: each is refused with the reason.
chunk_kindsNoOnly chunks of these kinds; Rust's structs, enums, traits and impls are classes.
exclude_globNoNo file this glob names, read as path_glob is (`tests`, `*_test.py`).
project_pathNoAbsolute path to the project, or to a directory inside its git repository. Left out, the client's workspace root: the directory Claude Code was started in, which must lie in a git repository.
include_debugNo

Output Schema

NameRequiredDescriptionDefault
debugYes
resultsYes
project_rootYesThe root of the project whose index answered: as project_path, it searches the whole repository.
searched_directoryYesThe directory the search kept to: project_root, or a directory under it; the search did not look outside it.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed35 schema fields changedv0.5.0
    • addedInput schema / $defs
      Added value: +{
      +  "ChunkKind": {
      +    "description": "What a chunk is. Rust's structs, enums, traits and impls are classes.",
      +    "enum": [
      +      "module",
      +      "function",
      +      "class",
      +      "method",
      +      "section"
      +    ],
      +    "title": "ChunkKind",
      +    "type": "string"
      +  },
      +  "Language": {
      +    "description": "A language the chunkers read.",
      +    "enum": [
      +      "python",
      +      "rust",
      +      "markdown"
      +    ],
      +    "title": "Language",
      +    "type": "string"
      +  }
      +}
    • addedInput schema / properties / chunk_kinds
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "$ref": "#/$defs/ChunkKind"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Only chunks of these kinds; Rust's structs, enums, traits and impls are classes.",
      +  "title": "Chunk Kinds"
      +}
    • addedInput schema / properties / exclude_glob
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "No file this glob names, read as path_glob is (`tests`, `*_test.py`).",
      +  "title": "Exclude Glob"
      +}
    • addedInput schema / properties / include_debug
      Added value: +{
      +  "default": false,
      +  "title": "Include Debug",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / languages
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "$ref": "#/$defs/Language"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Only chunks of files in these languages.",
      +  "title": "Languages"
      +}
    • addedInput schema / properties / limit / maximum
      Added value: +50
    • addedInput schema / properties / limit / minimum
      Added value: +1
    • addedInput schema / properties / path_glob
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Only files this glob names, as in a .gitignore: without a slash a name at any depth below the directory project_path names (`*.rs`, and `tests/`, as a trailing slash does not count), with one before a name a path from that directory (`src/**/*.py`, `/tests`); `*` stays within a directory, `**` crosses any number, even inside a name (`src**.py`, where a .gitignore reads it as `*`), `?` is one character, and a directory takes what it holds. No character classes (`[ab]`), braces, escapes, a leading `!`, `..` or more than 1000 characters: each is refused with the reason.",
      +  "title": "Path Glob"
      +}
    • addedInput schema / properties / project_path / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / project_path / default
      Added value: +null
    • addedInput schema / properties / project_path / description
      Added value: +"Absolute path to the project, or to a directory inside its git repository. Left out, the client's workspace root: the directory Claude Code was started in, which must lie in a git repository."
    • removedInput schema / properties / project_path / type
      Removed value: -"string"
    • changedInput schema / required
      Previous value: -[
      -  "query",
      -  "project_path"
      -]New value: +[
      +  "query"
      +]
    • addedOutput schema / $defs / ChunkKind
      Added value: +{
      +  "description": "What a chunk is. Rust's structs, enums, traits and impls are classes.",
      +  "enum": [
      +    "module",
      +    "function",
      +    "class",
      +    "method",
      +    "section"
      +  ],
      +  "title": "ChunkKind",
      +  "type": "string"
      +}
    • removedOutput schema / $defs / ErrorResponse
      Removed value: -{
      -  "description": "Error response for tool failures.",
      -  "properties": {
      -    "error": {
      -      "title": "Error",
      -      "type": "string"
      -    }
      -  },
      -  "required": [
      -    "error"
      -  ],
      -  "title": "ErrorResponse",
      -  "type": "object"
      -}
    • removedOutput schema / $defs / FormattedSearchResult
      Removed value: -{
      -  "description": "A search result formatted for response.",
      -  "properties": {
      -    "chunk_type": {
      -      "title": "Chunk Type",
      -      "type": "string"
      -    },
      -    "content": {
      -      "title": "Content",
      -      "type": "string"
      -    },
      -    "file_path": {
      -      "title": "File Path",
      -      "type": "string"
      -    },
      -    "line_end": {
      -      "title": "Line End",
      -      "type": "integer"
      -    },
      -    "line_start": {
      -      "title": "Line Start",
      -      "type": "integer"
      -    },
      -    "name": {
      -      "title": "Name",
      -      "type": "string"
      -    },
      -    "score": {
      -      "title": "Score",
      -      "type": "number"
      -    },
      -    "truncated": {
      -      "default": false,
      -      "title": "Truncated",
      -      "type": "boolean"
      -    }
      -  },
      -  "required": [
      -    "file_path",
      -    "line_start",
      -    "line_end",
      -    "name",
      -    "chunk_type",
      -    "content",
      -    "score"
      -  ],
      -  "title": "FormattedSearchResult",
      -  "type": "object"
      -}
    • removedOutput schema / $defs / IndexResultSummary
      Removed value: -{
      -  "description": "Summary of indexing result for search debug info.",
      -  "properties": {
      -    "chunks_indexed": {
      -      "title": "Chunks Indexed",
      -      "type": "integer"
      -    },
      -    "files_indexed": {
      -      "title": "Files Indexed",
      -      "type": "integer"
      -    }
      -  },
      -  "required": [
      -    "files_indexed",
      -    "chunks_indexed"
      -  ],
      -  "title": "IndexResultSummary",
      -  "type": "object"
      -}
    • removedOutput schema / $defs / IndexStatusSummary
      Removed value: -{
      -  "description": "Summary of index status for search debug info.",
      -  "properties": {
      -    "chunks_count": {
      -      "title": "Chunks Count",
      -      "type": "integer"
      -    },
      -    "files_count": {
      -      "title": "Files Count",
      -      "type": "integer"
      -    },
      -    "was_stale": {
      -      "anyOf": [
      -        {
      -          "type": "boolean"
      -        },
      -        {
      -          "type": "null"
      -        }
      -      ],
      -      "default": null,
      -      "title": "Was Stale"
      -    }
      -  },
      -  "required": [
      -    "files_count",
      -    "chunks_count"
      -  ],
      -  "title": "IndexStatusSummary",
      -  "type": "object"
      -}
    • addedOutput schema / $defs / IndexingSummaryView
      Added value: +{
      +  "description": "What the search indexed before it searched.",
      +  "properties": {
      +    "chunks_indexed": {
      +      "title": "Chunks Indexed",
      +      "type": "integer"
      +    },
      +    "files_indexed": {
      +      "title": "Files Indexed",
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "files_indexed",
      +    "chunks_indexed"
      +  ],
      +  "title": "IndexingSummaryView",
      +  "type": "object"
      +}
    • removedOutput schema / $defs / SearchDebugInfo
      Removed value: -{
      -  "description": "Debug information included in search response.",
      -  "properties": {
      -    "index_result": {
      -      "$ref": "#/$defs/IndexResultSummary"
      -    },
      -    "index_status": {
      -      "$ref": "#/$defs/IndexStatusSummary"
      -    },
      -    "stats": {
      -      "$ref": "#/$defs/SearchStats"
      -    },
      -    "timings": {
      -      "$ref": "#/$defs/SearchTimings"
      -    }
      -  },
      -  "required": [
      -    "timings",
      -    "stats",
      -    "index_status",
      -    "index_result"
      -  ],
      -  "title": "SearchDebugInfo",
      -  "type": "object"
      -}
    • addedOutput schema / $defs / SearchDebugView
      Added value: +{
      +  "description": "Timings and counts of a search, sent only when asked for.",
      +  "properties": {
      +    "indexing": {
      +      "anyOf": [
      +        {
      +          "$ref": "#/$defs/IndexingSummaryView"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "stats": {
      +      "$ref": "#/$defs/SearchStatsView"
      +    },
      +    "timings": {
      +      "$ref": "#/$defs/SearchTimingsView"
      +    }
      +  },
      +  "required": [
      +    "timings",
      +    "stats",
      +    "indexing"
      +  ],
      +  "title": "SearchDebugView",
      +  "type": "object"
      +}
    • removedOutput schema / $defs / SearchResponse
      Removed value: -{
      -  "description": "Complete search response with results and debug info.",
      -  "properties": {
      -    "debug": {
      -      "$ref": "#/$defs/SearchDebugInfo"
      -    },
      -    "results": {
      -      "items": {
      -        "$ref": "#/$defs/FormattedSearchResult"
      -      },
      -      "title": "Results",
      -      "type": "array"
      -    }
      -  },
      -  "required": [
      -    "results",
      -    "debug"
      -  ],
      -  "title": "SearchResponse",
      -  "type": "object"
      -}
    • addedOutput schema / $defs / SearchResultView
      Added value: +{
      +  "description": "One hit as the agent sees it; `content` is cut to a line limit, `truncated` says so.",
      +  "properties": {
      +    "content": {
      +      "title": "Content",
      +      "type": "string"
      +    },
      +    "file_path": {
      +      "title": "File Path",
      +      "type": "string"
      +    },
      +    "kind": {
      +      "$ref": "#/$defs/ChunkKind"
      +    },
      +    "line_end": {
      +      "title": "Line End",
      +      "type": "integer"
      +    },
      +    "line_start": {
      +      "title": "Line Start",
      +      "type": "integer"
      +    },
      +    "name": {
      +      "title": "Name",
      +      "type": "string"
      +    },
      +    "parent": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "title": "Parent"
      +    },
      +    "truncated": {
      +      "title": "Truncated",
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "file_path",
      +    "line_start",
      +    "line_end",
      +    "name",
      +    "kind",
      +    "parent",
      +    "content",
      +    "truncated"
      +  ],
      +  "title": "SearchResultView",
      +  "type": "object"
      +}
    • removedOutput schema / $defs / SearchStats
      Removed value: -{
      -  "description": "Statistics about search results.",
      -  "properties": {
      -    "filtered_out": {
      -      "title": "Filtered Out",
      -      "type": "integer"
      -    },
      -    "results_count": {
      -      "title": "Results Count",
      -      "type": "integer"
      -    },
      -    "tokens_estimate": {
      -      "title": "Tokens Estimate",
      -      "type": "integer"
      -    },
      -    "unique_files": {
      -      "title": "Unique Files",
      -      "type": "integer"
      -    }
      -  },
      -  "required": [
      -    "results_count",
      -    "filtered_out",
      -    "unique_files",
      -    "tokens_estimate"
      -  ],
      -  "title": "SearchStats",
      -  "type": "object"
      -}
    • addedOutput schema / $defs / SearchStatsView
      Added value: +{
      +  "description": "What a search kept and dropped.",
      +  "properties": {
      +    "filtered_out": {
      +      "title": "Filtered Out",
      +      "type": "integer"
      +    },
      +    "results_count": {
      +      "title": "Results Count",
      +      "type": "integer"
      +    },
      +    "tokens_estimate": {
      +      "title": "Tokens Estimate",
      +      "type": "integer"
      +    },
      +    "unique_files": {
      +      "title": "Unique Files",
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "results_count",
      +    "filtered_out",
      +    "unique_files",
      +    "tokens_estimate"
      +  ],
      +  "title": "SearchStatsView",
      +  "type": "object"
      +}
    • removedOutput schema / $defs / SearchTimings
      Removed value: -{
      -  "description": "Timing breakdown for search operation.",
      -  "properties": {
      -    "embedding_ms": {
      -      "title": "Embedding Ms",
      -      "type": "number"
      -    },
      -    "indexing_ms": {
      -      "anyOf": [
      -        {
      -          "type": "number"
      -        },
      -        {
      -          "type": "null"
      -        }
      -      ],
      -      "default": null,
      -      "title": "Indexing Ms"
      -    },
      -    "search_ms": {
      -      "title": "Search Ms",
      -      "type": "number"
      -    },
      -    "total_ms": {
      -      "title": "Total Ms",
      -      "type": "number"
      -    }
      -  },
      -  "required": [
      -    "embedding_ms",
      -    "search_ms",
      -    "total_ms"
      -  ],
      -  "title": "SearchTimings",
      -  "type": "object"
      -}
    • addedOutput schema / $defs / SearchTimingsView
      Added value: +{
      +  "description": "Where the time of a search went, in milliseconds.",
      +  "properties": {
      +    "embedding_ms": {
      +      "title": "Embedding Ms",
      +      "type": "number"
      +    },
      +    "indexing_ms": {
      +      "anyOf": [
      +        {
      +          "type": "number"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ],
      +      "title": "Indexing Ms"
      +    },
      +    "search_ms": {
      +      "title": "Search Ms",
      +      "type": "number"
      +    },
      +    "total_ms": {
      +      "title": "Total Ms",
      +      "type": "number"
      +    }
      +  },
      +  "required": [
      +    "embedding_ms",
      +    "search_ms",
      +    "total_ms",
      +    "indexing_ms"
      +  ],
      +  "title": "SearchTimingsView",
      +  "type": "object"
      +}
    • addedOutput schema / description
      Added value: +"The answer of `search_code`."
    • addedOutput schema / properties / debug
      Added value: +{
      +  "anyOf": [
      +    {
      +      "$ref": "#/$defs/SearchDebugView"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / project_root
      Added value: +{
      +  "description": "The root of the project whose index answered: as project_path, it searches the whole repository.",
      +  "title": "Project Root",
      +  "type": "string"
      +}
    • removedOutput schema / properties / result
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "$ref": "#/$defs/SearchResponse"
      -    },
      -    {
      -      "$ref": "#/$defs/ErrorResponse"
      -    }
      -  ],
      -  "title": "Result"
      -}
    • addedOutput schema / properties / results
      Added value: +{
      +  "items": {
      +    "$ref": "#/$defs/SearchResultView"
      +  },
      +  "title": "Results",
      +  "type": "array"
      +}
    • addedOutput schema / properties / searched_directory
      Added value: +{
      +  "description": "The directory the search kept to: project_root, or a directory under it; the search did not look outside it.",
      +  "title": "Searched Directory",
      +  "type": "string"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "result"
      -]New value: +[
      +  "project_root",
      +  "searched_directory",
      +  "results",
      +  "debug"
      +]
    • changedOutput schema / title
      Previous value: -"search_codeOutput"New value: +"SearchCodeResponse"
  2. First observedv0.1.0

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the side effect of automatically indexing the project and re-indexing changed files, the language coverage (Python, Rust, Markdown), that only best matches are returned, and that invalid globs are refused with a reason. It does not cover permissions, cost/latency, or behavior when no results are found, so it stops short of fully transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded and conventionally structured with Args/Returns sections, but the Args block duplicates schema text nearly verbatim for several parameters, and phrasing like 'For every place a name is used, Grep: this returns only the best matches' is awkward and costs a read. The examples earn their place; the restated parameter lines mostly do not.

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 an eight-parameter tool with no annotations, the definition covers the essentials: what is indexed, when indexing happens, how scoping works, and what a result contains (path, line range, name, kind, owner, content), which the output schema also backs up. Missing only edge-case behavior such as empty result sets or failure modes, which are minor given the output schema's presence.

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?

At 63% schema coverage, the Args block touches all eight parameters and adds real meaning for the two most important ones: query (write identifiers as the code would, with examples) and project_path (a directory inside the repo narrows the search). The remaining entries (limit, chunk_kinds, languages, include_debug) largely restate the schema descriptions, so the added value is concentrated rather than uniform.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with unusual precision: 'Find the functions, classes, methods and document sections of a project by the words their code uses.' It also carves out a boundary against plain text search ('For every place a name is used, Grep: this returns only the best matches'), so the agent can tell it apart from a generic grep without opening the schema. The sibling tools index_codebase/index_status are only addressed indirectly via the auto-indexing sentence.

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 concrete usage guidance: write the identifiers the code would use, and 'on a miss search again with others', plus three worked query examples. It names the alternative (Grep) and the condition that selects it. There is no explicit statement of when this tool should be avoided in favor of index_codebase or index_status, but the context is otherwise clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools