Skip to main content
Glama

get_active_build

Check index health and get active build metadata: status, compile commands, defines, memory, and reindex reasons before querying C/C++ symbols.

Instructions

MANDATORY FIRST CALL for C/C++ projects. Return metadata about the most recently indexed build configuration — check index health before using any other fw-context tools.

Read-only, and it spawns no subprocess — the startup daemon thread and the file watcher own the background reindex.

Act on status:

  • "ready" — up to date. Continue.

  • "reindexing" — background reindex running; queries stay accurate. Continue. reindex_progress holds its last log line.

  • "reindex_needed" — schema mismatch, an old row format, changed compile_commands.json, or a source file that compile_commands.json does not cover. Queries still work on existing data. Read reindex_reasons: a missing source file needs fw-context index --build, the others need only fw-context index.

    Read bg_reindex_running before you name any command here. A run already under way does the work, thus a second one only waits on the same lock, and index_message and the branch reason both say so. That field covers a run of the daemon AND a run the operator started — the arguments of neither are readable, thus a reason that needs --build can outlive a run without it. This status wins over "reindexing" deliberately: the answers of this moment come from the rows of the last FINISHED run.

  • "no_index" — initialized, never indexed. Run fw-context index.

  • "not_initialized" — run fw-context init.

A failure sets NO status. DB corruption, or no access to the index, gives a dict that holds error alone. Read that key first: a reader that waits for status == "error" waits for a value this tool does not produce.

Four conditions set reindex_needed: an outdated schema, an outdated ROW FORMAT, a changed compile_commands.json, and a source file that is on disk but absent from compile_commands.json. The last one needs a build, because only the build system writes that file — a plain reindex has no translation unit for the file and skips it without a word. Modified source files are something else: they are handled per-query, and never set it.

row_format_mismatch means that the same columns hold text with an older meaning. Take it seriously: an index written before fw-context-rows/1 keeps every inactive #ifdef branch, thus a body or a file from it can show code that the compiler never sees. An index written before fw-context-rows/3 is wrong the other way: it ANSWERS LESS than it should. A definition that begins and ends on one line has no stored body there, thus search_bodies cannot reach an inline accessor; no macro is marked function-like; and no instance links to its template, thus get_template_instances gives an empty list for every template. Each of those looks like a legitimate empty answer. The value of a macro there also holds its parameter list glued to its replacement text, thus neither can be read out of it.

client_restart_required is the OPPOSITE case, and no command repairs it. The index carries a NEWER row format than this server process reads, thus the index is the correct one and this process is the old reader. A reindex makes it worse than useless: the indexer writes the same new format again, and the message comes back over an index that had nothing wrong with it. status therefore stays "ready" and reindex_needed stays False — every query keeps working.

Do NOT run a reindex for this field. Tell the operator to restart the LLM client — Claude Code, opencode, or whichever one is in use. The MCP server is a child process of that client, thus nobody can restart the server by itself. client_restart_reason holds the wording, and index_message opens with it.

indexed_at and first_indexed_at are UTC; file mtimes are local time. Never compare the two directly — in UTC+2 a correctly indexed file looks 2 hours newer than indexed_at. Call with fast=False to find modified files.

analysis splits the LLM-analysis coverage into project and vendor symbols:

  • model — the model of the analysis, or None. One model only, even when several were used.

  • analyze_vendor — the value at index time, not the current config.

  • project / vendor{analyzed, skipped, total}. skipped = tried, but not analyzable (body larger than the model context, an unparseable answer, or a body that was not readable).

  • complete — no work left: every project symbol is analyzed or skipped. True exactly when reindex_reasons holds no "unanalyzed symbols" entry. Vendor symbols excluded by analyze_vendor=False never block it, thus vendor.total large with vendor.analyzed=0 is expected, not a defect.

Args: 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. fast: When True (default), the header check reuses the cached manifest hashes. Both modes run the per-file scan, thus modified_files_count is accurate either way — a tool that reported "ready" while the search tools warned about the same file gave the caller two readings and no way to choose. False recomputes the header hashes and costs several times more.

