Skip to main content
Glama

explain_symbol

Explain any C/C++ symbol in plain English with libclang-aware analysis, returning its purpose, inputs, outputs, and side effects from precomputed or on-demand LLM data.

Instructions

Explain what a C/C++ symbol does in plain English — libclang-aware analysis. Uses pre-computed LLM analysis when available (instant), falls back to on-demand LLM. Falls back to macro explanation when the name matches a #define.

Read-only. No side effects — uses pre-computed LLM analysis when available (instant, generated during fw-context index --analyze), falls back to calling an LLM on-demand. Returns the symbol's purpose, inputs, outputs, and side effects.

For raw source code use get_source. For symbol metadata without explanation use lookup_symbol. For body + callers + callees use get_symbol_context.

Args: name: Symbol name to explain. E.g. uart_init, ModemMsg::send. project_root: Project root directory. 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. context_lines: Lines of source context around the symbol definition (default 40, max 200). Only used when no pre-computed analysis exists. 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: dict: {name, kind, file, line, signature, explanation, llm_analysis (if pre-computed)}. With no pre-computed analysis and no local LLM (disabled), the dict holds explain_prompt and no explanation. Macro fallback returns kind="macro", signature (as #define NAME or #define NAME(a, b)), is_function_like, value (the replacement text ALONE), and expanded_value.

A ``warning`` key means that the local LLM gave no explanation —
the request timed out, or the model is not available.  The dict then
holds ``source`` and ``explain_prompt``: read the source, and answer
the prompt yourself.

When the file changed after the last index run, the dict adds
``stale`` (True) and ``stale_warning`` (str).  ``stale_warning`` is
separate from ``warning``, which the LLM error paths use.  A symbol
that moved gives its indexed body, not the code that now sits at the
stored line number.

The on-demand path reads ``context_lines`` around the symbol from
the DISK.  That window is NOT ifdef-filtered: it holds every
``#if`` branch.  This tool gives no ``source_origin``.

An ``ambiguous_warning`` key means that *name* matched more than one
symbol, such as two classes with a method of the same name.  This
answer is about ONE of them, and the key names it.  ``candidates``
(max 20) lists the others and ``candidates_total`` counts them.
Give a ``qualified_name`` from it to ask about one symbol only.
It is separate from ``warning``, which the LLM error paths use.

A symbol in a file outside the project root, such as an SDK
header, is explained and not refused.

On failure the dict holds only ``error`` with the reason.

Input Schema

NameRequiredDescriptionDefault
nameYesSymbol name to explain. E.g. 'uart_init', 'ModemMsg::send'.
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.
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.
context_linesNoLines of source context around the symbol definition (1-200).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changedv0.32.1
    • changedInput schema / properties / context_lines / description
      Previous value: -"Lines of source context around the symbol definition."New value: +"Lines of source context around the symbol definition (1-200)."
    • changedInput schema / properties / image / description
      Previous value: -"Sysbuild image within the variant. Required when the variant holds several: each image is a separate program."New value: +"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."
    • changedInput schema / properties / variant / description
      Previous value: -"Build variant (multi-build project). Omit to use default_variant. One query answers for ONE build."New value: +"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."
  2. Changed4 schema fields changedv0.32.0
    • addedInput schema / properties / context_lines / minimum
      Added value: +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."
    • addedInput schema / properties / name / 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."
  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. 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"
      +}
  5. First observedv0.1.0

TDQS

A4.8/5.0
Behavior5/5

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

No annotations are provided, so the description carries the full burden and does so: read-only/no side effects, instant pre-computed path vs on-demand LLM fallback, macro fallback shape, the 'warning' LLM-failure path, 'stale'/'stale_warning' after reindex, 'ambiguous_warning' with candidates, and that the context window is not ifdef-filtered and has no source_origin. This is unusually rich disclosure for an unannotated tool.

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?

Front-loaded with purpose, then safety, then alternatives, then Args/Returns sections, so it is easy to scan. It loses a point for redundancy: the 'pre-computed ... falls back to on-demand LLM' sentence is stated twice in the first two paragraphs, and the Returns block is long relative to the rest.

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 no output schema, the description fully documents the return dict, including all degradation paths (explain_prompt with no LLM, warning, stale, ambiguous_warning, error). For a six-parameter tool with build variants and LLM fallbacks, nothing an agent needs in order to interpret results 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 genuine meaning beyond the schema: project vs project_root are mutually exclusive alternatives, and context_lines is only consumed when no pre-computed analysis exists. The variant/image build-selection semantics are also clarified ('one query answers for ONE build').

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 gives a specific verb (explain) plus resource (C/C++ symbol) and the analysis mechanism (libclang-aware). It then explicitly distinguishes itself from three named siblings (get_source, lookup_symbol, get_symbol_context) with the exact condition for each, so an agent can route without opening any 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?

Explicit when-to-use routing is given: raw source -> get_source, metadata without explanation -> lookup_symbol, body+callers+callees -> get_symbol_context. It also states the pre-computed-vs-on-demand condition that governs behavior, and the macro-fallback condition, leaving little to inference.

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