Skip to main content
Glama

semantic_search

Search code symbols by concept rather than keyword: matches meaning through pre-computed embeddings, even when query words never appear in the code.

Instructions

Semantic search using pre-computed libclang symbol embeddings. Finds symbols by meaning, not by text — matches concepts even when query words don't appear literally in the code. Uses cosine similarity over variable-dimension embeddings generated during fw-context index. Dimensions vary by model: mxbai-embed-large → 1024, qwen3-embedding → 4096.

When to prefer over search_code: When you're describing a concept rather than searching for a known keyword. Examples:

  • "parcel locker state" finds door-state and shipment methods even though "parcel" and "locker" don't appear in their names.

  • "cell modem" finds _socket_t and ModemMsg* classes.

  • "delivery box" finds set_shipment and get_zrtdata.

  • "power consumption" finds get_load_power and INA260 class.

When to prefer search_code instead: When you know the exact keyword or symbol name ("fram_write", "cbor encode"). FTS5 is faster and more precise for lexical matches.

Threshold guidance (mxbai-embed-large model):

  • 0.50 — exploratory: more results, lower precision

  • 0.55 — balanced (~1000 results)

  • 0.60 — precise: ~175 avg, high precision (default)

  • 0.65 — strict: few results, may miss relevant symbols

Source-aware ranking: the similarity of a project symbol is multiplied by 1.2, and the similarity of every other symbol by 0.85. The index marks each file as project code or not, thus the two tiers are all there are. The multiplied score sets the order. _similarity in the result holds the raw cosine similarity, thus it is on the same scale as threshold and never above 1.0.

Requires [llm] enabled = true, embeddings in the index, and for an Ollama embedding model a running Ollama server at llm.ollama_url. A sentence-transformers or ft:// model embeds the query locally and needs no Ollama. Without one of them, the tool falls back to a lexical search with a warning.

Read-only. No side effects.

Args: query: Natural language description of what you're looking for. Be specific — 5–15 words works best. 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. threshold: Minimum cosine similarity (0.0-1.0). Default 0.60. The tool applies it to the raw cosine similarity, before the source boost. limit: Maximum number of results on one page (default 20, max 100). offset: Skip this many results. Reads the next page; the page notice names the offset to use. 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: The page notice {total, offset, shown, more, hint} comes before the symbols. total counts every symbol above threshold, as far as one KNN query reaches (4096 vector rows; a symbol of several chunks takes several of them). When the KNN stopped there with its last row still above the threshold, the notice also holds total_capped: True, and total is a lower bound. A page after the last symbol gives one info dict that names the total.

Then a list of dicts, each with: name, qualified_name, kind, file, line,
is_definition, signature, docstring, plus ``_method``
(``"embedding"`` or ``"search_code_fallback"``), ranked in windows
of 200 raw ranks: inside a window by the boosted similarity, then
by the symbol id.  Thus the boost moves a symbol only inside its
window.  The reranker (when
``llm.reranker_model`` is set) reorders the first symbols of a
page, and moves no symbol to another page.  An ``"embedding"``
result also holds ``_similarity``, the raw cosine similarity.  A
symbol also holds ``summary``, ``inputs`` and ``outputs`` when
``fw-context index --analyze`` wrote them — model text, never a
fact to quote — and ``_rerank_score`` when
``llm.reranker_model`` is set.

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.

Fallback: when the LLM is disabled or not running, or the index
holds no embeddings, or the embedding model fails, this tool runs
a plain FTS5 symbol search (the first step of ``search_code``,
with no kind and no relaxation), one page of it.  A leading dict
holds a ``warning`` with the reason, the page notice follows, and
each symbol carries ``_method: "search_code_fallback"``.  A
changed result file or compile_commands.json adds another leading
``warning``.  When the lexical search finds nothing too, the answer
is one ``warning``.

No match above ``threshold`` runs the same lexical fallback, with a
``warning`` that suggests a lower threshold.  When a phase of the
search failed, that ``warning`` gives the error of the phase.  When
the best raw similarity of all matches is below 0.68, the answer is
the page notice and one dict: a ``warning`` that the matches are
likely unrelated, ``_fallback_suggestion: "search_code"``,
``_best_similarity``, and the matches of the page in ``_results``.

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. 'parcel locker state machine' or 'how does the modem connect?'.
offsetNoSkip this many results. Reads the next page of the symbols above the threshold.
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.
thresholdNoMinimum cosine similarity (0.0-1.0). Default 0.60. Use 0.55 for exploratory, 0.50 for broad search.
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. Reads the next page of the symbols above the threshold.",
      +  "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. Changed4 schema fields changedv0.32.0
    • addedInput schema / properties / limit / minimum
      Added value: +1
    • addedInput schema / properties / query / minLength
      Added value: +1
    • addedInput schema / properties / threshold / maximum
      Added value: +1
    • addedInput schema / properties / threshold / minimum
      Added value: +0
  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. Addedv0.5.0

TDQS

A4.7/5.0
Behavior5/5

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

No annotations provided, so the description carries the full burden — and it does: prerequisites (llm enabled, embeddings present, Ollama for Ollama models), local embedding path, fallback to FTS5 with a warning, source-aware 1.2/0.85 ranking, window-based reordering, and explicit 'Read-only. No side effects.' Warning/error shapes are documented.

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 with purpose and routing, and bold headers aid navigation. However the 'Returns:' section is long and largely redundant with the existing output schema, and the threshold/ranking prose repeats itself in places. It is thorough but heavier than needed.

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 an 8-param read-only retrieval tool with a rich output schema, the definition covers prerequisites, degradation/fallback paths, ranking semantics, pagination, and failure shapes. Nothing an agent needs to invoke it correctly 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 baseline is 3, but the description adds real value beyond the schema: threshold values mapped to precision/result-count outcomes, the raw-vs-boosted similarity distinction for threshold, query word count guidance, and the project-vs-project_root mutual exclusivity and one-build-per-query constraint for variant/image.

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 ('Semantic search using pre-computed libclang symbol embeddings') and explicitly contrasts the concept-match behavior against search_code's lexical matching. An agent can distinguish it from search_code, lookup_symbol, and smart_search from the description alone.

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?

Explicit bidirectional routing: 'When to prefer over search_code' with four worked examples of concept queries, and a parallel 'When to prefer search_code instead' for known keywords/symbol names. Threshold guidance gives per-value tradeoffs (exploratory/balanced/precise/strict).

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