Returns: dict: {config_hash, project_id, project_root, build_system, compile_commands, indexed_at (str — "YYYY-MM-DD HH:MM:SS" in UTC, the completion time of the last full index), symbol_count, file_count, reference_count, modified_files_count (int — files whose content no longer matches the index; counted in both modes), header_affected_tus (int — number of TUs with stale header dependencies), manifest_verification (str — "full" when manifest.json exists, "none" otherwise), analysis (dict — LLM-analysis coverage split by project/vendor: {model, analyze_vendor, project: {analyzed, skipped, total}, vendor: {analyzed, skipped, total}, complete}), description (str), first_indexed_at (str — UTC, same format as indexed_at), vendor_paths (list[str] — config index.vendor_paths), project_paths (list[str] — config index.project_paths), effective_vendor_patterns (list[str] — the SQL LIKE patterns that this build really used to mark vendor code, for example ["mbed-os/%"]; empty when the manifest cannot be read. The two lists above hold what the config asks for, this one what the index did), bg_reindex_running (bool), reindex_progress (str or None — last log line when reindex is running), schema_version (int — DB schema version), current_schema (int — code expects), status (str — "ready"|"reindexing"| "reindex_needed"|"no_index"|"not_initialized"; a failure sets no status and gives error alone), reindex_needed (bool — structural mismatch requiring a full reindex), reindex_reasons (list[str] — why reindex is needed, empty when False. One of them asks for fw-context index --build rather than a plain reindex: when the tree is on a different branch than the index, compile_commands.json belongs to the OLD branch and carries its file list and its compiler flags, so only a build regenerates it. Read the reason text — it names the command it needs), stale (bool — True when reindex_needed or header_affected_tus > 0), _warning (str, optional — when manifest verification is not "full"), vec_available (bool), vec_error (str, optional), index_message (str — human-readable summary of index state), multi (bool — True for a multi-variant project), variants (list[dict] — {name, description, board}), images (list[dict] — {name, description, dir, type}), variant_images (dict — variant name to its image names), active_variant (str or None — [build] default_variant), active_image (str or None — [build] default_image), entry_point (str — the ENTRY() of the linker script of the build that the other fields describe, empty when no script names one), memory (list[dict] — the MEMORY regions of that build: {name, attributes, origin, length, origin_value, length_value, file_path, line})}

About ``memory``: ``origin`` and ``length`` hold the expression the
script writes, thus they differ by platform — an mbed script writes
`0xefe00` and a Zephyr script writes `((673792) - 0xe6)`.
``origin_value`` and ``length_value`` hold the number, and both are
None for an expression that names a symbol, such as
`ORIGIN(RAM) + LENGTH(RAM)`.  The end of a region is
``origin_value + length_value``.

``memory`` and ``entry_point`` describe ONE build.  For a
multi-variant project they follow ``config_hash``, which is the
build named by ``[build] default_variant``, and both are empty when
the config names no default.  Use ``list_variants`` for the map of
every build.

``memory`` is empty for a build system that records no linker
script.  A PlatformIO project is the measured case: SCons writes no
ninja file and no link command the index can read, and the map file
never names the script.  An empty list means "not recorded", never
"no memory".

``defines`` (dict — the `-D` flags of that build) and
``defines_varying`` (int).  ``defines`` holds only the names that
EVERY translation unit of the build carries with the same value, so
the tool never shows the defines of one file as the defines of the
build.  ``defines_varying`` counts the names left out, thus a name
absent from ``defines`` is either not defined at all or not defined
everywhere — measured on the Mbed project: 27 names in all 881 units, 59
in only some, where the three assembly files get a shorter set.

This is the configuration the BUILD states, not every macro the
preprocessor saw.  The second is three orders of magnitude larger —
27800 distinct names on the STM32 project — and almost all of it comes from the
headers and the compiler.  A Zephyr build keeps its real
configuration in ``autoconf.h`` (740 `CONFIG_*` names) and passes
few `-D` flags, so ``defines`` says little there and a great deal on
an mbed build, where it holds `APPLICATION_ADDR`,
`APPLICATION_SIZE`, and `CMSIS_VECTAB_VIRTUAL`.

