Skip to main content
Glama

smart_search

Find C/C++ symbols by describing what you need in natural language when exact keywords are unknown; searches a libclang index by meaning using LLM-generated FTS5 terms.

Instructions

Natural-language search: an LLM generates FTS5 keywords, then searches the libclang index. Finds concepts by meaning rather than exact text match. Prefer this when you don't know the exact keywords and want to describe what you're looking for ("how does the modem connect?", "handle BLE pairing failure").

Read-only: yes. Slow (10-30 s) — delegates to the full SMART_SEARCH pipeline (translate → rough_search → llm_query → fts5_search → refine → embedding → adaptive_fusion → deduplicate → expand_context → format).

Multi-phase approach:

  1. Translate non-English queries

  2. Rough search to gather sample symbols for naming conventions

  3. LLM sees those samples + query and generates FTS5 terms

  4. FTS5 search with generated terms

  5. Refine: LLM checks results and course-corrects query terms

  6. Semantic embedding search (cosine similarity re-rank)

  7. Deduplicate, score, and format results

When to prefer over search_code: When you don't know the exact keywords and want to describe what you're looking for ("how does the modem connect?", "handle BLE pairing failure").

Fallback: When LLM is unavailable, falls back to direct FTS5 search with word-split terms from the query. When the LLM call or the embedding step fails, a metadata dict gives the reason in warning or detail.

Args: query: Natural language description of what you're looking for. Be specific — 5–15 words works best. project_root: Project root directory. Auto-detected from CWD 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. limit: Maximum number of results on one page (default 20, max 100). The search itself always ranks up to 100 symbols. offset: Skip this many results of the previous search of the same query. 0, the default, is a NEW search. A page with an offset comes out of the stored answer of the last search; when the last search was of another query (or another project, or a build that a reindex changed), the tool searches again first. An index run that keeps the build keeps the stored answer. variant: Variant of the build (a board, or a PlatformIO environment). On a project of more than one build, give the arguments of one build as the refusal lists them: the variant, the image, or the two. fw-context does not select a build. One query answers for ONE build. image: Image of the build: a separate program, such as the application or the bootloader. Give it when the build has an image name.

Returns: list of dicts with metadata entries (_generated_queries, _rough_queries, _translated_from + _translated_to), then the page notice {total, offset, shown, more, hint}, followed by symbol results with name, qualified_name, kind, file, line, is_definition, signature, docstring. total counts the symbols of the answer (at most 100). A page after the last symbol gives one info dict that names the total. A symbol also holds summary, inputs and outputs when fw-context index --analyze wrote them. A model wrote that text, and the code did not: never quote it as a fact.

When the pipeline passes the LLM timeout (``[llm] timeout`` of the
project), a leading dict holds ``_partial: True``, a ``warning``
with the timeout, and a ``hint``.  The symbols that follow are the
ones that the steps before the timeout found, without the later
re-rank steps; there can be none.  This answer has no page notice
and is not stored, thus a next page searches again.  Make the query
more specific, or increase the LLM timeout.

When the index of the build of the query is not current (for
example, compile_commands.json changed after the last index run),
a leading dict holds ``warning`` and ``index_state``.  The answer
then comes from the last index run.

No match gives the metadata entries and a dict with ``info``.  One
dict with ``error`` means the query failed — check that key first.

Input Schema

NameRequiredDescriptionDefault
imageNoImage of the build: a separate program, such as the application or the bootloader. On a project of more than one build, give it when that build has an image name, as the refusal lists it.
limitNoMaximum results on one page (default 20). Held between 1 and 100.
queryYesNatural language description, 5-15 words. E.g. 'how does the modem connect?' or 'handle BLE pairing failure'.
offsetNoSkip this many results of the previous search of this query. 0 (the default) is a new search.
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.
variantNoVariant of the build (a board, or a PlatformIO environment). On a project of more than one build, give the arguments of one build as the refusal lists them: the variant, the image, or the two. fw-context does not select a build for you. One query answers for ONE build.
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

NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changedv0.32.1
    • addedInput schema / properties / image
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Image of the build: a separate program, such as the application or the bootloader. On a project of more than one build, give it when that build has an image name, as the refusal lists it.",
      +  "title": "Image"
      +}
    • changedInput schema / properties / limit / description
      Previous value: -"Maximum results (default 20, max 100)."New value: +"Maximum results on one page (default 20). Held between 1 and 100."
    • addedInput schema / properties / offset
      Added value: +{
      +  "default": 0,
      +  "description": "Skip this many results of the previous search of this query. 0 (the default) is a new search.",
      +  "minimum": 0,
      +  "title": "Offset",
      +  "type": "integer"
      +}
    • addedInput schema / properties / variant
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Variant of the build (a board, or a PlatformIO environment). On a project of more than one build, give the arguments of one build as the refusal lists them: the variant, the image, or the two. fw-context does not select a build for you. One query answers for ONE build.",
      +  "title": "Variant"
      +}
  2. Changed2 schema fields changedv0.32.0
    • addedInput schema / properties / limit / minimum
      Added value: +1
    • addedInput schema / properties / query / minLength
      Added value: +1
  3. Changed3 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."
  4. First observedv0.1.0

TDQS

A4.7/5.0
Behavior5/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 so: it declares read-only, warns about 10-30s latency, enumerates the pipeline phases, and discloses edge behaviors (partial results with `_partial`/`warning` on LLM timeout, stale-index `index_state` warning, no-match `info` dict, `error` key on failure). It also warns that `summary`/`inputs`/`outputs` are model-written and must not be quoted as fact.

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?

Front-loaded and headed, but padded: the same example pair ("how does the modem connect?" / "handle BLE pairing failure") and the same don't-know-keywords rationale appear twice, and the arrow-form pipeline list is then re-expanded as numbered phases. The offset paragraph is verbose for what it conveys. Content is useful but not tight.

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?

For a 7-parameter tool with an output schema, the description covers what the schema cannot: pipeline behavior, latency, fallbacks, partial/stale/error result shapes, and build selection rules. An agent has everything needed to call it and interpret the response.

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; the description goes beyond it by explaining offset's caching semantics (a paged request reuses the stored answer unless the query/project/build changed) and the project vs project_root mutual exclusivity. It restates query-length and limit bounds that the schema already covers, so it adds value without fully redefining every parameter.

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 mechanism (an LLM generates FTS5 keywords, the search runs over the libclang index) and the distinct benefit (finds concepts by meaning, not exact text). It explicitly names the sibling it competes with (search_code) and the condition that distinguishes them, so an agent can route without opening either schema.

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?

Gives an explicit when-to-use ("you don't know the exact keywords"), a when-to-prefer-otherwise framing ("When to prefer over search_code"), concrete example queries, and the failure-mode fallback (direct FTS5 search when the LLM is unavailable). Alternatives and the selection condition are both spelled out.

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