Skip to main content
Glama

search_bodies

Find patterns in compiled C/C++ definition bodies—calls, declarations, members—and get matching symbols with exact line numbers for citation.

Instructions

Find patterns in the TEXT OF A DEFINITION — the code inside its extent.

Searches ifdef-filtered text — only the code that compiles for the current build. A line of an inactive #if branch holds nothing, thus a pattern that lives only in a dead branch gives no result here. That empty answer is the correct one: the code does not compile.

Searches the stored text of every definition (is_definition=1), and a definition is not only a callable. Measured on one project of 60,877 symbols, the text covers:

  • Callables — function, method, constructor, destructor. Call patterns (.attach(, .rise(, callback(&), ISR registration, one case label of a long switch.

  • Types — class, struct, union, enum, namespace. An enum constant, a bit field, a member declaration such as InterruptIn _pin; — all inside the body of the type that holds them.

  • Definitions of data — varglobal, varlocal, typedef. A table with a multi-line initializer is found by its content.

A match on a type reports the type as the result, thus a query for one enum constant answers with the enum, and match_lines gives the line of the constant itself.

Only the text matches. The query is bound to the stored body: a hit in the NAME, the signature, the docstring or the llm_analysis of a symbol is not a hit here. Measured on one project, sensor used to give 36 results of which 22 matched only through a summary that a model wrote — untrusted text that cannot be cited, and a _match_snippet with no match in it. Use search_code to reach a name or a concept. A column filter you write yourself (summary : sensor) overrides the binding.

When to use search_bodies and when search_code:

  • search_bodies — patterns in the code (what the code DOES or DECLARES): self test, attach, SELF_TEST.

  • search_code — symbols by NAME (what the code IS): modem init, interrupt handler.

The query goes to FTS5 as you wrote it. This tool alone adds no wildcard, and that is what keeps a pattern precise:

  • A space is an AND of two exact tokens, NOT an OR. CommandType NUM answers with the definitions that hold both.

  • No prefix is implied. SELF_TEST matches the tokens self test and misses Self tester; write SELF_TEST* to reach the second. Measured on one project, the wildcard added the one caller that the bare query missed.

  • Punctuation is not searchable. FTS5 cannot parse .attach( at all, thus the query is repaired into the phrase ".attach(" — and the tokenizer inside a phrase drops the punctuation too, so what runs is the word attach. Such a result carries _fallback: "sanitized" and _query_used. The hits whose body really holds .attach( are the ones with match_lines.

  • search_code and search_content behave the OTHER way: each of their terms gets a trailing * and the terms are OR-joined.

Limitation — the extent of a definition is the boundary. Text that belongs to no definition is out of reach:

  • #include, #define, #ifdef — preprocessor directives. search_code covers a macro name and value. search_content covers the directive as text.

  • extern "C" — a linkage specifier is no symbol.

  • A comment or a declaration at file scope, outside every definition.

For those, use search_content, which indexes the full file text.

Set project_only=True for a question about YOUR code ("where do we register interrupt handlers?"). Leave it False (default) when the vendor SDK code — the framework or OS code that your team did not write — is also relevant.

Results include _match_snippet — a highlighted excerpt that shows each match in context (e.g. _timeout.<b>attach</b>(callback(...))) — and match_lines, the line numbers of the matches inside the definition. line is where the definition starts, which for a large function is far from the match. Cite from match_lines instead. Project code sorts before vendor code in the output.

Read-only: yes. Requires the FTS5 index. May auto-reindex stale files (non-blocking) — see search_code.

Args: query: FTS5 search terms, 1-3 words. A bare multi-word query is an AND of exact tokens, and no wildcard is added — see the query rules above. A single word is the broadest form: 'attach' reaches every .attach(...) pattern. Add * for a prefix ('attach*'), and double quotes for a phrase ('"attach callback"'). project_root: Project root. Auto-detected if omitted. project: Project name or project_id — call list_projects to get them. Use it to ask about a project that is not the project of the current directory. It is an alternative to project_root, which takes a root path. Give one of the two, not both. kind: Optional filter to return only symbols of this kind. limit: Maximum results of one page (default 20, max 100). offset: Skip this many results. Reads the next page of a pattern with many hits; the page notice names the offset to use. project_only: When True, exclude vendor SDK directories and return only application code. Default False. variant: Build variant (multi-build project). Omit to use default_variant. One query answers for ONE build. image: Sysbuild image within the variant. Required when the variant holds several: each image is a separate program.

Returns: list of dicts. The page notice leads the answer — total, offset, shown, more — and each that follows holds: name, qualified_name, kind, file, line (first line of the definition), is_definition, signature, _match_snippet (excerpt around the match), source (the text of the definition).

Also, when they carry an answer:

* ``match_lines`` (list[int]) — absolute line numbers of the
  matches, up to 20.  Computed from the full text, thus a match
  after the cut below still has a number.  Use these to cite
  ``file:line``, and not the ``line`` of the definition.  The name
  carries no leading underscore for a reason: a field the caller
  must cite is an answer, while ``_``-prefixed fields
  (``_match_snippet``, ``_fallback``, ``_source_truncated``) tell
  where the answer came from.
* ``_source_truncated`` (True) — ``source`` is cut.  A callable
  keeps 2000 characters, any other kind 500, because the body of a
  type is mostly members that the match has nothing to do with.
  ``get_source`` gives the whole text.
* ``_fallback`` (``"sanitized"``) with ``_query_used`` — FTS5 could
  not parse the query as written, thus a repaired one ran.  The
  repair drops punctuation, so the answer is wider than the text
  that was asked for.  Every query FTS5 accepts runs untouched and
  carries neither field.

``source`` here is bare text with no line-number prefix.  Only
``get_source`` numbers its lines.

No match gives ``[]``.  A dict with ``error`` means the query
failed.  A stale index prepends a dict with ``warning`` + ``hint``,
and so does a query that FTS5 refuses to parse — an empty list
always means "no such code", never "bad query".

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
kindNoOptional kind filter: function, method, class, etc.
imageNoSysbuild image within the variant. Required when the variant holds several: each image is a separate program.
limitNoMaximum results of one page (default 20, max 100).
queryYesFTS5 search terms for the body of a definition. 1-3 words. E.g. 'attach', 'callback', 'rise'.
offsetNoSkip this many results. Reads the next page of a pattern with many hits.
projectNoProject name or project_id — call list_projects to get them. Use it to ask about a project that is not the project of the current directory. It is an alternative to project_root, which takes a root path. Give one of the two, not both.
variantNoBuild variant (multi-build project). Omit to use default_variant. One query answers for ONE build.
project_onlyNoExclude vendor SDK code. When True, only application code. Default False.
project_rootNoProject root. Auto-detected if omitted. This field also accepts a project name or a project_id, but project is the clear field for those.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv0.32.0
    • changedInput schema / properties / image / description
      Previous value: -"Sysbuild image name within the variant (multi-project). Omit for all images of the variant."New value: +"Sysbuild image within the variant. Required when the variant holds several: each image is a separate program."
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum results (default 20, max 100)."New value: +"Maximum results of one page (default 20, max 100)."
    • addedInput schema / properties / limit / minimum
      Added value: +1
    • addedInput schema / properties / offset
      Added value: +{
      +  "default": 0,
      +  "description": "Skip this many results. Reads the next page of a pattern with many hits.",
      +  "minimum": 0,
      +  "title": "Offset",
      +  "type": "integer"
      +}
    • addedInput schema / properties / query / minLength
      Added value: +1
    • changedInput schema / properties / variant / description
      Previous value: -"Build variant name (multi-project). Omit to use default_variant or fail-closed. Use '*' for all variants."New value: +"Build variant (multi-build project). Omit to use default_variant. One query answers for ONE build."
  2. Changed4 schema fields changedv0.30.0
    • addedInput schema / additionalProperties
      Added value: +false
    • addedInput schema / properties / project
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Project name or project_id — call list_projects to get them. Use it to ask about a project that is not the project of the current directory. It is an alternative to project_root, which takes a root path. Give one of the two, not both.",
      +  "title": "Project"
      +}
    • changedInput schema / properties / project_root / description
      Previous value: -"Project root. Auto-detected if omitted."New value: +"Project root. Auto-detected if omitted. This field also accepts a project name or a project_id, but project is the clear field for those."
    • changedInput schema / properties / query / description
      Previous value: -"FTS5 search terms for function bodies. 1-3 words. E.g. 'attach', 'callback', 'rise'."New value: +"FTS5 search terms for the body of a definition. 1-3 words. E.g. 'attach', 'callback', 'rise'."
  3. Changed2 schema fields changedv0.25.3
    • addedInput schema / properties / image
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Sysbuild image name within the variant (multi-project). Omit for all images of the variant.",
      +  "title": "Image"
      +}
    • addedInput schema / properties / variant
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Build variant name (multi-project). Omit to use default_variant or fail-closed. Use '*' for all variants.",
      +  "title": "Variant"
      +}
  4. Changed2 schema fields changedv0.18.2
    • changedInput schema / properties / project_only / description
      Previous value: -"Exclude vendor SDK code (mbed-os/, .pio/, zephyr/, build/). When True, only your application code (src/, lib/). Default False."New value: +"Exclude vendor SDK code. When True, only application code. Default False."
    • changedInput schema / properties / query / description
      Previous value: -"FTS5 search terms for function bodies. 1-3 words. E.g. 'attach', 'NVIC_SetVector', 'rise'."New value: +"FTS5 search terms for function bodies. 1-3 words. E.g. 'attach', 'callback', 'rise'."
  5. Addedv0.13.1

TDQS

A4.8/5.0
Behavior5/5

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

No annotations exist, so the full burden falls on the description — and it delivers richly: explicit read-only declaration, ifdef-filtering semantics, FTS5 tokenizer behavior (AND not OR, no implied prefix, punctuation dropping), fallback sanitization with _query_used, source truncation limits, stale-index warnings, and the line-vs-match_lines citation distinction. Warning/error/empty-list conventions are also spelled out so an agent knows what each response shape means.

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

Conciseness4/5

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

The description is very long (1000+ words) but clearly sectioned with headers and bullets, with the core purpose front-loaded. Most sentences earn their place given the tool's subtle FTS5 semantics and conditional return fields; the measured-project anecdotes and some repeated wildcard reminders are illustrative but could be trimmed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With zero annotations and 9 parameters, the description covers everything needed to invoke correctly: query formation semantics, scope boundaries, return-field meanings (match_lines vs line for citation), truncation, pagination, error vs warning vs empty-list conventions, and sibling routing. The output schema exists, and the description still adds value by explaining the conditional fields' semantics rather than just their shape.

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 baseline is 3, but the description adds non-inferable meaning: FTS5 query rules for the query param (add * for prefix, double quotes for phrases, single word is broadest), the mutual exclusivity of project and project_root, a use-case for project_only, and offset's page-navigation behavior. The value-add is real but concentrated on query plus cross-parameter relationships, so a 4 not a 5.

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?

The opening sentence names a specific verb and resource — 'Find patterns in the TEXT OF A DEFINITION — the code inside its extent' — and the coverage enumeration (callables, types, data definitions) makes the scope concrete. The 'Only the text matches' paragraph explicitly negates what this tool is not (name/signature/docstring search), distinguishing it from search_code and search_content without needing their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

An explicit 'When to use search_bodies and when search_code' section gives contrasting example queries ('self test' vs 'modem init'), names search_content for what falls outside definition extents, and advises project_only=True for questions about the team's own code. This exceeds the calibration example: it gives positive conditions, exclusions, and named alternatives.

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