fw-context-mcp
fw-context-mcp provides a persistent, build-aware semantic index of embedded C/C++ firmware, exposed as MCP tools for querying code structure, call relationships, and build context.
Inspect project/index health, list builds, check dependencies, Ollama status, memory maps, defines, and reindex state.
Search symbols by exact/prefix name, keyword, body content, file content, or semantic similarity (including LLM-assisted smart_search).
Retrieve source bodies, file maps, symbol context, macros, variables, class members, inheritance chains, method overrides, and template instances.
Analyze call graphs: direct/indirect callers and callees, recursive traversal, call paths, hotspots, dead code, wrapper callers, and data-flow tracing.
Model embedded-specific relationships: function pointers, callbacks, indirect call sites/targets, ISRs, and vector table service status.
Filter project vs vendor code, reindex individual files, reset indexes, and configure LLM chat/embedding backends.
Allows AI assistants to understand and navigate Arduino firmware codebases by indexing them via compile_commands.json.
Provides optional natural-language search and symbol explanation capabilities by leveraging local LLMs via Ollama.
Allows AI assistants to understand and navigate PlatformIO-based embedded firmware projects.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@fw-context-mcpWhat does modem_parser_oob_init do?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
fw-context
Build-aware code intelligence for AI coding agents working on embedded C and C++ firmware.
fw-context builds a persistent semantic index from compile_commands.json and the libclang AST, then exposes it to coding agents through MCP. Instead of reconstructing your firmware through repeated file reads and text searches, the agent can query the program structure that one build produces.
It helps agents answer questions such as:
Which implementation is active in this build?
Who calls this function, directly or indirectly?
Where is this callback registered?
Which function-pointer assignments can reach this call site?
Which code is excluded by preprocessing?
What will be affected if this API changes?
How does execution flow from an ISR to application code?
The goal is not to give the model more source code. It is to give it the smallest useful, build-aware context needed for the current task.
Results from a real firmware review
In the included firmware review case study, fw-context was used on an nRF52/Mbed OS project containing approximately 67,000 lines of C and C++:
115 changed files reviewed by 8 parallel subagents
19 findings across memory safety, concurrency, API use and dead code
9 findings that depended on semantic relationships not available from ordinary text search alone
approximately 54,000 context tokens used by fw-context queries
an estimated 5.8 million tokens for the equivalent broad
grepand file-reading workflow
The case study includes the review output, methodology and per-tool token analysis so the claims can be inspected rather than treated as a black-box benchmark.
Related MCP server: Semantic Code Search MCP Server
Quick start
Prerequisites
Python 3.11 or newer
libclang
a project that can produce
compile_commands.jsonan MCP-capable coding agent such as Claude Code or OpenCode
Ollama is optional for the core index: symbols, full-text search, call graph and source come from libclang and SQLite only. With the default configuration, Ollama also computes the vector embeddings (semantic_search, the re-rank step of smart_search) and the symbol analysis (explain_symbol, symbol descriptions). Without Ollama, these features fall back to full-text search or return raw prompts, and the status tools tell you that the embeddings are not complete. When you use no embedding model and no LLM, set [llm] enabled = false. See Ollama.
Install via pip (recommended)
pip install fw-context-mcpInstall the current source version
git clone https://github.com/turbyho/fw-context-mcp.git ~/.fw-context/src
cd ~/.fw-context/src
make installRegister fw-context with the supported coding agents detected in your project:
cd /path/to/your/firmware
fw-context initBuild and index the firmware:
cd /path/to/your/firmware
fw-context index --buildThen restart the coding agent and ask it questions about the project. The index is persistent and incremental; after the initial run, changed translation units are reprocessed instead of rebuilding the entire index.
See the Quick Start and Installation Guide for platform-specific setup and supported build systems.
What fw-context changes
Without a semantic project index, an AI coding agent usually starts by opening files, searching for names, following includes and trying to infer relationships that are implicit in the build. In embedded firmware this reconstruction is often the dominant part of the task.
That approach can fail in predictable ways:
reviewing source files that are not part of the build that you query
following the wrong preprocessor branch
missing callback registrations and indirect calls
selecting an inactive driver or platform implementation
treating declarations found by text search as reachable code
consuming large amounts of context on vendor code and unrelated files
fw-context moves much of that reconstruction into a reusable compiler-derived index. The agent can request exact symbol bodies, callers, callees, references, active macros, callback relationships, inheritance edges and other targeted information without reading whole source trees.
Why embedded firmware is different
In many application-level projects, the source files visible in the repository are reasonably close to the program being executed. Embedded C and C++ projects often have a much larger gap between the source tree and the resulting program.
The active firmware depends on factors such as:
compiler flags and preprocessor definitions
target, board and product configuration
include paths and generated headers
Kconfig and Devicetree selections
selected driver and HAL implementations
templates, inheritance and virtual dispatch
callbacks, interrupt handlers and function pointers
vendor SDK and RTOS configuration
A repository may therefore contain several plausible implementations of the same subsystem while only one is compiled for the selected target. An agent can reason convincingly about the wrong implementation unless it first reconstructs the build context correctly.
How it works
fw-context indexes the project through the same compilation database used by build tooling and language servers.
flowchart LR
CCJ[compile_commands.json] & SRC[(source files)] --> LIBCLANG[libclang<br/>AST parser]
LIBCLANG --> SYMBOLS[symbols<br/>name, kind, USR<br/>signature, ifdef-filtered source body<br/>docstring, tokens] & FILES[files<br/>path, language<br/>ifdef-filtered content<br/>project/SDK sources] & REFS[refs & call graph<br/>fp_assignments<br/>indirect_call_sites] & INHERIT[inheritance<br/>& overrides<br/>virtual dispatch] & MACROS[macros<br/>params, value<br/>& expanded value<br/>FTS5 searchable] & ENRICH[optional enrichment<br/>embeddings & summaries<br/>hotspot cache]
SYMBOLS & FILES & REFS & INHERIT & MACROS & ENRICH --> MCP[MCP server<br/>37 tools]
MCP --> LLM[AI coding agent]The index contains:
symbol definitions, signatures, source extents and documentation
references, direct call edges and recursive caller paths
function-pointer assignments and indirect call sites
callback registrations and invocation relationships
active, preprocessor-filtered file content
macro parameter lists, replacement text and expanded values
inheritance, overrides and virtual-dispatch relationships
translation-unit and project/vendor metadata
optional embeddings and LLM-generated summaries
The MCP server exposes this information as compact high-level queries optimized for repeated use by an AI agent.
Typical use cases
build-aware review of firmware commits
tracing execution across ISRs, work queues, tasks and callbacks
locating all callers and references of an API
identifying the implementation selected by the current build
impact analysis before changing a function signature or data type
navigating unfamiliar firmware without reading complete files
finding dead-code candidates and unreferenced symbols
separating project code from SDK and vendor code
reducing irrelevant source text sent to the model
fw-context supports Zephyr, PlatformIO, Mbed OS, Arduino, ESP-IDF, generic CMake, Makefile-based projects and custom builds that can provide a compilation database. Additional setup paths are documented for Keil, IAR, STM32CubeIDE and TI Code Composer Studio.
Why not just use clangd or another LSP?
clangd already uses compilation commands and is excellent at editor-oriented tasks such as diagnostics, completion, go-to-definition and reference lookup. fw-context does not replace it.
fw-context targets a different interface and workload:
persistent project-wide data prepared for repeated agent queries
MCP tools that return compact, structured semantic context
recursive caller and impact-analysis queries
callback and function-pointer relationship modelling
active source content suitable for targeted retrieval
project/vendor classification and firmware-specific workflows
optional cached enrichment shared across repeated analyses
Use clangd for interactive editing. Use fw-context when an AI agent needs structured, reusable context for reviewing, understanding or navigating the built firmware.
Documentation
Project maturity
fw-context is functional and is used on real embedded C and C++ projects, but its interfaces and indexing behaviour are still evolving. Bug reports, incorrect results, unsupported build configurations and reproducible edge cases are particularly valuable.
The project is local-first: source code and the compiler-derived index remain on the developer's machine unless optional external services are explicitly configured.
Background
The project grew from a recurring failure mode in AI-assisted firmware work: coding agents frequently spent more effort reconstructing the active program than reasoning about the engineering question itself.
For the longer explanation, read: Why AI Coding Agents Keep Making the Same Mistakes When Analyzing Embedded Firmware
The compiler has already reconstructed your program. Let your coding agent use it.
Available Tools
37 toolscheck_dependenciesA
Run the dependency audit of the installation. Read-only, and it creates no file.
Call it when get_project_status or another tool reports a problem of
the installation, or before the first fw-context init. It is not a
call for each session: it runs every check of the installation.
Each entry gives what to do in action: a message for a human,
and the shell command that repairs it. status="skipped" means a
prerequisite is missing (e.g. libclang-so skipped because
libclang-python is absent) — not a failure.
In a project that is not initialized, only the checks that need no project config run: the Python packages and libclang. The Ollama, model, database and build checks need the config.
The check config names a config file that cannot be used. The
checks that read the config are then skipped. When a config file
cannot be used, the tool cannot know if the project is initialized,
thus it runs every check.
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.
Returns:
list[dict]: one dict per check, each with name, status,
critical (bool), message, and an optional action
({message, command}).
| Name | Required | Description | Default |
|---|---|---|---|
| project | No | 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. | |
| project_root | No | Project root. Auto-detected if omitted. Pass explicitly when the project is not the server cwd. This field also accepts a project name or a project_id, but project is the clear field for those. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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 richly: it discloses read-only behavior, the meaning of status='skipped' as a missing prerequisite rather than a failure, which checks run in an uninitialized project, and the fallback behavior when a config is unusable. This is substantive behavioral context beyond any structured field.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and read-only guarantee are front-loaded, and most paragraphs cover distinct behavioral nuances. It is on the verbose side and repeats the project/project_root guidance already in the schema, but little is purely wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool whose output schema already defines the returned fields, the description adds the remaining context an agent needs: when checks are skipped, how uninitialized projects are handled, and what the action/command fields are for. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The description explains the project vs project_root relationship ('use one of the two, not both'), but this largely restates the schema text, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource ('Run the dependency audit of the installation') and immediately discloses the safety profile ('Read-only, and it creates no file'). It is clearly distinguishable from siblings like check_ollama and get_project_status, which check narrower concerns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to call it ('when get_project_status or another tool reports a problem... or before the first fw-context init'), names the triggering sibling, and states a negative condition ('It is not a call for each session'). The when/when-not split leaves little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_ollamaA
Check whether the LLM backend is running and the configured embedding/chat model is installed.
Read-only: yes. No side effects. Call before smart_search, semantic_search, or explain_symbol (when on-demand fallback is expected — pre-computed analysis returns instantly without the LLM backend).
Args: project_root: Project root. Auto-detected if omitted. Used to locate the project's LLM configuration. 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.
Returns:
dict: {ollama_enabled (bool), status (str — "ok"|"disabled"|
"not_configured"|"model_missing"|"embedding_unavailable"|"error"),
ollama_running (bool), ollama_url (str), configured_model (str),
num_ctx (int), installed_models (list[str]),
chat_api (dict — {configured (bool), model (str)}: whether an
external chat API replaces Ollama, and the model it names; a
configured one adds endpoint, format, and compliance_warning for an
external host),
configured_embed_model (str), embedding_installed (bool),
embedding_backend (str — "ollama", or "local" for a
sentence-transformers or ft:// model, which needs no Ollama:
it counts as installed, and with chat on an external API a
stopped Ollama still gives "ok"),
message (str, when status is not "ok"), model_details (list[dict]),
suggest_cloud (bool), vec_available (bool),
vec_error (str, optional), debug_log (str, optional — only when
debug logging is enabled)}
The chat model is looked for on the Ollama server of the chat
calls: ``ollama_url``, or the Ollama server that ``chat_api_base``
names. An OpenAI-compatible ``chat_api_base`` runs the model
itself, and no Ollama server is asked for it. ``"model_missing"``:
``message`` names a command for each missing model, which sets
``OLLAMA_HOST`` to the server that must hold the model.
``"error"`` also means that the Ollama server of ``chat_api_base``
gives no model list. When the server of ``ollama_url`` does not
answer, the chat model is not looked for.
ollama_url, num_ctx, installed_models, model_details,
configured_embed_model, and embedding_installed are present only
when Ollama runs; configured_model also needs chat on Ollama.
``"disabled"`` gives only status, ollama_enabled,
ollama_running, configured_model, num_ctx, and message;
embedding_backend is present on every other status.
| Name | Required | Description | Default |
|---|---|---|---|
| project | No | 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. | |
| project_root | No | Project root. Auto-detected if omitted. Used to locate LLM config. Falls back to auto-detection when omitted. This field also accepts a project name or a project_id, but project is the clear field for those. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does it well: it declares read-only/no-side-effects, enumerates every status value ('ok'|'disabled'|'not_configured'|'model_missing'|...), explains per-status field presence, describes the chat_api_base/OpenAI-compatible fallback, and documents ''model_missing'' and ''error'' semantics. This is unusually rich behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is long, but front-loads purpose and safety, then uses clear Args/Returns sections. Nearly every sentence earns its place given there is no output schema, though the Returns section is dense enough that it edges toward overload for a two-parameter check.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations and no output schema, the description must supply both the safety profile and the return contract, and it does: it enumerates statuses, conditional field presence, fallback backends, and error cases. An agent has everything needed to interpret the result correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the Args section in the description largely restates the schema text for project_root and project, including the mutual-exclusivity note that is already in the schema. It adds essentially no meaning beyond the structured field descriptions, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific verb and resource — 'Check whether the LLM backend is running and the configured embedding/chat model is installed' — which is unambiguous and clearly distinct from siblings like check_dependencies or configure_llm. An agent can tell what this tool answers without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to call it ('Call before smart_search, semantic_search, or explain_symbol') and even carves out the exception where pre-computed analysis returns instantly without the backend, so the agent knows when NOT to call it. This is routing-level guidance, not mere implication.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
configure_llmA
Configure LLM settings for the current project.
Writes to <project>/.fw-context/local.toml ONLY (gitignored,
per-developer). Does NOT modify the global config or the shared
project config.toml. After writing, tests the configuration
by making a simple API call (skipped when LLM is disabled). When the
test fails, the previous local.toml is restored and status is
"error". A call with no change returns "error" and writes
nothing.
IMPORTANT: When chat_api_base points to an external host, source
code snippets in chat prompts will be sent to that endpoint. Ensure
this complies with your organization's data security policies.
Consider using local Ollama or an internal API proxy first.
Args:
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.
chat_api_base: Chat API URL (see description for format details).
chat_api_key: Bearer token for cloud/proxy APIs.
chat_api_format: Override auto-detection: "ollama" or "openai";
"auto" returns to detection from the URL. None keeps the
current value.
model: Chat model name.
embed_model: Embedding model: an Ollama tag, a sentence-transformers
name (BAAI/..., needs the st extra), or ft://.
auto_pull: Whether to auto-pull models on 404. None keeps the
current value.
stream: Stream chat responses via SSE. True avoids reverse-proxy idle timeouts.
Returns: dict: {status ("ok"|"error"), chat_api (dict — configured, endpoint, format, model), model (str), auto_pull (bool), stream (bool), test_latency_s (float, on success), test_response (str, on success), compliance_warning (str, when chat_api_base is external), message (str)}
| Name | Required | Description | Default |
|---|---|---|---|
| model | No | Chat model name. None = keep current. | |
| stream | No | Stream chat responses via SSE (both OpenAI-compatible and Ollama-native). True = send stream:true, consume SSE chunks — avoids reverse-proxy idle timeouts (nginx 60s, Cloudflare 100s). None = keep current setting. | |
| project | No | 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. | |
| auto_pull | No | Auto-pull models on 404 (Ollama only). False for intranet. None = keep current. | |
| embed_model | No | Embedding model: an Ollama tag, a sentence-transformers name (e.g. 'BAAI/bge-small-en-v1.5'), or 'ft://latest'. None = keep current. | |
| chat_api_key | No | API key for cloud/proxy APIs. None for local/no-auth. | |
| project_root | No | 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. | |
| chat_api_base | No | Chat API URL. None = use local Ollama for chat. Auto-detects format: :11434 or /api/generate -> Ollama, /v1 or bare host -> OpenAI-compatible. Examples: 'https://api.deepseek.com/v1' (DeepSeek), 'http://localhost:4000' (LiteLLM), 'http://localhost:8080/v1' (llama.cpp). WARNING: external URLs send source code to that host. | |
| chat_api_format | No | Format override: 'ollama' or 'openai'; 'auto' returns to detection from the URL. None = keep current. |
TDQS
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 richly: it discloses the exact write target (local.toml, gitignored, per-developer), what it does NOT touch (global config, shared config.toml), the post-write API test and its skip condition, rollback of local.toml on failure, and that a no-op call returns error and writes nothing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well front-loaded: side-effect scope first, then the compliance warning, then Args and Returns. The Args section is somewhat redundant with the 100%-covered schema, which is the only waste in an otherwise tight structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 9-parameter config-writing tool with no output schema, the description covers side effects, rollback semantics, the post-write test, and a full Returns breakdown, plus a data-security caveat. Nothing needed to call it safely is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The Args section largely restates the schema rather than adding new meaning, though the chat_api_base note and security warning add marginal context. No syntax or format detail beyond what the schema already documents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Configure') and resource ('LLM settings') scoped to the current project. No sibling tool performs configuration, so it is trivially distinguishable from the read/search siblings, and it even names list_projects as a helper.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear routing guidance between project and project_root ('It is an alternative to project_root... Give one of the two, not both') and points to list_projects. It lacks explicit when-not-to-use framing, but the config scope is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
explain_symbolA
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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Symbol name to explain. E.g. 'uart_init', 'ModemMsg::send'. | |
| image | No | 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. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | 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. | |
| context_lines | No | Lines of source context around the symbol definition (1-200). |
TDQS
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.
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.
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.
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.
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.
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.
find_all_callers_recursiveA
Find all transitive C/C++ callers — who calls name, directly or indirectly, through the libclang call graph including function-pointer edges, implicit constructors, and synthetic dispatch edges. libclang-powered: follows function-pointer assignments and ISR vector registrations across the full call tree.
Use for impact analysis: "if I change this function, how far does the
ripple go?" Returns callers at depth 1 (direct), depth 2 (callers of
callers), up to max_depth (default 5). Results are deduplicated —
each caller appears once at its shortest distance to the target.
Edge types traversed: Includes call, indirect (function
pointers / ISRs), implicit_construct (constructors reachable through
file-scope global objects), and dispatch (synthetic edges through
event loops and thread starts).
Limitation — ambiguous name resolution: When a source-line fallback
cannot disambiguate which method is called (e.g. attach() matching
both Timeout::attach and SerialBase::attach), the edge is
conservatively omitted to avoid false callers. If you suspect a
missing caller, verify with search_bodies("target_name") and
find_indirect_targets.
For a flat, single-level caller list use find_callers (faster).
For the reverse direction use find_callees_recursive.
Read-only. No side effects. Requires the reference index
(fw-context index — refs on by default). BFS from the target
outward; performance scales with call-graph fan-out.
Args: name: Symbol name to find transitive callers of. 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. max_depth: Maximum BFS depth for transitive search (default 5). limit: Maximum results (default 50). offset: Skip this many results. Reads the next page of a deep call tree; 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: list of dicts, each with: name (str — the caller), qualified_name (str), kind (str), signature (str), depth (int — distance from the target), file (str — absolute).
This tool gives no line, because one caller can hold several call
sites. For the line of each call use ``find_callers`` on the name
that this tool reports.
When *name* matches more than one symbol, such as two classes with
a method of the same name, the answer holds the callers of all of
them. A ``warning`` dict then comes first and names the symbols,
and each result carries ``target_qualified_name``, which tells the
symbol that it calls. Give the full qualified name to ask about
one symbol only.
The page notice ``{total, offset, shown, more, hint}`` comes
before the rows of the answer. ``total``
counts every row of the whole answer. When ``more`` is true, the
``hint`` names the call that reads the next page. A page after
the last row gives one ``info`` dict that names the total.
Never empty: one dict with ``error`` (cannot resolve) or ``info``
(no results) replaces the results. Check both keys first.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Symbol name to find transitive callers of. | |
| image | No | 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. | |
| limit | No | Maximum results (default 50). | |
| offset | No | Skip this many results. Reads the next page of a deep call tree. | |
| project | No | 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. | |
| variant | No | 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. | |
| max_depth | No | Maximum BFS depth for transitive search (default 5). | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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 richly: read-only/no side effects, dependency on the reference index, BFS traversal with deduplication, the four edge types traversed, and a candid limitation about ambiguous name resolution conservatively omitting edges. It also discloses ambiguous-match warnings, pagination notices, and the never-empty error/info contract.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose, edge types, limitations, and usage are front-loaded and every early sentence earns its place. It is long, and the multi-paragraph Returns block duplicates an output schema that already exists, which keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a recursion/pagination-heavy graph query, the description covers everything an agent needs: traversal semantics, ambiguity behavior, pagination, error/info handling, and build/variant selection. Nothing required for a correct call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all eight parameters; the args block largely restates it. The description adds only marginal nuance (e.g. offset reads the page the notice names, and that one query answers for one build), so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (transitive C/C++ callers via the libclang call graph) and immediately names the sibling tools it is not: find_callers (flat single-level) and find_callees_recursive (reverse direction). An agent can distinguish it from its neighbors 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use (impact analysis: 'if I change this function, how far does the ripple go?'), plus named alternatives with the condition that selects them (find_callers for a flat list; find_callees_recursive for reverse). It also gives a fallback path (search_bodies, find_indirect_targets) when a caller seems missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_callees_recursiveA
Find all transitive C/C++ callees — what name calls, directly or indirectly, through the libclang call graph including function-pointer edges, implicit constructors, and synthetic dispatch edges. libclang-powered: follows function-pointer calls and indirect invocations across the full dependency tree.
Use for dependency analysis: "what does this function depend on to do
its job?" Returns callees at depth 1 (direct), depth 2 (callees of
callees), up to max_depth (default 5). Results are deduplicated
by shortest distance.
Edge types traversed: Includes call, indirect (function
pointers / ISRs), implicit_construct (constructors reachable through
file-scope global objects), and dispatch (synthetic edges through
event loops and thread starts).
Limitation — ambiguous name resolution: When a source-line fallback
cannot disambiguate which method is called, the edge is conservatively
omitted to avoid false callees. If you suspect a missing callee,
verify with search_bodies("target_name").
For direct callees only, get_symbol_context gives a faster flat
list along with the function body and callers. For the reverse
direction use find_all_callers_recursive.
Read-only. No side effects. Requires the reference index
(fw-context index — refs on by default).
Args: name: Symbol name to find transitive callees of. 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. max_depth: Maximum BFS depth for transitive search (default 5). limit: Maximum results (default 50). offset: Skip this many results. Reads the next page of a deep call tree; 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: list of dicts, each with: name (str — the callee), qualified_name (str), kind (str), signature (str), depth (int — distance from the source), file (str — absolute).
This tool gives no line, because one function can call the same
callee several times. For the line of each call use
``find_callers`` on the name that this tool reports.
When *name* matches more than one symbol, the answer holds the
callees of all of them. A ``warning`` dict then comes first and
names the symbols, and each result carries
``target_qualified_name``, which tells the symbol that calls it.
Give the full qualified name to ask about one symbol only.
The page notice ``{total, offset, shown, more, hint}`` comes
before the rows of the answer. ``total``
counts every row of the whole answer. When ``more`` is true, the
``hint`` names the call that reads the next page. A page after
the last row gives one ``info`` dict that names the total.
Never empty: one dict with ``error`` (cannot resolve) or ``info``
(no results) replaces the results. Check both keys first.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Symbol name to find transitive callees of. | |
| image | No | 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. | |
| limit | No | Maximum results (default 50). | |
| offset | No | Skip this many results. Reads the next page of a deep call tree. | |
| project | No | 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. | |
| variant | No | 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. | |
| max_depth | No | Maximum BFS depth for transitive search (default 5). | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so richly: it enumerates the edge types traversed (call, indirect, implicit_construct, dispatch), discloses the ambiguous-name-resolution limitation and the conservative omission behavior, states it is read-only with no side effects, and requires the reference index. It also covers deduplication by shortest distance and pagination.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose and edge-type summary, then organized under clear headers. It is somewhat long, and because an output schema exists the extensive Returns block is partly redundant with the schema, plus the Args section mirrors the schema descriptions — minor duplication keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex graph-traversal tool with 8 parameters, this is complete: it explains the traversal semantics, the multi-symbol matching behavior with target_qualified_name, the never-empty error/info contract, and pagination, all of which an agent needs to invoke and interpret correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the Args block largely restates what the schema already documents (project/project_root mutual exclusion, variant/image build selection, offset paging). It adds only marginal meaning beyond the schema — the rationale that one query answers for ONE build and the offset/page-notice hint — so the high-coverage baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource+scope: 'Find all transitive C/C++ callees — what name calls, directly or indirectly.' It explicitly distinguishes itself from siblings by naming get_symbol_context (direct callees only) and find_all_callers_recursive (reverse direction), 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use framing ('Use for dependency analysis: what does this function depend on to do its job?') and names two concrete alternatives with the conditions that select them — get_symbol_context for a faster flat direct list, find_all_callers_recursive for the reverse direction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_callersA
Find who calls a C/C++ function — direct calls AND indirect via
function pointers, callbacks, and struct/array init lists (such as a
vector table that the build generates in C). libclang-powered: detects
function-pointer assignments that text-based search cannot see.
A slot of an assembly vector table (ref_kind "vector") and an
NVIC_SetVector install ("runtime_vector") are not callers: use
find_references or get_vector_table for those.
Falls back to macro lookup when the symbol is not found as a function/method: returns the macro definition (kind="macro") and files that use it (ref_kind="macro_use").
Use when you need a quick, flat list of immediate callers. For the full
transitive call tree (who calls this indirectly through other functions),
use find_all_callers_recursive. For all references including reads
and member accesses, use find_references. For a path between two
specific symbols, use find_call_path.
Read-only. No side effects. Requires the reference index
(fw-context index — refs are on by default). Only direct call
sites are returned; callers more than one hop away are not included.
Indirect edges (ref_kind: "indirect") are detected when a function
pointer references a function through:
Call arguments:
callback(&Class::method, this),EventQueue::call_every(ms, obj, &handler)Assignments:
driver.onData = &handleData,global_cb = &handlerVariable initializers:
static void (*fp)(int) = &handlerStruct/array init lists:
{.on_data = &handler},{&fn_a, &fn_b}
Args:
name: Symbol name to find callers of. Uses the same three-tier
resolution as find_references (exact name, exact qualified,
suffix LIKE).
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.
limit: Maximum results of one page (default 50, max 200).
offset: Skip this many results. Reads the next page of a symbol
with many call sites; 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 first — total, offset, shown, more
— then a dict per call site with: file, line, ref_kind ("call",
"indirect", "implicit_construct", or "macro_use"),
caller (enclosing function name), caller_kind ("function",
"method", …). Macro fallback puts a dict with kind="macro",
signature (#define free: NAME or NAME(a, b)),
is_function_like, value (the replacement text ALONE) and
expanded_value between the notice and the rows;
that answer pages too, and its total counts the uses in active
code only — a use inside a comment is not one.
When *name* matches more than one symbol, such as two classes with
a method of the same name, the answer holds the call sites of all
of them. A ``warning`` dict then comes first and names the
symbols, and each result carries ``target_qualified_name``. Give
the full qualified name to ask about one symbol only.
A virtual method with no call site of its own answers with the
call sites of its base method and of the other overrides of that
base. A ``warning`` dict leads such an answer, and each row
carries ``recorded_against`` (the symbol the index records the
call against) and ``reaches_this_symbol`` (true for a call on the
base method, which reaches this override at run time; false for a
call on a sibling override, which does not). Read both before you
report a caller count.
Never empty: one dict with ``error`` (symbol not resolved) or
``info`` (no references of this kind). Check both keys first.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Symbol name to find callers of. Returns direct call sites and indirect calls via function pointers. | |
| image | No | 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. | |
| limit | No | Maximum results of one page (default 50, max 200). | |
| offset | No | Skip this many results. Reads the next page of a symbol with many call sites. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and does so thoroughly: read-only, no side effects, requires the reference index, only direct call sites are returned, indirect edge detection is explained with examples, macro fallback behavior is described, and output edge cases such as warnings and never-empty error/info dicts are disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is front-loaded and well organized, but it is very long, and much of the Returns section explains output shape even though an output schema exists. The indirect-edge examples and return-value edge cases are useful, but the description could be trimmed without losing essential selection or invocation information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the absence of annotations, and the presence of a rich output schema, the description is complete enough for correct selection and invocation. It covers indexing prerequisites, build/variant selection, pagination, macro fallback, symbol conflicts, virtual method handling, and error/info return cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline would be 3, but the description adds meaningful semantics beyond the schema: `name` uses the same three-tier resolution as `find_references`, `project` and `project_root` are mutually exclusive alternatives, and `variant`/`image` must match exactly one build as refusal messages list them. These additions help an agent invoke the tool correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: finding who calls a C/C++ function, and explicitly includes direct calls plus indirect calls via function pointers, callbacks, and init lists. It distinguishes itself from siblings such as `find_all_callers_recursive`, `find_references`, and `find_call_path` by name and scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states exactly when to use this tool (a quick, flat list of immediate callers) and when to use alternatives: `find_all_callers_recursive` for transitive call trees, `find_references` for all references including reads, `find_call_path` for a path between two symbols. It also warns that vector-table slots and `NVIC_SetVector` installs are not callers and should be queried with `find_references` or `get_vector_table`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_call_pathA
Find call paths between two C/C++ functions via BFS in the libclang call graph, including function-pointer edges, ISR vector registrations, implicit constructors, and synthetic dispatch edges (event loops, thread starts). libclang-powered: follows function-pointer edges and ISR vector registrations that text-based search cannot resolve.
Use to answer "how does A reach B?" — e.g. tracing how a high-level
event handler eventually calls a low-level driver. Returns up to 5
distinct paths in BFS order (short paths first), each with depth
(edge count) and chain
(e.g. "main → app_run → modem_init").
Edge types traversed: The BFS includes call, indirect
(function pointers / ISRs), implicit_construct (global/static
object constructors), and dispatch (synthetic edges through event
loops like EventQueue::dispatch_forever and thread starts like
Thread::start).
Limitations:
Dispatch bridges: callbacks registered through
EventQueue::call_every,k_work_submit, orxTimerStartreach their dispatch entry point (dispatch_forever,z_work_q_main) through a built-in map for mbed-os, Zephyr, and FreeRTOS. Add other RTOS patterns in[call_graph.dispatch_bridges](.fw-context/config.toml); a bridge whose entry symbol is not in the index is skipped silently.Ambiguous fallback names: for a call that libclang cannot resolve (template-obscured
_timeout.attach(...)), a source-line regex matches the method name. When several methods share that unqualified name and neither the receiver field type nor the caller class disambiguates, fw-context creates NO edge — conservative, to avoid false paths.Global constructors: file-scope
implicit_constructedges hang off a synthetic<global ctors>node betweenmainand every global constructor. Any query that can reachmainuses it, not only a query that starts atmain.
On an empty result that you expected to hold a path: look for async
dispatch (search_bodies("call_every"), search_bodies("attach")),
trace the intermediate symbols with find_callers, raise
max_depth, and check the function-pointer wiring with
find_indirect_call_sites / find_indirect_targets.
For one-sided exploration use find_all_callers_recursive (who reaches
this?) or find_callees_recursive (what does this reach?).
For exact call-graph verification use find_callers or
find_references.
Read-only. No side effects. Requires both symbols to be in the index
and refs enabled (fw-context index — refs on by default).
Args:
from_name: Starting symbol for path search.
to_name: Target symbol to find path to.
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.
max_depth: Maximum BFS depth for path search (default 10). The
search runs from both ends, and each end goes up to
max_depth hops, thus a path can hold up to 2 × max_depth
edges. No clamp holds this number. What bounds a deep search is
the node budget of the walk — 5000 expansions — thus a large
depth gives up on that budget and not on the depth.
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:
At most 5 paths, each a dict with: depth (edge count, int), chain (str —
e.g. "main → app_run → modem_init"), target_usr (str — the USR
of the symbol the path ends at, which tells two overloads apart).
When no path exists within the depth limit, the list holds one
info dict.
The number of paths cannot be counted, thus this tool has no page
notice and no ``offset``. A trailing ``info`` dict says when paths
can be left out: the search found 5 paths and stopped, it spent
its budget of node expansions, or a direct call answered and the
longer paths were not searched. After a spent budget an empty
answer says that a path can still exist, and NOT "no path". The
paths come in a fixed order: the same query gives the same paths.
When *to_name* matches more than one symbol, the search reaches
all of them. A ``warning`` dict then comes first and names the
symbols, and each path carries ``target_qualified_name`` next to
``target_usr``. Give the full qualified name to ask about one
symbol only.
Never empty: one dict with ``error`` (cannot resolve) or ``info``
(no results) replaces the results. Check both keys first.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| project | No | 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. | |
| to_name | Yes | Target symbol to find path to. | |
| variant | No | 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. | |
| from_name | Yes | Starting symbol for path search. | |
| max_depth | No | Maximum BFS depth from each end of the search (default 10). A path can hold up to 2 x max_depth edges. | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden and does: it declares 'Read-only. No side effects,' states the prerequisite ('requires both symbols to be in the index and refs enabled'), and discloses real behavioral limits — the 5000-expansion node budget, the conservative no-edge fallback, the dispatch-bridge map, and the synthetic <global ctors> node.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the one-line purpose and organized under bolded headers (Edge types, Limitations, On an empty result), which keeps a large body navigable. It is longer than strictly necessary, and the Returns section restates much of what the output schema already carries, but the content is dense rather than padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a graph-traversal tool with 7 params, an output schema, and no annotations, the description covers purpose, prerequisites, edge semantics, failure modes, ambiguity handling, and result ordering. An agent has everything needed to invoke it and interpret empty or ambiguous responses correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 semantics beyond the schema: max_depth's bidirectional behavior and the fact that the node budget (not depth) bounds a deep search, plus the project/project_root 'give one, not both' rule and the one-build-per-query constraint on variant/image.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource+mechanism: 'Find call paths between two C/C++ functions via BFS in the libclang call graph,' and explicitly distinguishes itself from text-based search. It also names the siblings it is NOT (find_callers, find_references, find_all_callers_recursive, find_callees_recursive), so an agent can route without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger ('Use to answer "how does A reach B?" — tracing how a high-level event handler calls a low-level driver'), names the alternatives with their distinct purposes ('who reaches this?' vs 'what does this reach?' vs exact verification), and supplies remediation steps for an unexpected empty result.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_dead_codeA
Find C/C++ functions that are defined but never called — libclang-powered dead code detection across the entire indexed codebase. Distinguishes called from uncalled symbols globally, not just within a single file — text-based search cannot determine whether a function is actually reachable.
What "dead" means: zero references of any ref_kind in the
index — no call, no read, no function-pointer use, no vector slot.
Only functions, methods, constructors, and destructors with a
definition are checked. This is a
single-layer reference check, NOT a reachability analysis from the
entry points (main, ISR, exported symbols): a function that only a
second dead function calls still has a reference, thus this tool does
not mark it. For transitive reachability, trace from your entry points
with find_callees_recursive.
The status field splits the results:
"dead"— no reference at all. Likely unused."possibly_dead"— assigned to a function pointer (ref_kind="indirect") and never called directly, but no call site through that pointer resolved. Unindexed code or a type-erased API can still call it. Treat it as uncertain, and check each hit withfind_indirect_targetsbefore you delete anything.
fw-context detects a constructor call through global/static object and
member-field initialization as an implicit_construct reference.
ISRs: a handler that an assembly vector table names (.word) has a
vector reference, and one that NVIC_SetVector installs has a
runtime_vector reference, thus neither is reported. A handler in
a table that the build generates in C has an indirect reference
and can show as possibly_dead. A handler that no readable table
names (a slot with a linker-resolved address; arm64, Xtensa, MIPS
tables of branch instructions) shows as dead. Use
get_vector_table to check.
Other known false positives: constructors from factories, virtual method overrides, and weak-aliased symbols. Always verify before you delete.
project_only=True (default) excludes the SDK and vendor paths
through the is_project column, which follows the vendor_paths
and project_paths config. Set project_only=False to see the
vendor results too. No config default is added to
exclude_paths.
Read-only. No side effects. Requires the reference index
(fw-context index — refs on by default).
Args:
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.
limit: Maximum results of one page (default 100, max 200).
offset: Skip this many results. Reads the next page; the page
notice names the offset to use.
exclude_paths: Additional LIKE patterns to exclude (user-supplied
tool parameter, not config). E.g. ['lib/%'].
project_only: When True (default), filters to is_project = 1
symbols. Set False to see all results.
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 first — total, offset, shown, more
— then a dict per function with: name, qualified_name, kind,
signature, file (str — absolute), line, status ("dead" or
"possibly_dead"), and reason (str — explains why the function
is classified as dead or possibly dead). A "possibly_dead" row
also holds indirect_refs (str — up to 3 file:line pointer
uses, absolute paths, joined with ", "). "dead" rows come
first.
Never empty: one dict with ``error`` or ``info`` replaces an empty
result. Check both keys first.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| limit | No | Maximum results of one page (default 100, max 200). | |
| offset | No | Skip this many results. Reads the next page of a long report. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_only | No | When True (default), keeps only project code (is_project, from the vendor_paths/project_paths config and SDK detection). Set False to see all results. | |
| project_root | No | 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. | |
| exclude_paths | No | LIKE patterns on the project-relative file path to exclude, on top of project_only. E.g. ['lib/%']. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers: it declares 'Read-only. No side effects.', states the index prerequisite, defines exactly what 'dead' means, discloses that this is a single-layer reference check rather than reachability, enumerates known false positives (factories, virtual overrides, weak aliases), and explains ISR/vector-table edge cases. Far beyond what structured fields provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded and the false-positive discussion earns its place, but the Args and Returns sections largely restate the input schema and output schema verbatim, which is redundant given 100% schema coverage and an existing output schema. The prose is also heavily paragraph-bound, so signal is diluted by repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter, index-dependent analysis tool this is thorough: it covers prerequisites, result semantics, pagination via the page notice, the non-empty error/info guarantee, and build-selection requirements. An agent has everything needed to call it correctly and interpret the output.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 real meaning: it clarifies that project_only follows the vendor_paths/project_paths config, that 'No config default is added to exclude_paths', and that a query answers for ONE build so variant/image must be supplied. These are semantic nuances the schema alone does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a precise verb+resource+scope: 'Find C/C++ functions that are defined but never called — libclang-powered dead code detection across the entire indexed codebase.' It explicitly contrasts with text-based search and, through the transitive-reachability note, distinguishes itself from siblings like find_callees_recursive and find_references.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent to alternatives under named conditions: 'For transitive reachability, trace from your entry points with find_callees_recursive', 'check each hit with find_indirect_targets before you delete anything', and 'Use get_vector_table to check'. It also states when project_only should be flipped to False. This is textbook when/when-not/alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_hotspotsA
Find the most-called C/C++ functions ranked by caller count — libclang call-graph hotspot detection. Identifies functions with the most architectural weight — good targets for refactoring, optimization, or extra testing. Text-based search cannot aggregate caller statistics across the full call graph.
Use for high-level impact assessment: changing a hotspot affects many call sites. The result tells you which functions carry the most "architectural weight" across the entire codebase.
By default, SDK/vendor paths are auto-excluded so hotspots reflect
project code. Use project_only=False to see all results including
vendor code.
For the callers of a specific hotspot, follow up with find_callers
or find_all_callers_recursive.
Read-only. No side effects. Requires the reference index
(fw-context index — refs on by default).
Args:
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.
limit: Number of top-called functions per page (default 20, max 50).
offset: Skip this many results. Reads further down the ranking;
the page notice names the offset to use.
project_only: When True (default), filters to is_project = 1
symbols so hotspots reflect project code.
exclude_paths: Additional LIKE patterns to exclude (user-supplied
tool parameter). E.g. ['lib/%'].
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 first — total, offset, shown, more
— then a dict per function with: name, qualified_name, kind,
signature, file (str — absolute), line, caller_count (int — number
of call and indirect references to it).
Never empty: one dict with ``error`` or ``info`` replaces an empty
result. Check both keys first.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| limit | No | Number of top-called functions per page (default 20, max 50). | |
| offset | No | Skip this many results. Reads further down the ranking. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_only | No | When True (default), auto-excludes SDK/vendor paths so hotspots reflect project code. | |
| project_root | No | 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. | |
| exclude_paths | No | LIKE patterns on the project-relative file path to exclude, on top of project_only. E.g. ['lib/%']. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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: it declares the tool read-only with no side effects, discloses the prerequisite reference index ('refs on by default'), documents the default SDK/vendor auto-exclusion and how project_only=False overrides it, and warns that results are never empty but may contain error/info keys to check first.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well structured and front-loaded: purpose, then when-to-use, then behavior, then args, then returns. Slightly padded by repetition of the 'architectural weight' framing, which is used twice, but no sentence is pure noise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 8 all-optional parameters, a prerequisite index, and a multi-build variant/image selection model, the description covers everything an agent needs to call it correctly, plus pagination and the error/info fallback contract. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is already 100%, so the baseline is 3; the description still adds value by clarifying cross-parameter intent — project vs project_root as mutually exclusive alternatives ('give one of the two, not both') and offset semantics tied to the page notice 'the offset to use'. It does not add format or syntax detail beyond what the schema already supplies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('find the most-called C/C++ functions ranked by caller count') with implementation detail (libclang call-graph), and explicitly contrasts itself with sibling lookups ('For the callers of a specific hotspot, follow up with find_callers'). An agent can distinguish it from find_callers/find_all_callers_recursive 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ('Use for high-level impact assessment: changing a hotspot affects many call sites'), names the alternatives for the natural follow-up question, and states the capability boundary ('Text-based search cannot aggregate caller statistics across the full call graph').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_indirect_call_sitesA
Find indirect call sites where a C/C++ function pointer field or
variable is invoked. libclang-powered: resolves calls through
function pointers (e.g. driver.onData(buf, len)), which
text-based search cannot detect.
Returns locations where a function pointer is called through a field
access (driver.onData(buf, len)) or variable dereference
(stored_callback(42)).
Read-only. No side effects. Use this to answer "where is this function
pointer invoked?" as opposed to find_callers which answers "who
calls this function?" and find_references which answers "where is
this symbol read or assigned?"
For the reverse query — which functions are assigned to a given field
or parameter — use find_indirect_targets.
Requires the reference index (fw-context index — refs on by default).
Args:
name: Name of the function pointer field or variable.
E.g. "onData" finds every call through a field named
onData. Uses three-tier resolution: exact name, exact
qualified, suffix LIKE; a function pointer parameter matches
by its exact name.
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.
limit: Maximum results (default 50, max 200).
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:
list of dicts, each with: file, line, expr_text (the callee
expression, e.g. "driver.onData"), target_usr, target_name,
fn_ptr_type (the function pointer type signature), caller
(enclosing function name), caller_kind.
The page notice ``{total, offset, shown, more, hint}`` comes
before the rows of the answer. ``total`` counts every row of the whole answer. When
``more`` is true, the ``hint`` names the call that reads the next
page. A page after the last row gives one ``info`` dict that
names the total.
Never empty: one dict with ``error`` (cannot resolve) or ``info``
(no results) replaces the results. Check both keys first.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Name of the function pointer field or variable to find call sites of. E.g. 'onData' finds all calls through Driver::onData. | |
| image | No | 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. | |
| limit | No | Maximum results (default 50, max 200). | |
| offset | No | Skip this many results. Reads the next page of a long answer. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | Project root directory. 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
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so: it declares 'Read-only. No side effects.', states the prerequisite ('Requires the reference index (fw-context index — refs on by default)'), and discloses output behavior including the page notice and the never-empty error/info fallback. This is unusually complete disclosure for an unannotated read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The opening is front-loaded with purpose and sibling differentiation, and the Args/Returns sections are cleanly delineated. However, the Args block and the Returns block substantially duplicate the input schema and the existing output schema, so some sentences do not add new information even though the overall structure is disciplined.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, multi-build-aware query tool, the description covers purpose, alternatives, prerequisites, parameter resolution, pagination, and error handling. An agent has everything needed to decide to call it and to interpret the response, even though an output schema already exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 real meaning beyond the schema for `name` by spelling out three-tier resolution (exact name, exact qualified, suffix LIKE) and how function-pointer parameters match, which the schema does not state. The project/variant/image guidance largely restates schema text, so it is not a full 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Find indirect call sites where a C/C++ function pointer field or variable is invoked') and immediately explains the mechanism ('libclang-powered: resolves calls through function pointers... which text-based search cannot detect'). It explicitly separates itself from find_callers, find_references, and find_indirect_targets, so an agent can route correctly 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use framing via contrasting questions: this tool answers 'where is this function pointer invoked?' versus find_callers ('who calls this function?') and find_references ('where is this symbol read or assigned?'), and points to find_indirect_targets for the reverse query. Alternatives and their selecting conditions are named, not implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_indirect_targetsA
Find functions assigned to a C/C++ function pointer field or variable. libclang-powered: links assignment sites to call sites via the field's unique symbol reference, which text-based search cannot resolve.
Links assignment sites (driver.onData = &handler) to call
sites (driver.onData(buf, len)) via the field's USR.
Returns each function that could be invoked through the named function
pointer, showing both the assignment location and the call site(s).
When a function is assigned but no call site is found, call_file
and call_line are null — the assignment exists but the
invocation may be in unindexed code.
For the reverse query — where is this field or parameter called — use
find_indirect_call_sites.
Read-only. No side effects. Requires the reference index
(fw-context index — refs on by default).
Args:
name: Name of the function pointer field, variable, or parameter.
E.g. "onData" finds every function assigned to a field
named onData. Matches the pointer by exact name, exact
qualified name, or ::name suffix. It also matches the
ASSIGNED function by exact name or substring, thus a row can be
an assignment of a function whose name holds name.
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.
limit: Maximum results (default 50, max 200).
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: list of dicts, each with: rhs_name (assigned function), rhs_qname, fn_ptr_type, method (assignment/call_arg/var_init/ init_list), assign_file, assign_line, assign_caller, call_file, call_line, call_expr_text.
An entry can carry ``_note`` (str) when the callee is
template-obscured: the call site is then missing, or comes from
the type-based fallback. ``_note`` also marks a call site that
the ``fn_ptr_type`` fallback found: a call through another pointer
of the same type. A ``call_expr_text`` of ``"<inferred via
class hierarchy>"`` marks a call site that a fallback found, not
the field's USR. Read both before you act on ``call_file`` and
``call_line``.
The page notice ``{total, offset, shown, more, hint}`` comes
before the rows of the answer. ``total`` counts every row of the whole answer. When
``more`` is true, the ``hint`` names the call that reads the next
page. A page after the last row gives one ``info`` dict that
names the total.
Never empty: one dict with ``error`` (cannot resolve) or ``info``
(no results) replaces the results. Check both keys first.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Name of the function pointer field, variable, or parameter. E.g. 'onData' — returns functions assigned to Driver::onData. | |
| image | No | 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. | |
| limit | No | Maximum results (default 50, max 200). | |
| offset | No | Skip this many results. Reads the next page of a long answer. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so richly: 'Read-only. No side effects.', the index requirement, the null call_file/call_line case for unindexed code, the `_note` fallback semantics, the `<inferred via class hierarchy>` marker, and the error/info fallback dicts. This is far beyond what the schema conveys.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Content is front-loaded and each major section earns its place, but the Args entries for limit, offset, project, variant, and image repeat their schema descriptions nearly verbatim, which is redundant padding rather than added value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-param, index-dependent, paginated query tool, the description covers resolution rules, fallback markers, pagination, empty/error returns, and prerequisites. An agent has everything needed to call it correctly, and the output schema's existence is respected by not over-explaining the row shape.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 real meaning: `name` matches by exact name, qualified name, `::name` suffix, and also matches the assigned function by name/substring; `project` vs `project_root` are stated as mutually exclusive alternatives. The remaining params (limit, offset, variant, image) are largely restated from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb+resource ('Find functions assigned to a C/C++ function pointer field or variable') and immediately distinguishes itself from the sibling `find_indirect_call_sites` by explaining the direction of the query. An agent can identify the tool without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly names the reverse-query alternative (`find_indirect_call_sites`) and the condition that selects it, plus states the prerequisite (the reference index, `fw-context index`). When-to-use and when-not-to-use are both covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_referencesA
Find ALL references to a C/C++ symbol — calls, reads, member accesses,
function pointer registrations, vector table slots, and macro
usages. libclang-powered: detects function-pointer registrations
(vector table entries, callback attachments, NVIC_SetVector
installs) that text-based search cannot see.
Falls back to macro lookup when the symbol is not found as a function/method: returns the macro definition (kind="macro") and files that reference it (ref_kind="macro_use").
Read-only. No side effects. Returns every reference in the indexed codebase,
including call sites, variable reads, struct member accesses, indirect
function-pointer references, and macro usages. Requires the reference
index (fw-context index — refs on by default).
For direct callers only use find_callers. For transitive callers use
find_all_callers_recursive. For call paths between two symbols use
find_call_path.
Args: name: Symbol name to find all references of. 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. limit: Maximum results of one page (default 50, max 200). offset: Skip this many results. Reads the next page of a symbol with many references; 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 first — total, offset, shown, more
— then a dict per reference with: file, line, ref_kind, caller,
caller_kind.
ref_kind is one of: "call", "ref", "member",
"indirect" (function-pointer reference in arguments, assignments,
initializers, or init lists), "implicit_construct" (implicit
constructor call from global/static object or member-field
initialization), "dispatch" (synthetic edge from a dispatch
bridge such as EventQueue::call_every), "vector" (a slot of
an assembly vector table names the symbol; file and line are the
table entry), "vector_data" (a slot holds an address computed
from the symbol, such as the initial stack pointer),
"runtime_vector" (an NVIC_SetVector call installs the
symbol at run time), "alias" (.thumb_set: another assembly
name for the symbol), "macro_use" (macro usage
in file). Macro fallback puts a dict with kind="macro",
signature (NAME or NAME(a, b)), is_function_like,
value (the replacement text ALONE) and expanded_value
between the notice and the rows;
that answer pages too, and its total counts the uses in active
code only — a use inside a comment is not one.
When *name* matches more than one symbol, the answer holds the
references of all of them. A ``warning`` dict then comes first and
names the symbols, and each result carries
``target_qualified_name``. Give the full qualified name to ask
about one symbol only.
A virtual method with no reference of its own answers with the
references of its base method and of the other overrides of that
base. A ``warning`` dict leads such an answer, and each row
carries ``recorded_against`` and ``reaches_this_symbol`` (true only
for a row on the base method), as in ``find_callers``. Read both
before you report a reference count.
Never empty: one dict with ``error`` (symbol not resolved) or
``info`` (no references). Check both keys first.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Symbol name to find all references of — calls, reads, member accesses. | |
| image | No | 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. | |
| limit | No | Maximum results of one page (default 50, max 200). | |
| offset | No | Skip this many results. Reads the next page of a symbol with many references. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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, index dependency, macro-fallback behavior when the symbol is not a function, multi-match ambiguity warnings, virtual-method base/override attribution, and the never-empty error/info contract. This is unusually rich behavioral disclosure for a mutation-free read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and clearly sectioned (purpose, Args, Returns), but the Returns block is very long and largely redundant given the tool has an output schema, and the Args block repeats the schema descriptions nearly verbatim. The core routing guidance is only three sentences; the rest is bulk.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a 7-parameter tool with build/variant selection, an index prerequisite, and non-obvious result shapes, the description covers every decision an agent must make before calling: index state, build arguments, pagination, symbol ambiguity, and error handling. An output schema exists, so the return detail is surplus rather than a gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 goes beyond restating fields by explaining the interplay between project/project_root (mutually exclusive), and that variant/image select ONE build that fw-context will not choose for you, plus pagination semantics via offset. These relationships are hard to infer from the flat schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Find ALL references to a C/C++ symbol') and enumerates the reference categories it covers. It explicitly distinguishes itself from text-based search ('that text-based search cannot see') and names the sibling tools it is not (find_callers, find_all_callers_recursive, find_call_path).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing rules: 'For direct callers only use find_callers. For transitive callers use find_all_callers_recursive. For call paths between two symbols use find_call_path.' It also states the prerequisite ('Requires the reference index (fw-context index — refs on by default)') and the project vs project_root choice ('Give one of the two, not both').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_variablesA
Find C/C++ variables by name or part of it and trace who reads or
writes them through the call graph. libclang-powered: splits
variables into global (varglobal — file/namespace/class-scope)
and local (varlocal — inside a function body).
Each result includes a type signature (bool timeSet,
const IPAddress modbus_ip), the enclosing function for locals
("<file scope>" for globals), and a references list of the
functions that read or write the variable — the same ref_kind
values as find_references ("call", "ref", "member").
The list is capped at 30 per variable, and holds only references of
the selected build; references_total gives the whole count. Only
definitions are returned, globals first, then by name.
Use when you need to understand shared state, find who modifies a
global variable, trace side effects, or distinguish important globals
from loop counters. For general symbol search use search_code or
lookup_symbol. For all references to a specific variable
(including reads in expressions), use find_references.
This tool is the way to a LOCAL variable: search_code drops the
varlocal kind, because a local matches every topic query aimed at
the function around it. search_code(..., kind="varlocal") reaches
them as well.
Legacy indexes with kind="variable" (pre-split) are detected and
included in results — reindex to fully benefit from the split.
Read-only. No side effects.
Args:
name: Variable name or part of it. Substring match on name and
qualified name (e.g. g_ finds g_debug_level, g_state).
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.
kind: Optional kind filter — "varglobal", "varlocal",
"field", or None (all). Default None. The legacy
"variable" is also accepted, for an index made before the
kind was split.
limit: Maximum results (default 20, max 100).
offset: Skip this many variables. 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:
list of dicts, each with: name (str), qualified_name (str),
kind (str — "varglobal", "varlocal", "field", or
"variable" on an index made before the kind was split),
file (str),
line (int), signature (str — e.g. "const IPAddress modbus_ip"),
enclosing_function (str — function name for varlocal,
"<file scope>" for varglobal), enclosing_class (str — class
or struct name for fields and static members, empty otherwise),
references (list[dict] — function, file, line,
ref_kind; at most 30), references_total (int — every
reference of the variable). When the list is cut,
references_hint names the find_references call that
lists them all.
The page notice ``{total, offset, shown, more, hint}`` comes
before the rows of the answer. ``total`` counts every variable that matches. When
``more`` is true, the ``hint`` names the call that reads the next
page. A page after the last variable gives one ``info`` dict that
names the total.
No match gives ``[]``. One dict with ``error`` means the query
failed — check that key first.
A ``warning`` dict that comes first means that indexed files
changed after the last index run: the results can be out of date.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Filter by kind: 'varglobal', 'varlocal', 'field', legacy 'variable', or None for all. | |
| name | Yes | Variable name or part of it. Substring match on name and qualified name (e.g. 'g_' finds g_debug_level, g_state). | |
| image | No | 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. | |
| limit | No | Maximum results (default 20, max 100). | |
| offset | No | Skip this many variables. Reads the next page of a name that many variables share. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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 it delivers: read-only/no side effects, a 30-reference cap with references_total and a hint to find_references, result ordering (definitions only, globals first), build-scoped results ('one query answers for ONE build'), legacy-index handling, plus explicit error/warning/empty response shapes. This is unusually complete behavioral disclosure for a tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well organized and front-loaded with purpose and routing, but the trailing Args and Returns blocks substantially duplicate the input schema and the output schema, and the Returns section runs long for a tool that already publishes a structured return. Several sentences repeat points made earlier (the varlocal/search_code caveat).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter tool spanning build selection (variant/image), pagination, index states, and partial-failure responses, the description covers everything an agent needs to call it correctly and interpret the result, and it correctly defers return-value detail where an output schema exists while still explaining the cap and page notice.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and each parameter already carries a description, so the schema does the heavy lifting and a 3 is the baseline. The prose largely restates schema text (substring matching, limit/offset, project vs project_root), adding little beyond the mutual-exclusion note already present in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Find C/C++ variables by name or part of it and trace who reads or writes them through the call graph') and immediately distinguishes itself from search_code, lookup_symbol, and find_references by naming the conditions that select each. The global/local split adds precision about what is actually searched.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly enumerates the situations this tool serves ('understand shared state, find who modifies a global variable, trace side effects') and routes the agent to alternatives for the adjacent cases ('For general symbol search use search_code or lookup_symbol', 'For all references to a specific variable ... use find_references'). It also flags the local-variable gap in search_code, which is a routing rule, not just a fact.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_wrapper_callersA
Find C/C++ wrapper classes that call methods of a driver class —
libclang-powered adapter pattern detection. Traces method ownership
across class boundaries to reveal the wrapper/adapter architecture
(e.g. UART wraps UART_DRIVER). Text-based search cannot
distinguish which class owns each method call.
Returns wrapper methods grouped by wrapper class, showing which driver
methods each wrapper calls. Useful for understanding the adapter/wrapper
architecture (e.g. UART wraps UART_DRIVER).
For the reverse perspective — finding who calls a specific driver method
— use find_callers. For class member listing use
get_class_members.
Read-only. No side effects. Requires the reference index
(fw-context index — refs on by default).
Args:
class_name: Driver class name to find wrappers for.
E.g. 'UART_DRIVER' or 'hal::UART_DRIVER'. The name
is case-sensitive. A bare name that names no top-level class
matches the class of that name in each namespace, but not a
class whose name only ends with it. The methods of a class
nested in the driver class count as driver methods.
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.
limit: Maximum wrapper classes on one page (default 20, max 100).
Each class comes with all of its methods and calls into the
driver (call and indirect references), thus a class is
never split over two pages.
offset: Skip this many wrapper classes. 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:
list of dicts, each with: wrapper_class (str — "(global)" for a
free function), method_count (int),
methods (list of dicts — each with method, qualified_name, kind,
file (str — absolute path of the file that holds the body of that
method), and calls (list of dicts — driver_method (str) and
line (int) of each call into the driver))).
The path sits on the method, not on the class, because one wrapper
class often spans several files.
The page notice ``{total, offset, shown, more, hint}`` comes
before the rows of the answer: ``total`` counts every wrapper class. A page after the last
class gives one ``info`` dict that names the total.
Never empty: one dict with ``error`` (cannot resolve) or ``info``
(no results) replaces the results. Check both keys first.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| limit | No | Maximum wrapper classes on one page (default 20, max 100). | |
| offset | No | Skip this many wrapper classes. Reads the next page. | |
| project | No | 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. | |
| variant | No | 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. | |
| class_name | Yes | Driver class name to find wrappers for. E.g. 'UART_DRIVER' or 'hal::UART_DRIVER'. Case-sensitive. | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so: it states 'Read-only. No side effects.' and the index prerequisite, plus non-obvious behaviors like the never-empty contract ('one dict with error or info replaces the results. Check both keys first') and the pagination/offset notice semantics. This is disclosure well beyond what any structured field supplies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded correctly (verb+resource first), but it repeats itself: the 'UART wraps UART_DRIVER' example appears twice, and the entire Args and Returns sections largely restate the input schema and the (present) output schema. Several sentences do not earn their place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter, multi-build, index-dependent query tool, the description covers preconditions, pagination, error/info fallbacks, and build scoping. Since an output schema exists, the Returns prose is redundant but harmless; nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 substantial meaning the schema lacks: class_name case-sensitivity and bare-name namespace matching rules, that nested-class methods count as driver methods, that limit keeps a class intact on one page, and how variant/image interact with multi-build projects. This meaningfully exceeds the schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb and resource ('Find C/C++ wrapper classes that call methods of a driver class') with the implementation backing ('libclang-powered adapter pattern detection'). It also explicitly distinguishes itself from siblings by naming the tools that cover the reverse and adjacent perspectives (find_callers, get_class_members).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing: 'For the reverse perspective — finding who calls a specific driver method — use find_callers. For class member listing use get_class_members.' It also states the precondition ('Requires the reference index') and the build-selection constraint (one query answers for ONE build), 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.
get_build_infoA
Return the detail of ONE build: its identity, its health, its memory map and its defines.
Read-only with the two exceptions that get_project_status also
has: it removes the marker of a missing build when it finds that build
again, and a reindex.pid or a reindex.pending of a process that
no longer runs. It spawns no subprocess. 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. get_project_status lists
the builds in builds. Without the arguments the answer is an
error that lists the builds. A project of one build
needs no selector.
The health fields (status, reindex_state, reindex_needed, reindex_reasons,
index_message, modified_files_count and the others) have the
meaning that get_project_status gives them, for this build only.
The version fields (update_notice, a restart after an upgrade) are
in get_project_status.
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). A name that the link command defines
with --defsym counts as a number: the STM32 Arduino core writes
LENGTH = LD_MAX_DATA_SIZE and gets length_value 98304. The end
of a region is origin_value + length_value.
memory is empty for a build system that records no linker script,
such as Keil or IAR. A PlatformIO project records its link only in
fw-context index --build: SCons writes no file with the link
command, thus the build asks pio run -t envdump. An empty list for
PlatformIO means that no build recorded the link yet, and
fw-context index --build is the step. An empty list means "not
recorded", never "no memory".
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 are in all 881 units and 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.
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. 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. fast: When True (default), the header check reuses the cached manifest hashes. False recomputes them.
Returns:
dict: {variant, image, board, config_hash, project_id, project_root,
build_system, compile_commands, indexed_at (str — UTC),
first_indexed_at, symbol_count, file_count, reference_count,
modified_files_count, header_affected_tus, manifest_verification,
analysis, description, vendor_paths, 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), status, reindex_state (str or None — see get_project_status),
reindex_needed, reindex_reasons, stale,
index_message, entry_point (str — the ENTRY() of the linker
script of the build, empty when no script names one), memory
(list[dict] — the MEMORY regions of the build: {name, attributes,
origin, length, origin_value, length_value, file_path, line}),
defines (dict — the -D flags of the build), defines_varying
(int), bg_reindex_running (bool), reindex_progress (str or None),
vec_available (bool), vec_error (str, optional), _warning (str,
optional), client_restart_required (bool, optional),
client_restart_reason (str, optional)}
A refusal of the selector, or an index with no build config, gives
a dict that holds ``error`` alone. A project that is not
initialized, that has no index, or whose config file cannot be used
(``"config_error"``) gets the answer of ``get_project_status``.
``config_warnings`` (a list) comes as in ``get_project_status``.
| Name | Required | Description | Default |
|---|---|---|---|
| fast | No | When True (default), reuse the cached manifest hashes for the header check. Pass False to recompute them, which is far slower. | |
| image | No | 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. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | 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. |
TDQS
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 thoroughly: it states the read-only exceptions, that no subprocess is spawned, how missing-build markers are cleaned up, and what an empty `memory` list means. It also explains cached manifest behavior for `fast=False` and error/refusal responses.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded and the Args/Returns sections are structured, but the description is heavily overlong for an invocation reference. Worked examples about Mbed, Zephyr, STM32, `--defsym`, and unit counts consume substantial space without improving tool selection or invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex build-inspection tool with no output schema and no annotations, the description is complete: it documents return fields, selector errors, side effects, and edge-case meanings for `memory` and `defines`. An agent has enough context to call it correctly and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters. The description repeats selector behavior and argument usage, but adds little parameter meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Return the detail of ONE build: its identity, its health, its memory map and its defines.' It clearly distinguishes this build-level detail from `get_project_status`, which lists builds and carries project-level version fields.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete selector guidance for multi-build projects and notes that `get_project_status` lists the builds, while a one-build project needs no selector. It also points version fields to `get_project_status`, but it does not explicitly frame a concise use-this-vs-that rule beyond the build-level scope.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_class_membersA
Return all methods, fields, and nested types of a C/C++ class/struct — libclang-powered member table. Groups members by kind (method, constructor, field, enum, etc.), distinguishing class members from free functions across the entire codebase.
Members are grouped by kind (method, constructor, destructor, field, enum, typedef, class, struct). Each member includes its signature, virtual flags, and source line. Works for C structs too — they just won't have methods.
For inheritance hierarchy use get_inheritance_chain. For individual
method details use get_symbol_context.
Read-only. No side effects.
Args:
class_name: Class or struct name. E.g. 'ModemManager' or
'comm::MODEM'.
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.
limit: Maximum members on one page (default 200, max 500).
offset: Skip this many members. Reads the next page; page
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: dict: {name, qualified_name, kind, file, line, members: {kind: [{name, qualified_name, signature, is_virtual, is_pure_virtual, line}]}, member_count (int — every member), page}
``page`` is the page notice ``{total, offset, shown, more,
hint}``. A page holds the members in the order kind, name and
line, and groups them by kind after the cut, thus one kind can go
on on the next page. A page after the last member gives one
``info`` dict that names the total.
When a file of the answer changed after the last index run, the
dict adds ``stale`` (True) and ``stale_warning`` (str).
On failure the dict holds ``error`` with the reason.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| limit | No | Maximum members on one page (default 200, max 500). | |
| offset | No | Skip this many members. Reads the next page of a large class. | |
| project | No | 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. | |
| variant | No | 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. | |
| class_name | Yes | Class or struct name. E.g. 'ModemManager' or 'comm::MODEM'. | |
| project_root | No | 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. |
TDQS
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 it does disclose a lot: 'Read-only. No side effects.', the stale/stale_warning behavior when a file changed after indexing, the error dict on failure, and the pagination continuation semantics. It does not, however, state prerequisites such as whether a fresh index or permissions are required, so it falls just short of fully covering a zero-annotation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded, but the prose is repetitive: members-by-kind grouping is stated twice ('method, constructor, field, enum, etc.' then again with the full list), and the Args section largely restates the schema. Awkward phrasing ('one kind can go on on the next page') adds length without clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description fully compensates by documenting the return dict shape, the nested members structure, the member_count total, the page notice dict, the stale-warning fields, and the error case. Nothing needed to interpret the result is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline would be 3, but the description adds real meaning: 'page' names the offset to use, project is an alternative to project_root and 'give one of the two, not both', and variant/image must match one build. These clarifications exceed what the schema text alone conveys.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: it returns methods, fields, and nested types of a C/C++ class/struct, via libclang. It explicitly distinguishes itself from siblings by naming get_inheritance_chain for hierarchies and get_symbol_context for individual method details, so an agent can route without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit alternatives and the conditions that select them: 'For inheritance hierarchy use get_inheritance_chain' and 'For individual method details use get_symbol_context.' It also explains the project/project_root and variant/image selection rules, including that one query answers for ONE build.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_file_mapA
Fast structural map of all C/C++ symbols in a file grouped by kind — libclang-powered table of contents. Like a table of contents before reading a chapter: see what functions, classes, and enums a file defines at a glance.
The index decides which file a path may reach: a path that no file of this build answers for is refused, and a header of the SDK that the build compiles is reachable like any file of the application.
Pass a path relative to the project root (src/main.cpp) or just the
filename (main.cpp). The exact path wins; else the path matches
whole trailing path segments (config.h matches src/config.h,
not hw_config.h), a project file before a vendor file, then the
shortest path. Returns symbols keyed by kind (function, method,
class, struct, enum, ...). Each kind has count (total) and items (first N,
default 30). Set max_per_kind=0 for unlimited, signatures=true for full sigs.
Enum constants (enum_constant) are grouped into subgroups by
parent enum. Each subgroup has name, count, and constants
(list of {name, qualified_name, line, enum_value}). The subgroup
count reflects the real total even when max_per_kind limits the
constants list.
For detailed symbol information use get_symbol_context or
lookup_symbol.
Read-only. No side effects. Use before reading a large file to orient yourself — see what functions, classes, and enums it defines.
Args:
file_path: Path relative to project root, or just the filename.
project_root: Project 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.
signatures: Include full function signatures. Default: False.
max_per_kind: Max items per kind group (default 30, 0 = unlimited).
With kind, the size of the page.
kind: One symbol kind, for example "function" or
"enum_constant". Gives one page of the items of that kind
instead of the map.
offset: With kind: skip this many items of that kind. Reads
the next page; page 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: dict: {file, total_symbols, symbols: {kind: {count, items[], subgroups?[]}}}
Each item holds ``name``, ``qualified_name``, and ``line``, plus
``end_line`` when the symbol is a definition. The two line numbers
are the extent, thus ``file:line-end_line`` is the citation. A
group that ``max_per_kind`` cut holds ``hint``, the call that pages
its items.
With ``kind``: {file, kind, count, items[], page}, where ``items``
is one flat page of that kind, enum constants too, and ``page`` is
the page notice ``{total, offset, shown, more, hint}``. A page
after the last item gives one ``info`` dict that names the total.
When the file changed after the last index run, the dict adds
``stale`` (True) and ``stale_warning`` (str).
On failure the dict holds ``error`` with the reason (plus the stale
keys when indexed files changed).
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | One symbol kind, e.g. 'function' or 'enum_constant'. Gives one page of the items of that kind. | |
| image | No | 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. | |
| offset | No | With kind: skip this many items of that kind. Reads the next page. | |
| project | No | 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. | |
| variant | No | 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. | |
| file_path | Yes | Path to source file — relative to project root or just filename. | |
| signatures | No | Include full function signatures in output. | |
| max_per_kind | No | Max items per symbol kind group (default 30, 0 = unlimited). With kind, the size of the page. | |
| project_root | No | 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. |
TDQS
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 thoroughly: read-only/no side effects, the index's reachability/refusal rule, the path-matching precedence algorithm, stale-file detection with stale/stale_warning keys, and error-dict behavior. This is far more than the structured fields convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well front-loaded with purpose first, then path rules, then returns. The Returns block is justified since no output schema exists, but the Args block largely duplicates the 100%-covered schema, adding some redundancy to an otherwise disciplined structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter tool with no output schema and no annotations, the description supplies the missing return shape, pagination mechanics, build-selection requirements, and failure modes. An agent has everything needed to invoke and interpret results correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 real meaning: exact-path-wins matching with whole-trailing-segment fallback, project-vs-project_root mutual exclusivity ('Give one of the two, not both'), and how variant/image select one build. It stops short of fully documenting offset/page interplay beyond what the schema states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Fast structural map of all C/C++ symbols in a file grouped by kind'), reinforced by the concrete 'table of contents' analogy. It explicitly distinguishes itself from detail-oriented siblings by naming get_symbol_context and lookup_symbol. An agent can select it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: 'Use before reading a large file to orient yourself' and 'For detailed symbol information use get_symbol_context or lookup_symbol.' It also explains when to use project vs project_root and to call list_projects for names. Both when-to-use and alternatives are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_inheritance_chainA
Return the C++ inheritance chain for a class or struct — libclang-aware hierarchy. Resolves base/derived class relationships across all translation units, which single-file reading cannot do.
Shows direct base classes (what this inherits from) and direct derived classes (what inherits from this), along with access level and virtual flag for each edge.
When transitive=True, walks the full hierarchy up to all ancestors
and down to all descendants (bounded by max_depth). Uses BFS with
cycle detection to handle diamond inheritance.
For class members use get_class_members. For virtual method
override chains use get_method_overrides.
Read-only. No side effects.
Args:
class_name: Class or struct name to get inheritance information for.
E.g. 'UART_DRIVER' or 'comm::MODEM'.
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.
transitive: When True, walk the full inheritance tree both up
(ancestors) and down (descendants). Default: False (direct
bases and derived only).
max_depth: Maximum BFS depth for transitive walk (default 10).
The schema holds it between 1 and 50, thus a number outside
that range is REFUSED and not cut down to fit.
limit: Maximum classes in all_bases and in all_derived on
one page (default 100, max 500). Only with transitive=True.
offset: Skip this many classes in all_bases and in
all_derived. One offset pages the two lists together.
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, qualified_name, kind, file, line, bases: [{name, usr, access, is_virtual, file}], derived: [{name, usr, access, is_virtual, file}], all_bases: [{name, usr, access, is_virtual, depth, file, kind}] (when transitive=True, ancestors sorted by depth, then name), all_derived: [...] (when transitive=True, descendants, same shape) }
With ``transitive=True`` each of the two lists is one page, and
``all_bases_page`` and ``all_derived_page`` hold its page notice
``{total, offset, shown, more, hint}``. A hierarchy below a root
class of a framework can hold thousands of classes.
When a file of the answer changed after the last index run, the
dict adds ``stale`` (True) and ``stale_warning`` (str).
On failure the dict holds ``error`` with the reason.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| limit | No | Maximum classes in all_bases and in all_derived on one page (default 100, max 500). Only with transitive=True. | |
| offset | No | Skip this many classes in all_bases and in all_derived. Reads the next page of a large hierarchy. Only with transitive=True. | |
| project | No | 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. | |
| variant | No | 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. | |
| max_depth | No | Maximum BFS depth for transitive walk (default 10). | |
| class_name | Yes | Class or struct name to get inheritance information for. E.g. 'UART_DRIVER' or 'comm::MODEM'. | |
| transitive | No | When True, walk the full inheritance tree both up (ancestors) and down (descendants). Default: False (direct bases and derived only). | |
| project_root | No | 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. |
TDQS
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 well: it discloses cross-translation-unit resolution, BFS with cycle detection to survive diamond inheritance, that out-of-range max_depth is REFUSED rather than clamped, that paging uses combined offset across two lists, that stale/stale_warning appear when files changed post-index, and that errors surface in an 'error' key. It also declares 'Read-only. No side effects.'
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and routing sentences are front-loaded and earned, but the Args block largely duplicates parameter descriptions already at 100% schema coverage, and the Returns block enumerates output keys at length. The result is longer than it needs to be given the structured data already present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations and no output schema, the description supplies everything an agent needs: return shape including the transitive-only all_bases/all_derived lists, page notice fields, staleness warnings, and the failure shape. For a 9-parameter, paged, cross-file tool this is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 and most Args text restates the schema. It nonetheless adds genuine semantic details beyond the schema, notably that max_depth values outside 1–50 are refused rather than truncated, and that project_root also accepts a project name/id while project is the clearer field for that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (return the C++ inheritance chain for a class or struct) and immediately qualifies scope with 'libclang-aware hierarchy' resolved across all translation units. It explicitly distinguishes itself from get_class_members and get_method_overrides, 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit alternatives ('For class members use get_class_members. For virtual method override chains use get_method_overrides') and a conditional usage rule for transitive=True vs the default direct-only mode. It also advises when each project/variant/image argument is needed, covering when-to-use rather than leaving it to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_method_overridesA
Return C++ virtual method override information — libclang-powered vtable analysis. Resolves virtual dispatch across class hierarchies: shows which base-class method this overrides, and which derived-class methods override this one. Text-based search cannot resolve virtual dispatch across translation units.
Shows what base-class method this method overrides, and what derived-class
methods override this one. Built from the overrides table which is
populated during fw-context index via post-processing of the inheritance
graph and virtual method signatures.
For class-level inheritance, use get_inheritance_chain. For symbol
details, use get_symbol_context.
Read-only. No side effects.
Args:
method_name: Method name to get override information for. Use
qualified name for disambiguation, e.g.
'UART_DRIVER::write'.
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.
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, qualified_name, kind, file, line, signature, overrides: [{usr, name, qualified_name, kind, file, line}], overridden_by: [{usr, name, qualified_name, kind, file, line}] }
When a file of the answer changed after the last index run, the
dict adds ``stale`` (True) and ``stale_warning`` (str).
On failure the dict holds ``error`` with the reason.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| project | No | 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. | |
| variant | No | 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. | |
| method_name | Yes | Method name to get override information for. Use qualified name for disambiguation, e.g. 'UART_DRIVER::write'. | |
| project_root | No | 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. |
TDQS
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 disclose the safety profile ('Read-only. No side effects.') plus stale/stale_warning and error return behavior. It also explains the data source (overrides table populated at index time), though it omits auth or rate-limit context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat bloated: it states the base/derived override behavior twice in consecutive paragraphs, which is redundant. The alternative-routing line and read-only note are well placed, but the duplication wastes space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description fully documents the returned dict fields and the stale/error cases. For a read-only analysis tool, an agent has everything needed to call it and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters; the description's param notes largely restate them. It adds only marginal value (qualified-name disambiguation example), so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (return C++ virtual method override information) plus the mechanism (libclang vtable analysis). Explicitly distinguishes itself from siblings get_inheritance_chain and get_symbol_context, 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names alternatives and the condition that selects them: get_inheritance_chain for class-level inheritance, get_symbol_context for symbol details. Also clarifies variant/image usage and the one-build-per-query rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_project_infoA
Return project metadata (name, type, root_path) for a project ID.
Looks up the global project registry at ~/.fw-context/projects.db.
Use this to identify a project from its UUID4 — find out what build
system it uses, its name, and where it was last indexed.
Read-only. No side effects.
Args: project_id: Project ID (UUID4 hex) to look up.
Returns: dict: {project_id, name, project_type, root_path, created_at, updated_at} or {"error": "..."} when the project_id is not registered.
On failure the dict holds only ``error`` with the reason.
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | No | Project ID (UUID4 hex) to look up. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full transparency burden. It explicitly discloses the underlying data source ('~/.fw-context/projects.db'), states 'Read-only. No side effects.' and defines the failure contract ('On failure the dict holds only error with the reason'). This is excellent behavioral disclosure beyond the bare operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well organized with a front-loaded summary, usage context, Args, and Returns sections. It is slightly redundant around failure behavior — the error dict is described both in Returns and again in the final sentence — but overall it is compact and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool with no output schema and no annotations, the description covers the purpose, data source, side-effect profile, return fields, and error shape. The only notable gap is that it does not state what happens if project_id is empty or omitted, given the parameter has a default and is not marked required.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% coverage by describing project_id as 'Project ID (UUID4 hex) to look up.' The description's Args section largely repeats this. It adds context that the ID must be registered, but does not explain behavior for an omitted or invalid project_id, so it provides only marginal additional semantic value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Return project metadata (name, type, root_path) for a project ID.' It clearly identifies this as a single-project lookup against a global registry, distinguishing it from sibling tools like list_projects and get_active_build by focusing on UUID4-based identification and build-system metadata.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: 'Use this to identify a project from its UUID4 — find out what build system it uses, its name, and where it was last indexed.' This tells the agent when the tool is appropriate, though it does not explicitly name alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_project_statusA
MANDATORY FIRST CALL for C/C++ projects. Return the health of the index of the project, and the list of its builds — check it before you use any other fw-context tool, and call it again while you wait for a reindex.
Read-only with two exceptions, and it spawns no subprocess — the
startup daemon thread and the file watcher own the background reindex.
The exceptions: the last index run can leave a marker that says that
the build is not there, and when the tool finds that build again, it
removes the marker. It also removes a reindex.pid or a
reindex.pending of a process that no longer runs. It creates no
.fw-context file in a project that is not initialized. It takes no
variant and no image: it reports every build. For the detail
of one build (its config_hash, memory map, defines), call
get_build_info.
builds lists every build of the index. A project of more than one
build has no active build: every query tool must get the parts of one
entry that are not empty, its variant, its image, or the two.
Select the build from the task, and
ask the user when the task does not identify one.
Act on reindex_state of the build that the task needs, in
builds (a project of one build has it at the top level too):
null— the index of the build is current. Continue."reindexing"or"pending"— the index of the build is not current, and an index run is active or scheduled. Wait, and call this tool again after about 30 s. Continue with the old index only when the user tells you to."not_scheduled"— the index of the build is not current, and no run updates it. Tell the user the command that the reasons name."failed"— the last index run failed. Give its text to the user: it names the command that repairs it.
Each query answer carries the state of its build as index_state,
from quick checks only. A query thus can miss a changed header, a
changed file that its answer does not name, or a new source file when
its answer is not empty. This tool does the full check.
status gives the state of the project:
"ready"— up to date. Continue."reindexing"— background reindex running or scheduled, or fw-context builds new source files on its own.reindex_stateof a build tells whether that build waits for the run.reindex_progressholds the last log line of a running reindex."reindex_needed"— the last index run failed, the build is not there, schema mismatch, an old row format, a changed or missing compile_commands.json, a checkout of another branch, tag or commit since the index, or a source file that compile_commands.json does not cover and fw-context will not build itself. A changed compile_commands.json includes one that fw-context cannot compare with the index. Queries still work on existing data. Readreindex_reasons: each reason names the action that it needs.Read
bg_reindex_runningbefore you name any command here. A run already under way does the work, thus a second one only waits on the same lock, andindex_messageand the checkout reason both say so. That field covers a run of the daemon AND a run the operator started, and also work that the daemon has scheduled and not yet started — the arguments of no run are readable, thus a reason that needs--buildcan 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. Runfw-context index."not_initialized"— runfw-context init."config_error"— a config file cannot be used: it cannot be read, it is not UTF-8 or not valid TOML, a section is not a table, a key that selects the data or where data goes has a value of the wrong type, or a URL is not valid.config_filenames it, andindex_messagegives the problem. Correct the file, or runfw-context doctor --fix --only configwhen the message names it: it removes each value that cannot be used.fw-context initcannot repair it.
A project of several builds gets the worst status of its builds. A
reason that every build gives comes one time, and any other reason
names its build: build <variant>/<image>: <reason>.
A failure sets NO status. An index with no build config 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. A database that fw-context cannot read (damage, no access)
makes the call fail with the error of SQLite. The message of the
check db-integrity of check_dependencies tells if it is
damaged.
Seven conditions set reindex_needed: a failed last index run, a
build that is not there, an outdated schema, an outdated ROW FORMAT, a
changed or missing compile_commands.json, a checkout of another
branch, tag or commit since the index, and a source file that is on
disk but absent from compile_commands.json when fw-context will not
build it on its own. A missing build, a missing
compile_commands.json, a checkout and such a source file need the
action that makes compile_commands.json again: a build, or for a
database of the user ([index] compile_commands) a new file from the
user. A plain reindex reads the same file again, and it has no
translation unit for a new source file and skips it without a word. A
failed run needs the repair that its reason names first. 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. An index
written before fw-context-rows/4 parsed a GCC build with guessed
toolchain headers and the macros of clang: an ESP32 or AVR index there
holds host headers from /usr/include and takes the #if branches
of the host, for example #if __XTENSA__ as false, and an ARM index
saw __GNUC__ 4. A build whose GCC driver does not answer the query
keeps that fault also after /4; the index run names such a compiler
in a warning.
client_restart_required is the OPPOSITE case, and no command repairs
it. This server process does not run the code that it must run. Two
causes set it, and client_restart_reason names each one that
applies:
The index carries a NEWER row format than this 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.
The operator installed a different fw-context after the LLM client started this process. This cause does not need an index, thus it shows also for
not_initialized,no_indexandconfig_error.
status therefore stays as it is 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.
update_notice is not a status either. It shows when PyPI has a
newer fw-context than the installed one. Tell the operator one time,
and do NOT upgrade fw-context yourself: the operator knows the tool
that installed it. After a request that succeeded, the server asks
PyPI again only after 24 hours. The request runs in a background
thread, and no tool waits for it. [updates] check = false
in the global config, or FW_CONTEXT_NO_UPDATE_CHECK=1, stops 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. Read
modified_files_count 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, and every vendor symbol too whenanalyze_vendoris True. Vendor symbols excluded byanalyze_vendor=Falsenever block it, thusvendor.totallarge withvendor.analyzed=0is expected, not a defect.index_messageends with the same counts as text.
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: {project_id, project_root, build_system, schema_version (int
— DB schema version), current_schema (int — code expects),
vendor_paths (list[str] — config index.vendor_paths),
project_paths (list[str] — config index.project_paths),
status (str — "ready"|"reindexing"|"reindex_needed"|"no_index"|
"not_initialized"|"config_error"; a failure sets no status and
gives error alone), config_file (str — only with
"config_error": the file that cannot be used), reindex_needed (bool), reindex_reasons (list[str] — why a
reindex is needed, empty when False, except that a new source file
that fw-context builds on its own is listed while
reindex_needed is False. Some of them ask for a build rather
than a plain reindex. For example, after a checkout of another
branch, tag or commit, compile_commands.json belongs to the OLD
checkout 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 a
build needs a reindex or has stale header dependencies),
index_message (str — human-readable summary of index state),
builds (list[dict] — every build: {variant, image, board,
symbol_count, file_count, indexed_at, status, reindex_state (str
or None — "reindexing", "pending", "not_scheduled", "failed", or
None for a current index), reindex_needed, stale,
modified_files_count, header_affected_tus, reasons}, and
manifest_verification on a build whose manifest is not "full"),
declared_not_indexed (list[dict], optional — each
variant that the config declares and the index does not hold:
{variant, command}; no query reaches it until the command ran),
bg_reindex_running (bool), reindex_progress (str or
None — last log line when reindex is running), _warning (str,
optional — when the manifest verification of a build is not
"full"), vec_available (bool), vec_error (str, optional),
client_restart_required (bool, optional — only when True),
client_restart_reason (str, optional — with the field above),
update_notice (str, optional — a newer release is on PyPI)}
A project of ONE build also gets the fields of that build at the
top level: indexed_at (str — "YYYY-MM-DD HH:MM:SS" in UTC, the
completion time of the last full index), first_indexed_at,
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 source files with
stale header dependencies; a file that compile_commands.json lists
more than once counts once), manifest_verification (str — "full"
when manifest.json exists, "partial" when it exists and the
embeddings are not complete, "none" without one), analysis (dict — LLM
analysis coverage split by project/vendor: {model, analyze_vendor,
project: {analyzed, skipped, total}, vendor: {analyzed, skipped,
total}, complete}), description (str). A project of several
builds gets no sums: the counts of each build are in ``builds``,
and ``reference_count``, ``analysis``, ``description`` and
``first_indexed_at`` of a build are in ``get_build_info``.
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``. For ``"config_error"``, it
adds ``config_file``. The two version fields
(``client_restart_*`` for an upgrade, ``update_notice``) can come
with every result, these two included. ``config_warnings`` (a
list) can come with each result that has a ``status`` other than
``"config_error"``: values of a config file that fw-context did not
use. Tell the user each line.
| Name | Required | Description | Default |
|---|---|---|---|
| fast | No | 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. | |
| project | No | 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. | |
| project_root | No | 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. |
TDQS
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 exhaustively: read-only except for two named side effects (removing a stale 'not there' marker, removing orphaned reindex.pid/reindex.pending), no subprocess spawned, no .fw-context file created on uninitialized projects. It also discloses failure behavior ('A failure sets NO status', a dict holding 'error' alone), SQLite failure modes, and that client_restart_required cannot be repaired by any command.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and usage guidance are correctly front-loaded, but the body is massively over-long and repetitive — the seven reindex_needed conditions are enumerated twice ('Seven conditions set reindex_needed' after an earlier full list), and the status/reindex_state semantics are restated in multiple places. Much of the volume is a Returns dump that could be trimmed or made uniform.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with many status states, no annotations, and no output schema, the description is complete enough to act on: every status value, every reindex_state value, the error-only shape, and the per-build vs single-build result split are all documented, along with the UTC-vs-local-time caveat for indexed_at and modified_files_count.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The Args section largely restates the schema for project/project_root and fast, adding only a light clarification that project_root also accepts a project name/id. It does not add format or edge-case detail beyond what the structured fields already provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening states a specific verb and resource ('Return the health of the index of the project, and the list of its builds') and marks its position in the workflow ('MANDATORY FIRST CALL for C/C++ projects'). It explicitly distinguishes itself from siblings, routing single-build detail to get_build_info and project names to list_projects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ('check it before you use any other fw-context tool, and call it again while you wait for a reindex') and names concrete alternatives with the conditions that select them ('For the detail of one build ... call get_build_info'). It also tells the agent what NOT to do, e.g. 'Do NOT run a reindex for this field' and 'do NOT upgrade fw-context yourself'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_sourceA
Read a C/C++ function/method/enum/macro body using libclang exact extents — no guessing line numbers. Uses AST-precise {start, end} extents so you get exactly the function body. Generic file readers don't know where a function actually ends — libclang tracks exact {start, end} from the AST.
The body is ifdef-filtered: a line of an inactive #if branch
comes back blank, thus the text holds only the code that compiles for
this build. The line numbers do not move. source_origin says where
the text came from — "index" is the filtered copy, "disk" is the
file itself and holds EVERY branch. A body reaches you from the disk
when the file changed after the last index run (stale_warning says
so), or when the index holds no body for the symbol, such as a
declaration.
For enums, includes a constants array of the member constants
with their values (at most 200; constants_total counts them all,
and constants_hint names the call that pages them). For macros,
returns kind="macro" with signature
(#define NAME or #define NAME(a, b)), is_function_like,
value (the replacement text ALONE — the parameter list is not part
of it) and expanded_value (preprocessor-resolved).
For rich context (who calls this, what does it call) use
get_symbol_context instead — it returns body, callers, and callees
in a single call. For the full file, use read_file.
Read-only. No side effects.
Args:
name: Symbol name, or qualified name (Class::method) to select
one symbol. Returns exact function body via libclang extent.
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.
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, qualified_name, kind, file, line, signature,
docstring, is_definition, is_template, is_virtual, is_pure_virtual,
source (str — the function/enum/macro body, truncated at 8000 chars),
warning (str, optional — when source file cannot be read)}.
May also include end_line (the last line of the extent),
template_usr, parent_usr, enum_value, constants
(list for enums), value (macro replacement text),
expanded_value (preprocessor-resolved macro value) when
applicable. A declaration has no extent, thus it gets no
end_line.
``line`` and ``end_line`` are the extent of the symbol, thus they
are the citation: quote ``file:line-end_line``. Do not count the
lines of ``source`` to find the end.
``source`` carries a line-number prefix on every line — four
columns, right-aligned, then two spaces (``" 20 bool ..."``).
This tool always numbers its text. ``read_file`` numbers its
``content`` when you pass ``line_numbers=True``, and the ``source``
of ``search_bodies`` is always bare. Strip the prefix before you
compare the text with anything.
When the file changed after the last index run, the dict adds
``stale`` (True) and ``stale_warning`` (str). ``source_origin`` then
tells where the body comes from: ``"disk"`` when the symbol did not
move, ``"index"`` when it did and the body comes from the index
instead. A moved symbol never gives the code of another symbol.
``_source_truncated`` (True) marks a body that a cap cut:
``index.max_symbol_body_lines`` bounds the number of lines, and a
second cap bounds the characters (8000). The character cut lands in the
middle of a line, thus a body with this mark can end in an
unbalanced brace. Read the rest with ``read_file`` and a range.
An ``ambiguous_warning`` key means that *name* matched more than one
symbol, such as two classes with a method of the same name. This
body belongs to ONE of them, and the key names it. ``candidates``
(max 20, each with ``in_project_root``) lists the others and
``candidates_total`` counts them. Give a ``qualified_name`` from it
to get one symbol only. It is separate from ``warning``, which
reports a body that could not be read from the disk.
A body in a file outside the project root, such as an SDK header,
is returned and not refused.
On failure the dict holds only ``error`` with the reason.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Symbol name, or qualified name (Class::method) to select one symbol. Returns exact function body via libclang extent. | |
| image | No | 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. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | 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. |
TDQS
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: ifdef-filtered bodies, source_origin index-vs-disk semantics, stale/stale_warning behavior, the 8000-char and max_symbol_body_lines truncation caps, ambiguous_warning/candidates, and error returns. Read-only/no-side-effects is also stated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and well organized into purpose, Args, and Returns sections. It is long, and the extent rationale is restated ('exact extents — no guessing line numbers' vs 'AST-precise {start, end} extents'), but the detail is mostly load-bearing given there is no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex symbol-lookup tool with five parameters and no output schema, the description fully documents the return dict, optional keys, truncation behavior, and failure modes. An agent has everything needed to call it and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the Args section in the description largely duplicates the schema's own parameter text (variant/image/project wording is nearly identical). It adds the mutual-exclusion note between project and project_root, but that is also present in the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Read a C/C++ function/method/enum/macro body using libclang exact extents') and immediately distinguishes itself from generic readers. It names its siblings explicitly (get_symbol_context, read_file), 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit alternatives and the conditions that select them: 'For rich context... use get_symbol_context instead' and 'For the full file, use read_file.' It also explains the project/variant/image selection semantics and routes to list_projects for project identifiers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_symbol_contextA
Rich one-shot context for a C/C++ symbol: body, signature, the direct callers and callees. Answers "what does this do and how does it fit in the system?" in a single response — libclang powers the call graph, not regex. Falls back to macro display when the symbol is not found.
Prefer this over get_source when you also need callers, callees,
indirect call sites, or LLM analysis — all returned in a single call.
If you only need the raw function body (no metadata), get_source is
slightly faster. For transitive call-graph exploration use
find_all_callers_recursive or find_callees_recursive.
The callers and callees include vendor/SDK code — the call graph
naturally spans project and vendor boundaries in both directions
(project → vendor API, vendor callback → project handler). Each list
is cut (callers at 50, callees at 100), and its *_total says how
many there are; *_hint names the tool that pages a cut list.
The body is ifdef-filtered, the same as in get_source: a line of
an inactive #if branch comes back blank and the line numbers do not
move. source_origin says whether the text is the filtered copy
("index") or the file itself ("disk", every branch present).
Read-only. No side effects.
Args: name: Symbol name. Returns body, signature, the direct callers and callees (each list with its total). 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. 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 with: name, qualified_name, kind, file, line, signature,
docstring (raw Doxygen comment text), is_definition, callers (list,
max 50 — call and indirect references, each with its line),
callees (list, max 100 — one row for each callee and kind of
reference), source (body text),
indirect_call_sites (list, max 200 — for a field/variable symbol,
where the function pointer is invoked; for a function/method, the
calls through function pointers that it makes).
callers_total, callees_total and
indirect_call_sites_total count each whole list. When a list
is cut, callers_hint, callees_hint or
indirect_call_sites_hint names the tool that pages it.
For field and variable symbols that have function pointer type,
also includes resolution: {assignments_found, call_sites_found,
resolved, note} indicating whether assignments and call sites are
linked (Phase 3). resolved=False with a note when parts are
missing — LLM can detect uncertainty.
For an enum also returns constants (at most 200), constants_total and,
when the list is cut, constants_hint; for an enum constant, enum_value.
For macros returns kind="macro", signature (#define NAME
or #define NAME(a, b)), is_function_like, value (the
replacement text ALONE) and expanded_value
(preprocessor-resolved).
When LLM analysis has been generated (fw-context index --analyze),
includes llm_analysis: {summary, inputs, outputs, model, analyzed_at}
with a structured description of the symbol's purpose, parameters, and
return values/side effects.
When the file changed after the last index run, the dict adds
``stale`` (True) and ``stale_warning`` (str), and ``source_origin``
tells where the body comes from: ``"disk"`` when the symbol did not
move, ``"index"`` when it did. The callers and callees come from the
index in all cases, thus a stale dict can hold an incomplete list.
``_source_truncated`` (True) marks a body that a cap cut, as in
``get_source``.
The dict also carries the libclang flags of the symbol:
is_virtual, is_pure_virtual, is_template, parent_usr, and
template_usr. For a virtual method it adds ``overrides`` (the base
methods that this method overrides) and ``overridden_by`` (the
derived methods that override it) — use these two before you change
a virtual method.
An ``ambiguous_warning`` key means that *name* matched more than one
symbol, such as two classes with a method of the same name. Every
part of this answer — body, callers and callees — is about the ONE
symbol that the key names. ``candidates`` (max 20) lists the others
and ``candidates_total`` counts them. Give a ``qualified_name`` from
it to ask about one symbol only.
A symbol in a file outside the project root, such as an SDK header,
is returned and not refused.
On failure the dict holds only ``error`` with the reason.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Symbol name. Returns body, signature, the direct callers and callees (each list with its total). | |
| image | No | 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. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | 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. |
TDQS
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: 'Read-only. No side effects.', callers/callees span vendor/SDK boundaries, lists are cut at 50/100/200 with totals and paging hints, the body is ifdef-filtered with blanked lines and fixed line numbers, source_origin distinguishes index vs disk, stale-file behavior, and ambiguity via ambiguous_warning/candidates. This is unusually rich disclosure for a read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and routing to alternatives are front-loaded, and the Args:/Returns: structure is conventional. The Returns block is long, but with no output schema it is the only place return shapes can be documented; a few lines (e.g. the Args restatement of callers/callees totals) are redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No annotations and no output schema, so the description must cover both the safety profile and the return contract — and it does: every key, list cap, hint, stale/ambiguous case, and the failure mode ('the dict holds only error with the reason'). An agent has everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the Args section largely restates the same text that already appears in the schema (project, project_root, variant, image). It does add the useful 'give one of the two, not both' framing and the note that fw-context does not auto-select a build, but that nuance is also present in the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource: 'Rich one-shot context for a C/C++ symbol: body, signature, the direct callers and callees.' It explicitly differentiates from siblings by naming get_source and the recursive callers/callees tools as the alternatives it is not.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Two explicit selection rules: prefer this over get_source when you also need callers/callees/analysis, use get_source if you only need the raw body, and use find_all_callers_recursive / find_callees_recursive for transitive exploration. It also names list_projects as the source of project ids and states the project vs project_root either/or.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_template_instancesA
Find all template instantiations for a C/C++ class or function template — libclang template-aware lookup. Finds concrete instantiations spread across all translation units, each with its full type signature. Text-based search cannot resolve template specializations across translation units.
Returns concrete instantiations of the template — each with its full type
signature (e.g. Callback<void(int)>). They are nested in the
instances list of one dict that describes the template itself.
Uses the template_usr column populated during indexing via libclang's
cursor.specialized_template.
Known limitation: libclang's specialized_template does not
reliably resolve implicit instantiations or template methods of
template classes. Header-only templates (e.g. RingBuffer<T>)
may report zero instances even when used in the codebase. Explicit
specializations and class/struct instantiations are detected more
reliably than method-level instantiations.
For finding the template declaration itself use lookup_symbol.
Read-only. No side effects.
Args:
template_name: Template name to find instantiations for.
E.g. 'Callback' or 'mbed::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.
limit: Maximum results (default 50, max 200).
offset: Skip this many instances. 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:
list[dict]: the page notice {total, offset, shown, more, hint}
for the instances, then one element wrapping the template
declaration:
{name, qualified_name, kind, file, line, is_definition,
signature, instances (list of dicts, each with name,
qualified_name, kind, file, line, signature, is_definition — one
page of them), instance_count (int — all instances, as total)}
A page after the last instance gives one ``info`` dict that names
the total.
A dict with ``error`` means that the name was not found, is not a
template, or the query failed — check that key first. When a file
of the answer changed after the last index run, a ``warning`` dict
comes first.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| limit | No | Maximum results (default 50, max 200). | |
| offset | No | Skip this many instances. Reads the next page of a template with many instances. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | 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. | |
| template_name | Yes | Template name to find instantiations for. E.g. 'Callback' or 'mbed::Callback'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so well: it declares 'Read-only. No side effects.', a detailed Known limitation section about libclang's specialized_template failing on implicit instantiations/header-only templates, and error/warning dict behavior ('A dict with error means...check that key first').
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose well and uses labeled Args/Returns/Known limitation sections, but is long and the entire Returns block duplicates the existing output schema, so not every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 7-param template-lookup tool, the description is complete: purpose, mechanism, known limitations, parameter guidance, error/warning handling, and return shape are all covered, leaving no gaps an agent needs to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 7 parameters. The description largely repeats this (template_name examples, project vs project_root 'give one, not both'), adding only marginal meaning beyond the schema — baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Find all template instantiations for a C/C++ class or function template') and identifies the mechanism ('libclang template-aware lookup'). It explicitly distinguishes itself from text-based search and from lookup_symbol for the declaration.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent to lookup_symbol 'For finding the template declaration itself,' and contrasts with text-based search which 'cannot resolve template specializations across translation units.' Clear when-to-use context, though it states no explicit conditions under which this tool is the wrong choice beyond the declaration case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_vector_tableA
Read the interrupt vector table, and say what services each interrupt.
The vector table is how an interrupt reaches code. Nothing CALLS a handler — the hardware reads a slot and jumps — so a handler has no caller, and every other tool shows it as unreferenced. This tool reads the table itself, from the assembly the build compiles.
Use it to answer "which interrupts does this firmware service", to find the handler for one interrupt, or to find the interrupts that reach the trap loop.
The slot number is the position in the table. What that position
means belongs to the architecture, not to the index. On Cortex-M
slots 0 to 15 are the system exceptions and slot 16 + n is external
interrupt n, so TIM2_IRQHandler in slot 44 is TIM2_IRQn = 28.
On other architectures the same position means something else.
The status field says what services the interrupt:
"c"— a definition outside assembly. Code runs. When the index also holds the weak definition that this one replaced, the row hasoverriddenwith its file and line."assembly"— an assembly definition that is not an alias. Assembly services the interrupt."unhandled"— an assembly name that is an alias (.thumb_set) of another symbol, and nothing overrode it. The row holdsaliases, the name, file and line of the alias target. A CMSIS startup file aliases each unserviced interrupt toDefault_Handler, which is an infinite loop. If the interrupt fires, the device stops."runtime"— the image holds that same alias, and the code installs a real handler into this slot by callingNVIC_SetVector. A target that definesCMSIS_VECTAB_VIRTUALkeeps its vector table in RAM and fills it that way, so the interrupt IS serviced once the registering code has run — and not before it. The row holdsinstalled, one entry per call site with the handler name, its file and line, andat, where the registration happens. Followatto see WHEN it happens: on the Mbed projectus_ticker_irq_handlerreaches slot 25 fromus_ticker_init, so the tick source is unserviced until the ticker starts. A row with a real static definition keeps its own status and still carriesinstalled."data"— the slot holds an address BUILT from the symbol it names (.word z_main_stack + CONFIG_MAIN_STACK_SIZE), so the symbol is a base and nothing jumps to it. On Cortex-M this is slot 0 of a Zephyr table: the initial stack pointer. Do not read it as code."linker"— the linker script gives the address and no compiled file defines the name. Slot 0 holds the initial stack pointer, not a handler, and looks like this. When the index read the script,fileandlinename the assignment in it — on the Mbed project,__StackTopat.link_script.ld:148. Do not read this row as code: there is no function to follow."dispatcher"— the slot reaches a function that holds more than one slot of this table AND calls through a pointer. It cannot be servicing one particular interrupt; it decides at run time where to go. Zephyr fills every external IRQ slot with_isr_wrapper, which reads the interrupt number and jumps through_sw_isr_table. Follow it:get_symbol_contexton the name, thenfind_referenceson the table it uses. A handler that merely calls one registered callback is NOT this — it holds a single slot and keeps"c".
A "c" row with overridden is the CMSIS pattern: the startup
file defines each handler weakly, the project defines the same name
again, and the linker keeps the strong one.
Three sources are read, and source says which one a row came
from:
"assembly"— a table of address words,.wordor.longin a vector section, which is what a CMSIS startup file writes."c"— an array whose elements are addresses of functions, which is what a build that generates its table produces. Zephyr writes its external interrupts this way, withgen_isr_tables.py. These rows also carrytable_name, the array the slot belongs to."build"— the registration the build itself recorded, for a slot the other two could not name. A generator writes a resolved ADDRESS into every slot that is in use, so those slots have no name in the source at all — and they are the interrupts the firmware actually services. Measured on an nRF54L application: 284 of 290 slots name the spurious stub, and the 6 without a name are IRQ 89, 198, 219, 228, 269 and 270, which these rows fill in.Such a row can carry
argument, the symbol the build passes to the handler. Read it as an argument and not as a second handler: behind thenrfx_isrshim it is the real worker (nrfx_power_clock_irq_handler), while for another driver it is the device (__device_dts_ord_116). When the build enables run-time registration (CONFIG_DYNAMIC_INTERRUPTS), theinterruptsdict says so, because an interrupt connected at run time leaves nothing to read and the rows are then not all of them. A"build"row hasfileempty andline0 when the handler name has no single definition in the index.
Recognition is by shape, never by name, so any array of function
addresses is reported and the row names its table. A table of
interrupt handlers and a table of state machine steps are the same
construct, and table_name is how they are told apart.
Slot numbers are not joined across tables. Each slot is the index
inside its own table, so two tables both start at 0 — read slot
together with table_name and source. They are not renumbered
into one run because the index does not hold the length of the
assembly table, only its occupied slots, and an offset derived from
that would be silently wrong for every entry of a 290-entry table.
A coverage row follows the slots for each table longer than the
number of slots that name a function. It says how many of the declared
elements were named and which slot numbers were not, because a name is
not always there to be read: an element can be a zero, or an address
the linker resolved before the table was written.
Read it in both directions. A hole in a table of handlers is a vector
nothing services. A hole in Zephyr's _sw_isr_table is the
opposite — measured on an nRF54L application, 284 of 290 slots name the
spurious stub and the 6 without a name are the interrupts in use. The
tool reports where to look; which meaning applies depends on the table.
An interrupts row answers "which are unserviced" wherever the
build recorded its registrations, and it is the answer under
unhandled_only too. The row-level unhandled status is read
from an alias edge, which a CMSIS startup writes and a generator does
not — measured, zero unhandled rows on all eleven images of a Zephyr
project against 39 to 72 on four CMSIS and Mbed ones. The
registrations settle it from the other side: what the build connected
is the whole list, so anything else has nothing servicing it, and no
handler has to be recognised by name.
The complement is taken over the length of the table, NOT over the
slots that hold a stub. Measured on an mcuboot image: its software
table names 44 of 48 slots, and one of those 44 is
uarte_0_direct_isr, an interrupt wired straight into the vector
table. It IS serviced, and counting stubs would report it as not.
What is still not covered: an architecture that builds its table from
branch instructions (arm64, Xtensa, MIPS) writes no table of
addresses in either form. A handler whose address the build resolved
at link time has no name to report either — coverage names its slot
but not the function. For an interrupt this tool cannot show,
find_references on the handler name still gives every reference
the index holds.
Read-only. No side effects. Requires an index of the assembly and the
reference index (fw-context index — refs on by default).
Args:
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.
unhandled_only: When True, return only the "unhandled" slots.
limit: Maximum slots (default 400, max 1000).
offset: Skip this many slots. 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 rows of the answer: total counts every slot of every table. Then a list
of slot dicts sorted by source, then table, then slot. Each holds:
slot (int), name, file, line, source ("assembly", "c" or
"build"),
status ("c", "assembly", "unhandled", "runtime",
"data", "linker" or "dispatcher"), and table_file and table_line
(where the slot is written). Every path in this answer is
absolute, at included. A "c" source row also holds
table_name and table_usr. A "c" status row can hold
overridden, a dict with file and line. An "unhandled" row
holds aliases, a dict with name, file and line. Any assembly row
can hold installed, a list of dicts with name, file, line and at.
Never empty: one dict with ``error`` (no index) or ``info`` (no
vector table in this build). Check both keys first. A dict with
``coverage`` follows the slots for each table that has unnamed
elements, and a dict with ``interrupts`` says which are connected
and which are not — the latter in both modes. Neither is subject
to the page: they describe the whole table, the longest table is
where they matter most, and they come after the slots of each
page. A page after the last slot gives one ``info`` dict that
names the total, and then those two.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| limit | No | Maximum slots (default 400, max 1000). | |
| offset | No | Skip this many slots. Reads the next page of a long table. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | 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. | |
| unhandled_only | No | Return only the slots with status 'unhandled' (an alias of a default handler, nothing installed at run time). |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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. Requires an index of the assembly and the reference index (fw-context index — refs on by default).' It also discloses non-obvious behavior — slot numbering is not joined across tables, coverage/chunking of pages, rows that look like code but are data or linker symbols, and runtime-installed handlers that are unserviced until registration runs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and usage are front-loaded before the reference material, and headers make it navigable. But the body is enormously oversized and spends thousands of words enumerating return-value statuses and fields despite an output schema existing — much of that does not earn its place in the selection/invocation path.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a high-complexity tool with no annotations, the description covers prerequisites, build/variant/image scoping, pagination, error/info dicts, and pagination-independent coverage/interrupts rows. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all seven parameters, and the Args section largely restates them. It adds marginal value (e.g., project vs project_root 'give one of the two, not both'), but the baseline of 3 applies when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 ('Read the interrupt vector table, and say what services each interrupt') and immediately explains why the tool exists relative to siblings ('a handler has no caller, and every other tool shows it as unreferenced'). An agent can distinguish this from lookup_symbol/find_references/dead_code without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit use cases are given ('which interrupts does this firmware service', 'find the handler for one interrupt', 'the interrupts that reach the trap loop'), plus an explicit fallback when the tool cannot help: 'For an interrupt this tool cannot show, find_references on the handler name still gives every reference the index holds.' Naming the alternative and the condition that selects it satisfies the top bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_projectsA
List all indexed firmware projects with their statistics.
Read-only. No side effects. Use it to find another project; call
get_project_status for the builds and the health of one project.
indexed_at and first_indexed_at are UTC, in "YYYY-MM-DD HH:MM:SS" format — the same format that get_project_status returns.
indexed_at is the time of the newest build.
A project of several builds gets no counts here (symbol_count,
file_count, description and analysis are None): a file that
two images compile is in the index of each, thus a sum counts shared
code once for each build. get_project_status gives the counts of
each build.
analysis holds the project and vendor counts only. For the
model, analyze_vendor, and complete fields, call
get_build_info for that build.
Args:
project_root: Project root whose config names the index
directory (index.db_dir). Omitted, the global config does.
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.
Returns: list of dicts, each with: project_id, name, root_path, build_system, symbol_count, file_count, indexed_at (str — UTC), description (str), first_indexed_at (str — UTC), schema_version, current_schema, reindex_needed (bool — the schema is outdated, the compile_commands.json of a build changed or is missing, or a build holds rows of an older row format; each (variant, image) build counts), status (str — "ready" or "reindex_needed"), db (path to SQLite database file), build_count (int — number of builds, each a (variant, image) pair), analysis (dict — LLM-analysis coverage {project: {analyzed, skipped, total}, vendor: {analyzed, skipped, total}}, or None when no build is indexed).
When no project has an index, the result is a single dict with an
``info`` key. When fw-context cannot read a database, the result
holds a dict with ``db`` and ``error`` keys for that file.
| Name | Required | Description | Default |
|---|---|---|---|
| project | No | 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. | |
| project_root | No | Project root whose config names the index directory; pass it to distinguish multiple indexed projects that keep separate index directories. Omitted = the global config. Every project in that directory is listed. This field also accepts a project name or a project_id, but project is the clear field for those. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It declares 'Read-only. No side effects.' and thoroughly explains return semantics, edge cases (no indexed projects, unreadable databases), and why counts are None for multi-build projects. This is rich transparency beyond structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with purpose and usage, but it is long and includes detailed Args and Returns sections that duplicate the input schema and output schema. While every section is organized, several sentences do not earn their place given the structured fields already provided.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the existence of an output schema, the description is complete enough for an agent to call it correctly. It covers purpose, usage, parameters, return behavior, and edge cases, leaving no critical gap for invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters. The Args section largely repeats the schema text, adding only '(index.db_dir)' for project_root. Baseline 3 is appropriate because the description does not add significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'List all indexed firmware projects with their statistics.' Distinguishes from sibling tools by naming get_project_status for single-project builds and health. An agent can tell what this tool does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use it to find another project' and directs the agent to get_project_status for builds and health, and to get_build_info for model/analyze_vendor/complete fields. Clear alternatives and conditions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_symbolA
Look up a C/C++ symbol by name via libclang index — exact or prefix
matching. Finds symbols text-based search can miss: build-conditional
code, template instantiations, macro-expanded names. Macros are
extracted via clang -dM -E during indexing so #ifdef-conditional
macros resolve correctly for the build of the query. Prefer this over
search_code when you know the exact symbol name or a prefix
(uart_ finds all UART symbols). Use search_code for
keyword/concept search.
name matches the name or the qualified name. A name with ::
that matches nothing is tried once more by its last part, kept where
the qualified name ends with name: Foo::bar finds
ns::Foo::bar. Macros are searched only when no symbol matches.
Read-only: yes. May auto-reindex stale files (non-blocking).
Args:
name: Symbol name (exact match) or prefix (set exact=False).
E.g. 'uart_init' finds the exact function; 'uart_' finds
all symbols starting with 'uart_'.
project_root: Project 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.
exact: True = exact name match, False = prefix LIKE match (default).
limit: Maximum results of one page (default 50, max 100).
offset: Skip this many results (default 0). A common method name
lives in many classes — read and write match dozens of
symbols — and this walks past the ones already seen. The page
notice names the offset to use. The order is stable (a
definition first, then the line, then the file and the USR),
thus two pages never overlap and never skip a symbol.
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[dict]: The page notice leads the answer — total, offset,
shown, more — where total counts every symbol the name
matches. Read it before you conclude that a page holds them all.
Each symbol that follows has name, qualified_name, kind, file,
line, signature, docstring, is_definition, is_template, is_virtual,
is_pure_virtual fields, and class — the class, struct or union
that declares the symbol, absent for a free function. class is
what tells two same-name methods apart at a glance.
Enum constants include enum_value
with the integer value. Macro results include kind="macro",
signature (how the macro is invoked: #define NAME,
#define NAME() or #define NAME(a, b)), is_function_like,
value (the replacement text ALONE — the parameter list is not
part of it), and expanded_value (preprocessor-resolved value).
May also include template_usr,
parent_usr, and llm_analysis ({summary, inputs, outputs}) when available. A model wrote the text in
llm_analysis, and the code did not — use it to find a symbol,
and quote signature, docstring, or get_source instead.
When nothing matches, a trailing dict may hold _did_you_mean
with suggested names. The symbols of the first suggestion that
matches exactly then come back, each with _fallback: True — its
name is NOT name. With no match and no suggestion, the list is
empty and has no page notice, because there is no page. An
info entry comes back for one case only: an offset past the
end of an answer that does hold rows. When a file that the answer
names changed on disk, a dict with warning comes first.
**Note:** C++ constructors share their name with the enclosing
class, so ``lookup_symbol("Foo")`` may return both ``class Foo``
and ``constructor Foo::Foo()``. Use the ``kind`` field to
filter when you need a specific symbol type.
A list with one dict that holds an ``error`` key means that the
project has no index, that the variant or image is wrong, or that
the lookup failed. Read that key
before you read the result fields.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Symbol name. Exact match if exact=True, prefix LIKE match otherwise. E.g. 'uart_init' or 'uart_'. | |
| exact | No | True = exact name match, False = prefix LIKE match (default). | |
| image | No | 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. | |
| limit | No | Maximum results returned (capped at 100, default 50). | |
| offset | No | Skip this many results. Pages through a name that many classes share, such as 'read' or 'write'. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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: states 'Read-only: yes' and 'May auto-reindex stale files (non-blocking)', documents pagination/stable ordering, prefix-fallback behavior for qualified names, the _did_you_mean and _fallback semantics, and the error/info/warning dict cases. This is unusually rich behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the search_code routing are front-loaded, which is good. However the Returns section is extremely long and, given that an output schema already exists, much of it restates fields and edge cases at length rather than earning every sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter tool with complex build-selection semantics, the description covers the decision points an agent needs: matching mode, project selection, build/variant disambiguation, pagination, and failure modes. Nothing critical to calling it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline would be 3, but the description adds meaning beyond the schema: 'Give one of the two, not both' for project/project_root, the mutual relationship of variant and image, and the reasoning behind offset ('read' and 'write' match dozens of symbols). These relational constraints are not in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Look up a C/C++ symbol by name via libclang index') plus the matching modes (exact/prefix). It explicitly contrasts itself with the closest sibling, search_code, so an agent can route correctly 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use ('when you know the exact symbol name or a prefix'), when-not ('Use search_code for keyword/concept search'), and a concrete example ('uart_' finds all UART symbols). It also gives guidance on the project vs project_root choice and the variant/image build-selector relationship.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_fileA
Read a C/C++ source file, one page at a time, with ifdef-filtered content —
only code that actually compiles for the build of the query.
Inactive #ifdef branches are replaced with blank lines (preserving
original line numbers).
Use this to read a file without leaving the fw-context ecosystem.
Unlike generic file readers, this tool returns build-accurate content:
code gated behind #ifdef BOARD_V2 stays visible only when
BOARD_V2 is actually defined for this build. Line numbers match
the original file — inactive branches appear as blank lines, and the
text spans the whole file, thus lines is the length of the file.
A blank line is an answer, and not a defect: it says that the line is
in a branch the build does not take. When EVERY line of the file is
blank, the dict carries all_lines_inactive and a warning — such
a file holds code, and the build of the query compiles none of it.
content is bare text by default and carries NO line-number prefix —
unlike the source of get_source, which numbers every line.
Never count the lines here to find a number. Take it from a field
instead: the match_lines of search_bodies or search_content,
the line / end_line of get_source and get_file_map, or
pass line_numbers=True and read the number off the line.
start_line and end_line cut a window out of the file (1-based,
both ends inclusive, 0 = no bound on that side). Reading around a
known line costs a fraction of the whole file — 40 lines around a match
instead of 2000 lines of a header.
Without end_line the answer is ONE PAGE of at most 2000 lines from
start_line on, and page holds the page notice: total is
the number of lines of the file, offset the number of lines before
the page, shown the lines on it. When more is true, the
hint names the read_file call with the next start_line.
An explicit end_line gives the whole range that it names.
A comment and a preprocessor directive are part of the answer. Both
are text that the file holds and the build reads, thus both stay — an
include guard, a #define, and the description of a register in a
vendor header included. A blank line is therefore an inactive line, or
a line that is blank on disk, and nothing else.
For reading a single function body with libclang exact extents use
get_source. For body + callers + callees in one call use
get_symbol_context. For a structural overview without content use
get_file_map. For searching patterns across files use
search_content.
Read-only. No side effects. Falls back to raw disk content (with a
warning) when the indexed files.content column is empty — e.g. on
a legacy index that predates this feature. Run fw-context index
to populate the ifdef-filtered content.
Args:
file_path: Path relative to project root, or just the filename.
E.g. src/main.cpp or main.cpp.
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.
line_numbers: Prefix every line with its number, right-aligned and
followed by two spaces, as get_source does. Default False.
start_line: First line to return, 1-based inclusive. 0 = file start.
end_line: Last line to return, 1-based inclusive. 0 = one page of
at most 2000 lines.
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: {file (str), language (str — "c" or "cpp"),
mtime (float), lines (int — total line count of the WHOLE file,
whatever range was asked for),
content (str — the ifdef-filtered text, bare unless
line_numbers was set),
warning (str, optional — when reading from raw disk instead of
indexed content, or when no line of the file is active),
all_lines_inactive (True, optional)}.
``all_lines_inactive`` marks a file of which the build of the query
compiles no line: every line is inside an inactive ``#if`` branch, thus
``content`` holds the correct number of lines and no text. Without
this field that answer reads as an empty file, and the two mean
opposite things.
A range, or a page that is not the whole file, adds ``start_line``
and ``end_line`` — the first and last line the ``content`` really
holds, after the end was clamped to the length of the file.
Without ``end_line`` the dict also holds ``page``, the page notice
``{total, offset, shown, more, hint}`` in lines.
When the file changed after the last index run, the dict adds
``stale`` (True) and ``stale_warning`` (str): the content comes
from the index, not from the disk.
The path rules are those of ``get_file_map``. On failure the dict
holds only ``error`` with the reason: a path the index does not
hold, an ``end_line`` before ``start_line``, or a ``start_line``
past the end of the file.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| project | No | 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. | |
| variant | No | 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. | |
| end_line | No | Last line to return, 1-based inclusive. 0 = one page of at most 2000 lines. | |
| file_path | Yes | Path to source file — relative to project root or just filename. | |
| start_line | No | First line to return, 1-based inclusive. 0 = from the start of the file. | |
| line_numbers | No | Prefix every line with its line number, like get_source. Default False (bare text). | |
| project_root | No | 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. |
TDQS
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/no side effects, explains that inactive #ifdef branches become blank lines, warns when the whole file is inactive (all_lines_inactive + warning), discloses the raw-disk fallback when indexed content is empty, and flags staleness (stale/stale_warning). It also enumerates the failure modes that return only an error.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the differentiator (ifdef-filtered, build-accurate content) and is well organized into purpose, semantics, alternatives, and args/returns. It is, however, long-winded, with the blank-line meaning restated in two places ('A blank line is an answer, and not a defect' then 'A blank line is therefore an inactive line') and some redundant prose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must describe returns, and it does so exhaustively: the dict fields, when optional fields (warning, all_lines_inactive, page, stale) appear, and the distinction between an inactive file and an empty one. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 real meaning beyond the schema: the 1-based inclusive semantics with 0 = unbounded, the one-page-of-2000-lines default and how start_line/end_line interact with it, and the mutually exclusive variant/image build selection. Much of the per-parameter text mirrors the schema, which keeps this from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Read a C/C++ source file') and immediately names the defining property: ifdef-filtered, build-accurate content. It explicitly contrasts itself with 'generic file readers' and the sibling tools, so an agent can distinguish it from get_source, get_file_map, and search_content 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing: get_source for a single function body with libclang extents, get_symbol_context for body+callers+callees, get_file_map for a structural overview, search_content for cross-file pattern search. It also tells the agent when to window the read ('reading around a known line costs a fraction of the whole file') and how to pick a build via variant/image.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reindex_fileA
Re-parse a single source file with libclang and update its symbols in the index.
Not read-only — uses the exact compiler flags from compile_commands.json.
Use after editing a file to keep the index current without a full rebuild.
Without variant and image the file is re-parsed in EACH build
of the project that compiles it: an edit on disk changes the file for
every build of the tree. A build that does not compile the file is
named in builds_without_file. With the two arguments of one build,
as get_project_status lists them, only that build is re-parsed; a
part of a pair gets an error that lists the builds.
The call runs in a thread of the server and sends a notice each 5 s.
It holds the lock of the query tools: another query waits 5 s, then
gets "server busy". After 300 s the call returns an error, and a
part of the work can continue or fail. Call get_project_status
for the state of each build, and repeat the call for a build that is
not current. The answer holds no index_state.
A source file must be listed in compile_commands.json. A header is
not listed there — compile_commands.json names translation units — so it
is re-parsed through one unit that includes it, taken from the manifest
of each build. That answer describes a single compilation context,
thus the result carries a warning: another unit can see the header
under a different set of #define values and still hold stale
symbols. Only a full fw-context index covers every context. One
unit and not all of them is a cost decision — an application header
reaches a median of 3 units but as many as 266 on a real project, at
tens of seconds each.
Also rebuilds the method override relationships, the PageRank scores
and the hotspot cache when reference indexing is on
([index] index_refs), with and without with_analysis. When
with_analysis=True and the LLM is on ([llm] enabled), it also
regenerates the LLM analysis and the embeddings of the affected
symbols. The analysis also needs [llm] analyze_symbols. It is
content-addressed, thus an unchanged symbol is never re-analysed.
Args:
file_path: Path to the file to re-parse. A source file must be in
compile_commands.json; a header goes through one including unit.
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.
variant: The variant of the one build to re-parse. Omit it, and
image, to re-parse each build that compiles the file.
image: The image of the one build to re-parse.
with_analysis: When True (default), also regenerates the LLM symbol
analysis and the embeddings, which need a model. Set False for a
fast update: the status tools then report the symbols that wait
for the two.
A file that is gone from disk but still in the index has its records removed in each build that holds it; the result is then {file, symbols_removed, action: "deleted", builds}.
Returns:
dict: {file, translation_units, symbols_updated, elapsed_s, builds},
plus builds_without_file when a build does not compile the file.
builds has one entry for each build that compiles the file:
{variant, image, translation_units, symbols_updated, elapsed_s},
plus when they apply: skipped_tus and skipped_count (units that
failed to parse), warning (header coverage), analysis_updated and
embeddings_updated (counts for the whole build, not this file), and
analysis_warning, overrides_warning, pagerank_warning, or
embedding_warning when a phase failed, or error when the
re-parse of that build failed.
When one build compiles the file, the top level holds the full
result of that build. When several do, the top level holds the
sums of the builds that did not fail, ``elapsed_s`` of the whole
call, the sum of ``skipped_count``, ``warning`` only when each of
those builds has it, and ``failed_builds`` with the label of each
build whose entry holds ``error``.
On failure the dict holds ``error`` with the reason: a refusal of
the selector, no build that compiles the file, or an update that
failed in each build. It can add ``skipped_tus`` or ``action``.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | Image of the one build to re-parse: a separate program, such as the application or the bootloader. Give it when that build has an image name. | |
| project | No | 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. | |
| variant | No | Variant of the one build to re-parse. Omit it and image to re-parse the file in each build that compiles it. A part of a pair gets an error that lists the builds. | |
| file_path | Yes | Absolute or project-relative path to the file to re-parse. A source file must have an entry in compile_commands.json. A header is re-parsed through one translation unit that includes it, and the result then carries a warning that other units can still hold stale symbols. | |
| project_root | No | 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. | |
| with_analysis | No | When True (default), also regenerates the LLM symbol analysis and the embeddings — slower, because the two need a model. Set False for a fast update: the tool skips the two, and get_project_status then reports the symbols that wait for them. The method overrides, the PageRank scores and the hotspot cache are rebuilt in the two modes when reference indexing is on (`[index] index_refs`). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and discharges it: it states this is not read-only, that it holds the query-tool lock (another query waits 5s then gets 'server busy'), the 300s timeout with partial work, the 5s notices, header staleness warnings, and that it rebuilds overrides/PageRank/hotspot cache plus content-addressed LLM analysis.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core purpose and organizes the rest into prose plus Args/Returns sections. It is long, but the length is justified by genuine complexity (6 params, multi-build behavior, no output schema), with only mild duplication between the prose and the Returns block.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema and no annotations, so the description must cover returns and behavior — and it does: it details the returned dict shape, per-build aggregation rules, failed_builds, and failure/error cases. All six parameters are documented, so nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 real meaning: the variant/image pairing error, the project-vs-project_root exclusivity, and the with_analysis=True/False cost tradeoff. It largely mirrors the schema's own descriptions, hence not a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a precise verb+resource+effect: 'Re-parse a single source file with libclang and update its symbols in the index.' This clearly distinguishes it from siblings like reset_index (full rebuild) and the read-only query tools, so an agent can place it immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use: 'Use after editing a file to keep the index current without a full rebuild.' It names the alternative (full 'fw-context index') and the condition that selects it, and spells out when to supply variant/image versus omitting them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reset_indexA
Delete the entire symbol index for a project.
Not read-only — permanently deletes the SQLite database and WAL files.
Call with confirm=False first (dry-run) to see what would be deleted.
Re-index with fw-context index afterwards.
Handles corrupt databases gracefully — you can delete a corrupt index without needing to open it first.
Args: 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. confirm: Must be True to execute. Call without first as dry-run.
Returns:
dict: {project_root, db, project_id, action: "dry_run"|"deleted",
message, build_count, symbol_count, indexed_at}. build_count
counts the completed builds of the project, as
get_project_status lists them. symbol_count counts every
symbol row in the database, the rows that the reset deletes: also
the rows of a build that an index run writes now, and of an older
build of a pair that an interrupted run left behind.
indexed_at is the time of the newest build. The three are
present only when a build config is readable.
A ``warning`` key means that the database is corrupt — the
integrity check or a read of the database failed, thus the tool
counts nothing and the three count fields are absent.
On failure the dict holds only ``error`` with the reason.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | Must be True to execute. Call without confirm first as dry-run. | |
| project | No | 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. | |
| project_root | No | 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so: it declares the operation is not read-only, states that the SQLite database and WAL files are permanently destroyed, notes that corrupt databases can be deleted without opening them, and describes the dry-run vs deleted action values plus the corrupt-database `warning` path.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The destructive warning and the dry-run-first instruction are front-loaded ahead of the reference material, which is good structure. It is somewhat long and the Args block largely restates the 100%-covered schema, but the Returns detail earns its space because there is no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, zero-annotation tool with no output schema, the description covers everything an agent needs: destruction semantics, dry-run safety flow, the follow-up re-index command, the returned dict fields, the count-field caveat, and the failure and corruption cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents confirm, project, and project_root in nearly identical wording. The description adds only marginal detail (the corrupt-DB behavior and count fields), so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening line states a specific verb and resource ('Delete the entire symbol index for a project'), including the scope of the deletion. It is clearly distinguishable from the many read/search siblings and from reindex_file, which the description explicitly names as the follow-up action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It prescribes the exact workflow — call with confirm=False first as a dry-run, then re-index with 'fw-context index' afterwards. It also names the sibling list_projects for resolving the project parameter and explains when to prefer `project` over `project_root` (cross-project queries), explicitly saying to give one, not both.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_bodiesA
Find patterns in the TEXT OF A DEFINITION — the code inside its extent.
Searches ifdef-filtered text — only the code that compiles for the
build of the query. 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, onecaselabel of a longswitch.Types —
class,struct,union,enum,namespace. An enum constant, a bit field, a member declaration such asInterruptIn _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 NUManswers with the definitions that hold both.No prefix is implied.
SELF_TESTmatches the tokensself testand missesSelf tester; writeSELF_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 wordattach. Such a result carries_fallback: "sanitized"and_query_used. The hits whose body really holds.attach(are the ones withmatch_lines.search_codeandsearch_contentbehave 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_codecovers a macro name and value.search_contentcovers 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: 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. 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 query that FTS5 refuses to parse, also after the
repair, gives one dict with ``warning`` + ``hint`` — an empty list
always means "no such code", never "bad query". When a file that
the answer names changed on disk, a dict with ``warning`` comes
first; an empty answer gets it too when indexed files changed.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Optional kind filter: function, method, class, etc. | |
| image | No | 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. | |
| limit | No | Maximum results of one page (default 20, max 100). | |
| query | Yes | FTS5 search terms for the body of a definition. 1-3 words. E.g. 'attach', 'callback', 'rise'. | |
| offset | No | Skip this many results. Reads the next page of a pattern with many hits. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_only | No | Exclude vendor SDK code. When True, only application code. Default False. | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden and does so richly: read-only, requires FTS5 index, may auto-reindex stale files, ifdef-filtered semantics, punctuation sanitization producing _fallback/_query_used, source truncation limits (2000/500 chars), warning-first dicts on file change, and the [] = no-match vs warning = bad-query distinction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Content-dense and every section earns its place, but it is a very long wall of prose with some repetition (e.g. the search_code contrast is restated in several places). The key routing rule is front-loaded, but the size is well beyond what is needed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists yet the description still pins down the non-obvious return contract (page notice fields, match_lines vs line, underscore-prefix convention, error/warning dicts). For a 9-parameter tool with build-selection complexity, nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (baseline 3), but the description materially exceeds it: the query FTS5 grammar (space = AND not OR, no implied prefix, wildcard needed, phrase quoting), the project/project_root mutual exclusivity, and variant/image build-selection rules that the terse schema lines do not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb and resource: find patterns in the stored TEXT of a definition, i.e. the code inside its extent. It immediately bounds scope (only text, not name/signature/docstring/summary) and explicitly contrasts with search_code, search_content, and get_source, so an agent can place it among its 37 siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use routing: 'search_bodies — patterns in the code; search_code — symbols by NAME; search_content — full file text'. It also names the boundary cases (preprocessor directives, extern "C", file-scope declarations) and redirects to search_content for them, plus when to set project_only=True vs default.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_codeA
Find C/C++ symbols by name — searches function/class/enum NAMES.
Searches symbol names, qualified names, signatures, docstrings, and
pre-computed name tokens (CamelCase/snake_case split). Does NOT search
function bodies — for patterns in code like .attach(,
interrupt handler registrations, callback attachments use search_bodies instead.
Use when you know the concept but not the exact name
("interrupt handler", "modem init"). Prefer lookup_symbol
when you already know the exact or prefix name.
Results hold the metadata of each symbol — name, location, signature, docstring — not its implementation code.
FTS5 syntax:
Every bare term gets a trailing
*and the terms are OR-joined:modem initgoes to FTS5 asmodem* OR init*and answers with the symbols that hold EITHER word.search_bodiesdoes the opposite — it takes the query literally, where a space is an AND. A query that holds a double quote,AND,OR,NEARor a column filter goes to FTS5 as written.init*matches init, init_uart, initialize (trailing wildcard)"spi init"matches the exact phrase "spi init"Do NOT use an underscore in a query. The tokenizer splits
modem_initinto two tokens and looks for them NEXT TO EACH OTHER. That is a phrase and not an AND, thus the query missesmodem_parser_oob_init. Measured on one firmware index,serial_writegave 1 result andserial writegave 200. Writemodem initinstead.Punctuation is not searchable. The tokenizer drops it, thus
.attach(becomes a phrase that looks for the tokenattach. The query is repaired, never rejected.
Progressive relaxation: when a step matches nothing, the next one
runs. Six steps can run. Step 1 is the primary path and its results
carry NO _fallback key; each step after it names itself there:
FTS5 with the
kindfilter. No_fallbackkey.FTS5 without the kind, when the kind matched nothing; operators often guess the wrong kind —
_fallback="fts5".name_tokenssubstring match over the pre-computed CamelCase / snake_case tokens (BuildTypeis indexed as"build type"). Needs N−1 of N query terms —"name_tokens_like".LIKE over the docstring column, for a single-term query that the token steps missed —
"docstring_like".FTS5 per query word, results merged —
"individual_terms".macros_ftsfor#definenames and values, kind="macro" —"macros_fts".
Steps 3-6 ignore kind.
Kind filter values: function, method, constructor,
destructor, class, struct, union, enum, enum_constant,
typedef, varglobal, varlocal, variable, field,
namespace.
Local variables are out. FTS5 indexes the qualified name, thus a
local matches through the function that holds it: a query for
sensor used to answer with V, ret and tmp_value from
inside read_sensor_value, 4 of 20 results on one measured query.
A local is never the answer to "which symbol is about X", thus
varlocal and the legacy variable kind are excluded.
varglobal stays — a global carries architectural weight. Ask for
them explicitly with kind="varlocal", or use find_variables.
After fw-context index --analyze, a result also holds
llm_analysis — {summary, inputs, outputs}. A model wrote that
text, and the code did not. Treat it as a hint that points you at a
symbol, never as a fact to quote. Quote source from
get_source, signature, or docstring.
Read-only: yes. May auto-reindex stale files (non-blocking). When a file that the answer names changed on disk, this tool starts the watcher daemon in the background and answers from the index it has.
Args: query: FTS5 search terms. Keep queries short — 1–3 words. 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. 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 topic that many symbols carry; the page notice names the offset to use. One relaxation step owns the whole answer, thus a walk never changes the step under the reader. project_only: When True, exclude vendor SDK directories and return only application code. Default False. 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. The page notice leads the answer — total,
offset, shown, more — where total counts the
answer of the step that answered. Each symbol that follows has
name, qualified_name, kind, file, line, is_definition, signature,
docstring, is_template, is_virtual, is_pure_virtual. Enum
constants include enum_value with the integer value. May also
include template_usr, parent_usr, and llm_analysis
({summary, inputs, outputs} — written by a model, not by the
code. get_build_info().analysis.model names it). Fallback
results include _fallback with the method name. A macro
result also holds _macro_value and _macro_expanded_value
when they are not empty.
No match gives ``[]``. A dict with ``error`` means the query
failed. When FTS5 refuses the query and no LIKE step finds a row,
the answer is one dict with ``warning`` + ``hint``. When a file
that the answer names changed on disk, a dict with ``warning``
comes BEFORE the page notice — find the notice by its keys, and
not by its position. An empty answer gets that ``warning`` too
when indexed files changed: the code can be in them.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Optional kind filter: function, method, constructor, destructor, class, struct, union, enum, enum_constant, typedef, varglobal, varlocal, variable, field, namespace. | |
| image | No | 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. | |
| limit | No | Maximum results of one page (default 20, max 100). | |
| query | Yes | FTS5 search terms. 1-3 words, omit underscores. E.g. 'modem init' not 'modem_init'. Supports trailing wildcard 'modem*'. | |
| offset | No | Skip this many results. Reads the next page of a topic that many symbols carry. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_only | No | Exclude vendor SDK code. When True, only application code. Default False. | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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 thoroughly: declares read-only, discloses the non-blocking auto-reindex and background watcher-daemon start, enumerates the six progressive-relaxation steps with their _fallback keys, and specifies error/warning/empty-answer behaviors. It even flags that llm_analysis is 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and well sectioned, but it is very long and repeats content already in structured data — the full kind-value list is duplicated verbatim from the schema, and the Returns section restates much of what the output schema covers. Most sentences earn their place given the tool's real complexity, but it is longer than necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter tool with FTS5 query semantics and a six-step fallback pipeline, nothing an agent needs is missing — query syntax, build selection, pagination, failure modes, and result shape are all covered. An output schema exists, so the extra Returns detail is surplus rather than a gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 goes well beyond it: FTS5 tokenization semantics, the underscore prohibition with measured evidence, the OR-join vs search_bodies' AND behavior, project vs project_root mutual exclusion, variant/image single-build selection, and pagination/offset semantics tied to the relaxation step.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+scope ('Find C/C++ symbols by name — searches function/class/enum NAMES') and immediately carves out what it is not ('Does NOT search function bodies ... use search_bodies instead'). It names sibling alternatives (search_bodies, lookup_symbol) 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use ('Use when you know the concept but not the exact name'), explicit when-not (bodies → search_bodies; exact/prefix names → lookup_symbol; local vars → find_variables), and it documents the kind-filter guessing case. Alternatives and their selection conditions are all named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_contentA
Find patterns in FULL file content — the whole file, not only the text that belongs to a definition.
Searches ifdef-filtered file text — only code that actually compiles
for the build of the query. Inactive #ifdef branches are
replaced with blank lines (preserving original line numbers). A pattern
that lives only in a dead branch therefore gives no result, and that
empty answer is the correct one: the code does not compile.
Covers the text that belongs to no definition, which is what
search_bodies cannot see: #include, #define, #ifdef,
extern "C", and a comment or declaration at file scope. It covers
the text of definitions too. To find a symbol by NAME (modem init,
interrupt handler), use search_code.
Not a fallback of search_bodies — its complement. The two
answer different questions and reach different text:
search_bodiesanswers WHICH DEFINITION holds the pattern, and takes the query literally (no wildcard, space = AND).search_contentanswers WHICH FILES the topic touches, and widens the query: every term gets a trailing*and the terms are OR-joined. The wider query reaches text the literal one misses — measured on one project,SELF_TESTfound 6 files here and the same word found 5 throughsearch_bodies, the extra file holding the commentSelf tester.
For the footprint of one feature, run both.
Results are file-level — one entry per matching file, with
match_lines for the lines that hold a query term.
project_only=True filters to is_project = 1 files; the default
False includes the vendor SDK files.
When files_fts is missing (legacy index), falls back to LIKE
search on files.content — results include _fallback: "like"
and no snippet highlighting. Run fw-context index to upgrade.
The LIKE search splits the query on spaces and underscores and needs
EVERY word as a substring (AND, not OR).
Read-only: yes. Requires the FTS5 index with file content. May
auto-reindex stale files (non-blocking) — see search_code.
Args:
query: FTS5 search terms. 1-3 words. Bare multi-word queries are
OR-joined (prefix-wildcarded). Prefer single-word queries.
E.g. 'InterruptIn', 'extern C', '#define'.
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.
limit: Maximum results of one page (default 20, max 100).
offset: Skip this many results. Reads the next page of a topic
that many files touch; the page notice names the offset to use.
project_only: When True, filter to project code only (files with is_project = 1).
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. The page notice leads the answer — total,
offset, shown, more — and each that follows holds:
file, language, mtime, _match_snippet (highlighted excerpt around
the match).
Also, when it carries an answer:
* ``match_lines`` (list[int]) — line numbers of the lines that hold
a query term, up to 20. They are the line numbers of the file
itself: an inactive ``#ifdef`` branch is a blank line, thus the
count never shifts. Cite ``file:line`` from here.
The field is absent when FTS5 matched a variant of the token that
the term is not a substring of — ``SELF_TEST`` matches the file
that writes ``Self tester``, and no line holds ``self_test``.
Read ``_match_snippet`` in that case.
No match gives ``[]``. A dict with ``error`` means the query
failed. A query that FTS5 refuses to parse prepends a dict with
``warning`` + ``hint`` — the answer then comes from the LIKE path
and carries ``_fallback: "like"``. When a file that the answer
names changed on disk, a dict with ``warning`` comes first; an
empty answer gets it too when indexed files changed.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| limit | No | Maximum results of one page (default 20, max 100). | |
| query | Yes | FTS5 search terms for full file content. 1-3 words. E.g. 'InterruptIn', 'extern C'. Bare multi-word = OR-joined. | |
| offset | No | Skip this many results. Reads the next page of a topic that many files touch. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_only | No | Exclude vendor SDK code. When True, only application code. Default False. | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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 richly: read-only, requires the FTS5 file-content index, auto-reindexes stale files non-blocking, silences inactive #ifdef branches into blank lines, falls back to LIKE (with _fallback marker, no highlighting) when files_fts is missing, and emits leading warning/error dicts including on empty answers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and organized under clear sections (purpose, contrast, semination, read-only notes, Args, Returns), with every paragraph doing work. It is long, but the complexity of an 8-param, multi-path tool justifies most of it; the Args block partially duplicates the schema descriptions, which is the main slack.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 8 parameters, a real output schema, and a fallback code path, the description is complete: it explains the filtering model, build-selection prerequisites, query semantics, pagination, and the shape of the returns (match_lines, _match_snippet, warning/error notices) an agent needs to interpret results correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, but the description still adds meaning beyond it: query terms get a trailing '*' and are OR-joined, single-word queries are preferred, project vs project_root are mutually exclusive alternatives, offset reads the next page named by the page notice, and project_only filters is_project=1.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+scope: 'Find patterns in FULL file content — the whole file, not only the text that belongs to a definition.' It explicitly distinguishes itself from search_bodies (complement, not fallback) and search_code (name lookup), so an agent can route correctly without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use and when-not: use search_code for symbol names, use both search_content and search_bodies for a feature footprint, and names the query-widening difference (OR-joined prefix wildcards vs literal AND) that makes the two reach different text. Also states variant/image must be supplied by the agent since fw-context does not pick a build.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
semantic_searchA
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_tandModemMsg*classes."delivery box"findsset_shipmentandget_zrtdata."power consumption"findsget_load_powerand 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 precision0.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.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| limit | No | Maximum results on one page (default 20). Held between 1 and 100. | |
| query | Yes | Natural language description, 5-15 words. E.g. 'parcel locker state machine' or 'how does the modem connect?'. | |
| offset | No | Skip this many results. Reads the next page of the symbols above the threshold. | |
| project | No | 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. | |
| variant | No | 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. | |
| threshold | No | Minimum cosine similarity (0.0-1.0). Default 0.60. Use 0.55 for exploratory, 0.50 for broad search. | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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.
smart_searchA
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:
Translate non-English queries
Rough search to gather sample symbols for naming conventions
LLM sees those samples + query and generates FTS5 terms
FTS5 search with generated terms
Refine: LLM checks results and course-corrects query terms
Semantic embedding search (cosine similarity re-rank)
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.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| limit | No | Maximum results on one page (default 20). Held between 1 and 100. | |
| query | Yes | Natural language description, 5-15 words. E.g. 'how does the modem connect?' or 'handle BLE pairing failure'. | |
| offset | No | Skip this many results of the previous search of this query. 0 (the default) is a new search. | |
| project | No | 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. | |
| variant | No | 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. | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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.
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.
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.
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.
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.
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.
trace_data_flowA
Trace how C/C++ data of a given type flows to a target function via libclang call paths. libclang-powered: finds functions by type signature and maps call paths through the full call graph, which text-based search cannot trace across translation units.
Finds definitions whose signature mentions type_name (substring match, any symbol kind, most-called first), then looks for call paths from those to to_symbol. Returns a data flow map — useful for understanding how a data structure travels through the system to its destination.
Works best for synchronous driver stacks (e.g. sensor read → I2C write).
Cannot follow async flows (message queues, interrupts, RS485 callbacks).
For exact call-graph queries use the find_* family;
verify specific paths with find_call_path.
Read-only. No side effects. Requires the reference index
(fw-context index — refs on by default).
Args:
type_name: Type name to trace. E.g. 'SensorData' or
'Config::SensorData'.
to_symbol: Target symbol name. E.g. 'uart_send' or
'UART_DRIVER::send'.
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.
max_depth: Maximum call path depth (default 8, max 20).
limit: Maximum source functions to trace (default 15, max 15).
offset: Skip this many source functions. Reads the next page;
the page notice names the offset to use.
timeout_ms: Maximum total execution time in milliseconds
(default 30000). Clamped to 1000–300000. The budget is for
one page.
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 rows of the answer: total counts every source function that matches. Then
a _summary entry for this page:
{_summary (str), _type (str), _target (str)}, followed by source
entries each with: source_name, source_qualified_name, source_kind,
source_file (absolute), source_line, caller_count, reachable
(bool), and paths (up to 3 path dicts as find_call_path gives
them; the key is absent when unreachable). When to_symbol
matches more than one symbol, a source entry also holds the
warning that names them, and each path its
target_qualified_name.
A source entry with ``timed_out: True`` means that the time budget
ran out before the search for that source began. Its
``reachable: False`` thus means "not checked", not "proved
unreachable". Such a source counts as shown, thus the hint goes
past it. To check it, call again with the same ``offset``: each
page gets the whole time budget.
A source entry with ``budget_spent: True`` means that the path
search of that source spent its budget of node expansions. Its
``reachable: False`` thus means "not found", not "proved
unreachable".
A page after the last source function gives one ``info`` dict
that names the total. Never empty: one dict with ``error`` or
``info`` replaces an empty result. Check both keys first.
| Name | Required | Description | Default |
|---|---|---|---|
| image | No | 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. | |
| limit | No | Maximum source functions to trace (default 15, max 15). | |
| offset | No | Skip this many source functions. Reads the next page. | |
| project | No | 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. | |
| variant | No | 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. | |
| max_depth | No | Maximum call path depth (default 8, max 20). | |
| to_symbol | Yes | Target symbol name. E.g. 'uart_send' or 'UART_DRIVER::send'. | |
| type_name | Yes | Type name to trace. E.g. 'SensorData' or 'Config::SensorData'. | |
| timeout_ms | No | Maximum total execution time in milliseconds (default 30000). | |
| project_root | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
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/no side effects, requires the reference index (with the enabling command), states the async-flow limitation, and explains subtle partial-result semantics (timed_out means 'not checked', budget_spent means 'not found', not 'proved unreachable').
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose, limitations, and alternatives are front-loaded, which is good, but the long Args and Returns blocks largely restate the input schema and output schema (both fully documented). Since an output schema exists, the two-paragraph explanation of page notice, _summary, source entries, and error/info dicts is largely redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 10-parameter call-graph tracer, the description covers use cases, hard limitations, index prerequisites, pagination, timeout budgeting, and ambiguous-result handling. An agent has everything needed to invoke it correctly, with return-value detail additionally backed by an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3, but the description adds real meaning beyond the schema: max_depth cap of 20, the 1000–300000 clamp on timeout_ms, the per-page nature of the timeout budget, and the offset pagination hint. The project/project_root 'give one, not both' rule mostly repeats the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb+resource: tracing how C/C++ data of a given type flows to a target function via libclang call paths. It explicitly contrasts itself with text-based search and names the sibling family (find_* / find_call_path), so an agent can distinguish it without opening other schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit positive cases ('works best for synchronous driver stacks, e.g. sensor read → I2C write') and exclusions ('cannot follow async flows: message queues, interrupts, RS485 callbacks'). It also routes to alternatives — find_* for exact call-graph queries and find_call_path to verify specific paths.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.35.0- Changed
reindex_file3 fields changed- changed
Input schema / properties / file_path / descriptionPrevious value: -"Path to the file to re-parse. A source file must be in compile_commands.json. A header goes through one translation unit that includes it, and the result then carries a warning about the other units."New value: +"Absolute or project-relative path to the file to re-parse. A source file must have an entry in compile_commands.json. A header is re-parsed through one translation unit that includes it, and the result then carries a warning that other units can still hold stale symbols." - changed
Input schema / properties / project_root / descriptionPrevious 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."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." - added
Input schema / properties / with_analysisAdded value: +{ + "default": true, + "description": "When True (default), also regenerates the LLM symbol analysis and the embeddings — slower, because the two need a model. Set False for a fast update: the tool skips the two, and get_project_status then reports the symbols that wait for them. The method overrides, the PageRank scores and the hotspot cache are rebuilt in the two modes when reference indexing is on (`[index] index_refs`).", + "title": "With Analysis", + "type": "boolean" +}
- Removed
reindex_file_impl
37 tool updates
v0.32.1- Changed
configure_llm9 fields changed- added
Input schema / properties / auto_pull / anyOfAdded value: +[ + { + "type": "boolean" + }, + { + "type": "null" + } +] - changed
Input schema / properties / auto_pull / defaultPrevious value: -falseNew value: +null - changed
Input schema / properties / auto_pull / descriptionPrevious value: -"Auto-pull models on 404 (Ollama only). False for intranet."New value: +"Auto-pull models on 404 (Ollama only). False for intranet. None = keep current." - removed
Input schema / properties / auto_pull / typeRemoved value: -"boolean" - added
Input schema / properties / chat_api_format / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - changed
Input schema / properties / chat_api_format / defaultPrevious value: -"auto"New value: +null - changed
Input schema / properties / chat_api_format / descriptionPrevious value: -"Format override: 'auto' (default), 'ollama', or 'openai'."New value: +"Format override: 'ollama' or 'openai'; 'auto' returns to detection from the URL. None = keep current." - removed
Input schema / properties / chat_api_format / typeRemoved value: -"string" - changed
Input schema / properties / embed_model / descriptionPrevious value: -"Embedding model name (Ollama only). None = keep current."New value: +"Embedding model: an Ollama tag, a sentence-transformers name (e.g. 'BAAI/bge-small-en-v1.5'), or 'ft://latest'. None = keep current."
- Changed
explain_symbol3 fields changed- changed
Input schema / properties / context_lines / descriptionPrevious value: -"Lines of source context around the symbol definition."New value: +"Lines of source context around the symbol definition (1-200)." - changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_all_callers_recursive3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Reads the next page of a deep call tree.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_call_path3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / max_depth / descriptionPrevious value: -"Maximum BFS depth for path search (default 10)."New value: +"Maximum BFS depth from each end of the search (default 10). A path can hold up to 2 x max_depth edges." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_callees_recursive3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Reads the next page of a deep call tree.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_callers2 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_dead_code4 fields changed- changed
Input schema / properties / exclude_paths / descriptionPrevious value: -"Additional LIKE patterns to exclude. Merged with defaults from config. E.g. ['lib/%']."New value: +"LIKE patterns on the project-relative file path to exclude, on top of project_only. E.g. ['lib/%']." - changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / project_only / descriptionPrevious value: -"When True (default), auto-excludes SDK/vendor paths based on the detected build system and applies project config exclude_paths. Set False to see all results."New value: +"When True (default), keeps only project code (is_project, from the vendor_paths/project_paths config and SDK detection). Set False to see all results." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_hotspots3 fields changed- changed
Input schema / properties / exclude_paths / descriptionPrevious value: -"Additional LIKE patterns to exclude. Merged with defaults. E.g. ['lib/%']."New value: +"LIKE patterns on the project-relative file path to exclude, on top of project_only. E.g. ['lib/%']." - changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_indirect_call_sites4 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results (default 50)."New value: +"Maximum results (default 50, max 200)." - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Reads the next page of a long answer.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_indirect_targets3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Reads the next page of a long answer.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_references3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results of one page."New value: +"Maximum results of one page (default 50, max 200)." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_variables5 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / kind / descriptionPrevious value: -"Filter by kind: 'varglobal', 'varlocal', 'field', or None for all."New value: +"Filter by kind: 'varglobal', 'varlocal', 'field', legacy 'variable', or None for all." - changed
Input schema / properties / name / descriptionPrevious value: -"Variable name or prefix to search. Uses LIKE match (e.g. 'g_' finds g_debug_level, g_state)."New value: +"Variable name or part of it. Substring match on name and qualified name (e.g. 'g_' finds g_debug_level, g_state)." - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many variables. Reads the next page of a name that many variables share.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_wrapper_callers6 fields changed- changed
Input schema / properties / class_name / descriptionPrevious value: -"Driver class name to find wrappers for. E.g. 'UART_DRIVER' or 'hal::UART_DRIVER'."New value: +"Driver class name to find wrappers for. E.g. 'UART_DRIVER' or 'hal::UART_DRIVER'. Case-sensitive." - changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / defaultPrevious value: -50New value: +20 - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum wrapper method results (default 50, max 50)."New value: +"Maximum wrapper classes on one page (default 20, max 100)." - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many wrapper classes. Reads the next page.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Removed
get_active_build - Added
get_build_info - Changed
get_class_members5 fields changed- changed
Input schema / properties / class_name / descriptionPrevious value: -"Class or struct name. E.g. 'ModemManager' or 'the Mbed project::ZMODEM'."New value: +"Class or struct name. E.g. 'ModemManager' or 'comm::MODEM'." - changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / limitAdded value: +{ + "default": 200, + "description": "Maximum members on one page (default 200, max 500).", + "minimum": 1, + "title": "Limit", + "type": "integer" +} - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many members. Reads the next page of a large class.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Removed
get_environment_status - Changed
get_file_map5 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / kindAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "One symbol kind, e.g. 'function' or 'enum_constant'. Gives one page of the items of that kind.", + "title": "Kind" +} - changed
Input schema / properties / max_per_kind / descriptionPrevious value: -"Max items per symbol kind group (default 30, 0 = unlimited)."New value: +"Max items per symbol kind group (default 30, 0 = unlimited). With kind, the size of the page." - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "With kind: skip this many items of that kind. Reads the next page.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_inheritance_chain4 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / limitAdded value: +{ + "default": 100, + "description": "Maximum classes in all_bases and in all_derived on one page (default 100, max 500). Only with transitive=True.", + "minimum": 1, + "title": "Limit", + "type": "integer" +} - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many classes in all_bases and in all_derived. Reads the next page of a large hierarchy. Only with transitive=True.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_method_overrides2 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Added
get_project_status - Changed
get_source3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / name / descriptionPrevious value: -"Fully qualified symbol name. Returns exact function body via libclang extent."New value: +"Symbol name, or qualified name (Class::method) to select one symbol. Returns exact function body via libclang extent." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_symbol_context3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / name / descriptionPrevious value: -"Symbol name. Returns body, signature, all direct callers and callees."New value: +"Symbol name. Returns body, signature, the direct callers and callees (each list with its total)." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_template_instances3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many instances. Reads the next page of a template with many instances.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_vector_table5 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum slots (default 400)."New value: +"Maximum slots (default 400, max 1000)." - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many slots. Reads the next page of a long table.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / unhandled_only / descriptionPrevious value: -"Return only the slots that reach the default handler."New value: +"Return only the slots with status 'unhandled' (an alias of a default handler, nothing installed at run time)." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
list_projects1 field changed- changed
Input schema / properties / project_root / descriptionPrevious value: -"Project root. Auto-detected if omitted. Pass to distinguish multiple indexed projects. This field also accepts a project name or a project_id, but project is the clear field for those."New value: +"Project root whose config names the index directory; pass it to distinguish multiple indexed projects that keep separate index directories. Omitted = the global config. Every project in that directory is listed. This field also accepts a project name or a project_id, but project is the clear field for those."
- Removed
list_variants - Changed
lookup_symbol2 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
read_file3 fields changed- changed
Input schema / properties / end_line / descriptionPrevious value: -"Last line to return, 1-based inclusive. 0 = to the end of the file."New value: +"Last line to return, 1-based inclusive. 0 = one page of at most 2000 lines." - changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
reindex_file2 fields changed- added
Input schema / properties / imageAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Image of the one build to re-parse: a separate program, such as the application or the bootloader. Give it when that build has an image name.", + "title": "Image" +} - added
Input schema / properties / variantAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Variant of the one build to re-parse. Omit it and image to re-parse the file in each build that compiles it. A part of a pair gets an error that lists the builds.", + "title": "Variant" +}
- Changed
reindex_file_impl3 fields changed- added
Input schema / properties / imageAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Image of the one build to re-parse: a separate program, such as the application or the bootloader. Give it when that build has an image name.", + "title": "Image" +} - added
Input schema / properties / variantAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Variant of the one build to re-parse. Omit it and image to re-parse the file in each build that compiles it. A part of a pair gets an error that lists the builds.", + "title": "Variant" +} - changed
Input schema / properties / with_analysis / descriptionPrevious value: -"When True (default), also regenerates LLM symbol analysis and method override relationships — slower but produces a fully up-to-date index. Set False for a fast symbol-only update (used by background auto-reindex)."New value: +"When True (default), also regenerates LLM symbol analysis, method override relationships, PageRank and embeddings — slower but produces a fully up-to-date index. Set False for a fast symbol-only update."
- Changed
search_bodies2 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
search_code2 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
search_content2 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
semantic_search4 fields changed- added
Input schema / properties / imageAdded 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" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results (default 20, max 100)."New value: +"Maximum results on one page (default 20). Held between 1 and 100." - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Reads the next page of the symbols above the threshold.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
smart_search4 fields changed- added
Input schema / properties / imageAdded 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" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results (default 20, max 100)."New value: +"Maximum results on one page (default 20). Held between 1 and 100." - added
Input schema / properties / offsetAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
trace_data_flow3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many source functions. Reads the next page.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
30 tool updates
v0.32.0- Changed
explain_symbol4 fields changed- added
Input schema / properties / context_lines / minimumAdded value: +0 - changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_all_callers_recursive5 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / max_depth / minimumAdded value: +1 - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_call_path5 fields changed- added
Input schema / properties / from_name / minLengthAdded value: +1 - changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / max_depth / minimumAdded value: +1 - added
Input schema / properties / to_name / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_callees_recursive5 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / max_depth / minimumAdded value: +1 - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_callers6 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results."New value: +"Maximum results of one page (default 50, max 200)." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / name / minLengthAdded value: +1 - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Reads the next page of a symbol with many call sites.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_dead_code5 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results (default 100)."New value: +"Maximum results of one page (default 100, max 200)." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Reads the next page of a long report.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_hotspots5 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Number of top-called functions to return (default 20)."New value: +"Number of top-called functions per page (default 20, max 50)." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Reads further down the ranking.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_indirect_call_sites4 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_indirect_targets4 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_references6 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results."New value: +"Maximum results of one page." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / name / minLengthAdded value: +1 - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Reads the next page of a symbol with many references.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_variables4 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
find_wrapper_callers5 fields changed- added
Input schema / properties / class_name / minLengthAdded value: +1 - changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum wrapper method results (default 50)."New value: +"Maximum wrapper method results (default 50, max 50)." - added
Input schema / properties / limit / minimumAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_class_members3 fields changed- added
Input schema / properties / class_name / minLengthAdded value: +1 - changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_file_map4 fields changed- added
Input schema / properties / file_path / minLengthAdded value: +1 - changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / max_per_kind / minimumAdded value: +0 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_inheritance_chain3 fields changed- added
Input schema / properties / class_name / minLengthAdded value: +1 - changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_method_overrides3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / method_name / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_source3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_symbol_context3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / name / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_template_instances5 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results (default 50)."New value: +"Maximum results (default 50, max 200)." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / template_name / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
get_vector_table3 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / limit / minimumAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
lookup_symbol5 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / name / minLengthAdded value: +1 - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Pages through a name that many classes share, such as 'read' or 'write'.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
read_file5 fields changed- added
Input schema / properties / end_line / minimumAdded value: +0 - added
Input schema / properties / file_path / minLengthAdded value: +1 - changed
Input schema / properties / image / descriptionPrevious 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." - added
Input schema / properties / start_line / minimumAdded value: +0 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
reindex_file1 field changed- added
Input schema / properties / file_path / minLengthAdded value: +1
- Changed
reindex_file_impl1 field changed- added
Input schema / properties / file_path / minLengthAdded value: +1
- Changed
search_bodies6 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results (default 20, max 100)."New value: +"Maximum results of one page (default 20, max 100)." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Reads the next page of a pattern with many hits.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - added
Input schema / properties / query / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
search_code6 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results (default 20, max 100)."New value: +"Maximum results of one page (default 20, max 100)." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Reads the next page of a topic that many symbols carry.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - added
Input schema / properties / query / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
search_content6 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum results (default 20, max 100)."New value: +"Maximum results of one page (default 20, max 100)." - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Skip this many results. Reads the next page of a topic that many files touch.", + "minimum": 0, + "title": "Offset", + "type": "integer" +} - added
Input schema / properties / query / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
- Changed
semantic_search4 fields changed- added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / query / minLengthAdded value: +1 - added
Input schema / properties / threshold / maximumAdded value: +1 - added
Input schema / properties / threshold / minimumAdded value: +0
- Changed
smart_search2 fields changed- added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / query / minLengthAdded value: +1
- Changed
trace_data_flow9 fields changed- changed
Input schema / properties / image / descriptionPrevious 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." - changed
Input schema / properties / limit / descriptionPrevious value: -"Maximum source functions to trace (default 15)."New value: +"Maximum source functions to trace (default 15, max 15)." - added
Input schema / properties / limit / minimumAdded value: +1 - changed
Input schema / properties / max_depth / descriptionPrevious value: -"Maximum call path depth (default 8)."New value: +"Maximum call path depth (default 8, max 20)." - added
Input schema / properties / max_depth / minimumAdded value: +1 - added
Input schema / properties / timeout_ms / minimumAdded value: +1 - added
Input schema / properties / to_symbol / minLengthAdded value: +1 - added
Input schema / properties / type_name / minLengthAdded value: +1 - changed
Input schema / properties / variant / descriptionPrevious 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."
39 tool updates
v0.30.0- Changed
check_dependencies3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious value: -"Project root. Auto-detected if omitted. Pass explicitly when the project is not the server cwd."New value: +"Project root. Auto-detected if omitted. Pass explicitly when the project is not the server cwd. This field also accepts a project name or a project_id, but project is the clear field for those."
- Changed
check_ollama3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious value: -"Project root. Auto-detected if omitted. Used to locate LLM config. Falls back to auto-detection when omitted."New value: +"Project root. Auto-detected if omitted. Used to locate LLM config. Falls back to auto-detection when omitted. This field also accepts a project name or a project_id, but project is the clear field for those."
- Changed
configure_llm3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
explain_symbol3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
find_all_callers_recursive3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
find_call_path3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
find_callees_recursive3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
find_callers3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
find_dead_code3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
find_hotspots3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
find_indirect_call_sites3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious value: -"Project root directory. Auto-detected if omitted."New value: +"Project root directory. Auto-detected if omitted. This field also accepts a project name or a project_id, but project is the clear field for those."
- Changed
find_indirect_targets3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
find_references3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
find_variables3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
find_wrapper_callers3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
get_active_build4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / fast / descriptionPrevious 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." - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
get_class_members4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / class_name / descriptionPrevious value: -"Class or struct name. E.g. 'ModemManager' or 'zbox::ZMODEM'."New value: +"Class or struct name. E.g. 'ModemManager' or 'the Mbed project::ZMODEM'." - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
get_environment_status3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious value: -"Project root. Auto-detected if omitted. Pass explicitly when the project is not the server cwd."New value: +"Project root. Auto-detected if omitted. Pass explicitly when the project is not the server cwd. This field also accepts a project name or a project_id, but project is the clear field for those."
- Changed
get_file_map3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
get_inheritance_chain3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
get_method_overrides3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
get_project_info1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_source3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
get_symbol_context3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
get_template_instances3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Added
get_vector_table - Changed
list_projects3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious value: -"Project root. Auto-detected if omitted. Pass to distinguish multiple indexed projects."New value: +"Project root. Auto-detected if omitted. Pass to distinguish multiple indexed projects. This field also accepts a project name or a project_id, but project is the clear field for those."
- Changed
list_variants3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
lookup_symbol3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
read_file6 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / end_lineAdded value: +{ + "default": 0, + "description": "Last line to return, 1-based inclusive. 0 = to the end of the file.", + "title": "End Line", + "type": "integer" +} - added
Input schema / properties / line_numbersAdded value: +{ + "default": false, + "description": "Prefix every line with its line number, like get_source. Default False (bare text).", + "title": "Line Numbers", + "type": "boolean" +} - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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." - added
Input schema / properties / start_lineAdded value: +{ + "default": 0, + "description": "First line to return, 1-based inclusive. 0 = from the start of the file.", + "title": "Start Line", + "type": "integer" +}
- Changed
reindex_file4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / file_path / descriptionPrevious value: -"Path to source file to re-parse. Must be in compile_commands.json."New value: +"Path to the file to re-parse. A source file must be in compile_commands.json. A header goes through one translation unit that includes it, and the result then carries a warning about the other units." - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
reindex_file_impl4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / file_path / descriptionPrevious value: -"Absolute or project-relative path to the source file to re-parse. Must have a matching entry in compile_commands.json."New value: +"Absolute or project-relative path to the file to re-parse. A source file must have an entry in compile_commands.json. A header is re-parsed through one translation unit that includes it, and the result then carries a warning that other units can still hold stale symbols." - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
reset_index3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
search_bodies4 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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." - changed
Input schema / properties / query / descriptionPrevious 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'."
- Changed
search_code3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
search_content3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
semantic_search3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
smart_search3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
- Changed
trace_data_flow3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / projectAdded 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" +} - changed
Input schema / properties / project_root / descriptionPrevious 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."
1 tool update
v0.27.6- Changed
get_active_build1 field changed- changed
Input schema / properties / fast / descriptionPrevious 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'."
30 tool updates
v0.25.3- Added
check_dependencies - Changed
check_ollama1 field changed- changed
Input schema / properties / project_root / descriptionPrevious value: -"Project root. Auto-detected if omitted. Ignored by this tool."New value: +"Project root. Auto-detected if omitted. Used to locate LLM config. Falls back to auto-detection when omitted."
- Added
configure_llm - Changed
explain_symbol2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
find_all_callers_recursive2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
find_call_path2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
find_callees_recursive2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
find_callers2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
find_dead_code2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
find_hotspots2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
find_indirect_call_sites2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
find_indirect_targets2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
find_references2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
find_variables2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
find_wrapper_callers2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
get_class_members2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Added
get_environment_status - Changed
get_file_map2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
get_inheritance_chain2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
get_method_overrides2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
get_source2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
get_symbol_context2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
get_template_instances2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Added
list_variants - Changed
lookup_symbol2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
read_file2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
search_bodies2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
search_code2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
search_content2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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" +}
- Changed
trace_data_flow2 fields changed- added
Input schema / properties / imageAdded 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" +} - added
Input schema / properties / variantAdded 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 tool updates
v0.25.2- Added
find_variables - Changed
get_active_build1 field changed- added
Input schema / properties / fastAdded 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" +}
- Changed
get_inheritance_chain1 field changed- changed
Input schema / properties / class_name / descriptionPrevious value: -"Class or struct name to get inheritance information for. E.g. 'UART_DRIVER' or 'zbox::ZMODEM'."New value: +"Class or struct name to get inheritance information for. E.g. 'UART_DRIVER' or 'comm::MODEM'."
- Changed
search_code1 field changed- changed
Input schema / properties / kind / descriptionPrevious value: -"Optional kind filter: function, method, class, struct, union, enum, typedef, variable, field, namespace."New value: +"Optional kind filter: function, method, constructor, destructor, class, struct, union, enum, enum_constant, typedef, varglobal, varlocal, variable, field, namespace."
- Changed
trace_data_flow1 field changed- added
Input schema / properties / timeout_msAdded value: +{ + "default": 30000, + "description": "Maximum total execution time in milliseconds (default 30000).", + "title": "Timeout Ms", + "type": "integer" +}
1 tool update
v0.24.0- Changed
get_symbol_context1 field changed- removed
Input schema / properties / project_onlyRemoved value: -{ - "default": true, - "description": "When True (default), filters callers and callees to project paths (excludes SDK/vendor).", - "title": "Project Only", - "type": "boolean" -}
2 tool updates
v0.22.1- Added
get_project_info - Added
read_file
4 tool updates
v0.18.2- Changed
find_dead_code1 field changed- changed
Input schema / properties / project_only / descriptionPrevious value: -"When True (default), auto-excludes SDK/vendor paths (mbed-os/%, .pio/%, zephyr/%, build/%) and applies project config exclude_paths. Set False to see all results."New value: +"When True (default), auto-excludes SDK/vendor paths based on the detected build system and applies project config exclude_paths. Set False to see all results."
- Changed
search_bodies2 fields changed- changed
Input schema / properties / project_only / descriptionPrevious 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." - changed
Input schema / properties / query / descriptionPrevious 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'."
- Changed
search_code1 field changed- changed
Input schema / properties / project_only / descriptionPrevious value: -"Exclude vendor SDK code (mbed-os/, .pio/, zephyr/). When True, only application code (src/, lib/, app/). Default False."New value: +"Exclude vendor SDK code. When True, only application code. Default False."
- Changed
search_content1 field changed- changed
Input schema / properties / project_only / descriptionPrevious 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."
TDQS
Scored across 37 tools
Many tools share broad purposes—six search tools and a large family of call-graph/reference tools—so an agent can confuse semantic_search with smart_search or search_code, and get_source with get_symbol_context. The extensive descriptions and explicit cross-references help, but overlap remains substantial, especially in search.
All names are snake_case, mostly following a verb_noun pattern (get_, find_, search_, check_, list_, reset_). Minor deviations are adjective_noun forms such as semantic_search and smart_search, but the set is highly predictable overall.
37 tools is far beyond the 3-15 sweet spot and exceeds the 25-tool threshold that indicates overload. Many are narrow variants of search, reference, and call-graph queries, making the set difficult to navigate at a glance.
The query surface is very comprehensive—symbol search, call graph, references, vector table, dead code, class hierarchy, variables—but lifecycle coverage has notable gaps. There is no tool to initialize a project or trigger a full index/build; only reset_index and single-file reindex_file exist, forcing agents to fall back to CLI instructions for central setup operations.
Maintenance
Related MCP Connectors
Ask a codebase what calls what: search, blast radius, paths between symbols, and diffs.
Code intelligence for coding agents: semantic, AST, graph, and full-text search. 279+ languages.
Search indexed code, trace dependencies, assess change impact, and recall repository memory.
Code intelligence for LLMs. Analyze, search, and retrieve code from any public git repository.
Related MCP Servers
- AlicenseAqualityAmaintenanceKnot is a semantic and structural codebase indexer designed for AI coding agents and developers navigating large projects. It combines vector search and graph traversal to find code by meaning, analyze impact via reverse dependencies, and explore file architectures.78MIT

Semantic Code Search MCPofficial
AlicenseNot gradedqualityDmaintenanceProvides AI coding agents with structured access to indexed codebases via semantic search, symbol analysis, and file reading tools.13Server Side Public , v 1- AlicenseNot gradedqualityDmaintenanceEnables LLM agents to efficiently understand and navigate a codebase by providing semantic search over symbols and a reference graph, replacing expensive grep/glob calls with structured tools like definition lookup, caller/callee queries, and change-impact analysis.3MIT
- AlicenseNot gradedqualityCmaintenanceProvides intelligent code indexing with 15 MCP tools for symbol extraction, hybrid search (FTS5+vector), call graphs, and incremental indexing of local folders and remote repos, enabling token-efficient code retrieval for AI agents.3MIT