For a project that is not initialized, the result holds only
``status``, ``project_root``, and ``index_message``.  When no index
exists, the result adds ``project_id``.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
fastNoWhen True (default), reuse the cached manifest hashes for the header check. Both modes count modified files. Pass False to recompute the header hashes, which is far slower.
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.
project_rootNoProject root directory. Auto-detected from CWD if omitted. This field also accepts a project name or a project_id, but project is the clear field for those.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changedv0.30.0
    • addedInput schema / additionalProperties
      Added value: +false
    • changedInput schema / properties / fast / description
      Previous value: -"When True (default), skip the per-file stat scan. modified_files_count is then always 0. header_affected_tus still comes from the cached manifest hashes when manifest_verification is 'full'."New value: +"When True (default), reuse the cached manifest hashes for the header check. Both modes count modified files. Pass False to recompute the header hashes, which is far slower."
    • 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 directory. Auto-detected from CWD if omitted."New value: +"Project root directory. Auto-detected from CWD if omitted. This field also accepts a project name or a project_id, but project is the clear field for those."
  2. Changed1 schema field changedv0.27.6
    • changedInput schema / properties / fast / description
      Previous value: -"When True (default), skip per-file stat scan — faster but modified_files_count and header_affected_tus may be 0."New value: +"When True (default), skip the per-file stat scan. modified_files_count is then always 0. header_affected_tus still comes from the cached manifest hashes when manifest_verification is 'full'."
  3. Changed1 schema field changedv0.25.2
    • addedInput schema / properties / fast
      Added value: +{
      +  "default": true,
      +  "description": "When True (default), skip per-file stat scan — faster but modified_files_count and header_affected_tus may be 0.",
      +  "title": "Fast",
      +  "type": "boolean"
      +}
  4. 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 exist, so the description carries the full burden — and it discloses far beyond a typical definition: read-only and spawns no subprocess, the failure case sets NO status and returns error alone (explicitly warning a reader not to wait for status == 'error'), UTC-vs-local-time comparison traps, the row_format_mismatch semantics, and the meaning of empty memory lists ('not recorded, never no memory'). Nothing about behavior is hidden.

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?

Excellent front-loading — the purpose, role, and read-only/spawns-no-subprocess facts come first, and the status decision tree is the second block. The Returns section is clearly labeled and organized. However, the description is extremely long (several thousand words) with some redundancy, such as the 'Four conditions set reindex_needed' paragraph restating the status section, and the verbose defines/assembly-file measurement aside. Almost everything is substantive, but it is heavier than strictly necessary.

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 and a very rich return value, the description carries the full burden of documenting results, and it does so exhaustively: every status value, the error-only dict, the memory region origin/length semantics, the defines scope caveat, and the reduced result shape for uninitialized projects. Nothing an agent needs to interpret a response is left unexplained.

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% and the schema descriptions are already detailed, so baseline is 3. The description adds genuine value beyond the schema: the mutual-exclusivity rule ('Give one of the two, not both' for project vs project_root) and the correctness guarantee that modified_files_count is accurate in both fast modes. That interaction-level semantics pushes it above baseline, though not dramatically.

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?

Opens with a specific verb-resource pair ('Return metadata about the most recently indexed build configuration') and adds an explicit role marker ('MANDATORY FIRST CALL... check index health before using any other fw-context tools'). This immediately distinguishes it from every sibling search/query tool and states what it is not (a search or mutation tool).

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?

Provides exhaustive when-to-use guidance: it is the mandatory first call, and it gives a full decision tree on the status field — what command to run for 'no_index', 'not_initialized', and each 'reindex_needed' reason, plus explicit do-NOT guidance ('Do NOT run a reindex' for client_restart_required). It names sibling alternatives (list_projects, list_variants) for adjacent needs and tells when to pass fast=False.

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