search_code
Find C/C++ symbols by name, signature, or docstring when you know the concept but not the exact identifier. Returns symbol metadata, not implementation bodies.
Instructions
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.
Input Schema
| 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 | Default |
|---|---|---|---|
| result | Yes |