Dynamic Mode
The Falcon MCP server registers one tool schema per tool across all enabled modules. As the module set grows, this balloons the context window that AI clients must hold in every conversation — even for tools that will never be called in that session.
Dynamic mode solves this by replacing the full tool surface with three tools. Two are the
discovery pair: falcon_search_tools to find a tool and look up its parameter schema, and
falcon_execute_tool to run it. The third, falcon_list_enabled_tools, is always on and
returns the full inventory of Falcon tools available on the server. The agent fetches the
schema for exactly the tools it needs, paying a short discovery round-trip instead of a large
up-front context cost.
Enabling Dynamic Mode
Section titled “Enabling Dynamic Mode”Command-line flag:
falcon-mcp --dynamicEnvironment variable:
export FALCON_MCP_DYNAMIC=truefalcon-mcpIn .env file:
FALCON_MCP_DYNAMIC=trueDynamic mode can be combined with any other flag, including --modules to restrict which modules
are loaded into the catalog and --transport to choose the server transport.
How It Works
Section titled “How It Works”With dynamic mode enabled, the server exposes three tools instead of the full module surface —
the falcon_search_tools / falcon_execute_tool discovery pair plus the always-on
falcon_list_enabled_tools:
| Tool | Purpose |
|---|---|
falcon_list_enabled_tools | List the Falcon tools available on this server, grouped by the module each belongs to (meta-tools excluded) |
falcon_search_tools | Find tools by keyword or module, then return the parameters of the ones you name |
falcon_execute_tool | Execute a discovered tool by name with the given parameters |
The typical agent workflow is:
- Call
falcon_list_enabled_toolswhen you need to know what the server has at all — a name absent from that list is not available, whether because its module is off or a tool filter withholds it. Itsby_modulemap also publishes the module namesfalcon_search_toolsaccepts. - Call
falcon_search_toolswith a keyword or module name to see candidate tools, ordered by likely relevance, with theirread_onlyanddestructiveflags. The order is a keyword match, not a judgement of intent — read the descriptions and flags and pick the tool that fits. - Call
falcon_search_toolsagain withtool_namesset to the tool you picked, to get its parameters. - Call
falcon_execute_toolwith the tool name and parameters to run it.
Because falcon_execute_tool is a general dispatcher, it carries no read-only safety annotation by
default — the agent must rely on the read_only and destructive fields returned by
falcon_search_tools to understand a tool’s mutation risk before executing it. Those flags are
present on discovery results, so mutation risk is visible before the schema is fetched.
Two Response Shapes
Section titled “Two Response Shapes”falcon_search_tools answers two different questions, and returns a different shape for each.
Discovery — query and/or module, the default. Answers “which tool do I want?” Each result
carries name, module, description, read_only, and destructive, and deliberately no
parameters key. The absent key is the signal that a second call is needed; the hint field says so
explicitly.
Schema — tool_names. Answers “how do I call it?” Each named tool comes back as a full entry
including every parameter (type, required, description, examples) with FQL or CQL syntax hints
inlined. query, module, and limit are ignored. Naming two or more tools compares candidates in
a single call.
Splitting the two is what makes discovery cheap: on the full 117-tool catalog the input schema is roughly two thirds of an entry’s bytes, and at the moment of searching the agent has not chosen a tool to need it. A 50-result discovery response plus the schema for the one chosen tool costs slightly less than 20 results with schemas did.
If tool_names names something this server does not have, the response says which name and why —
withheld by a tool filter, or never available at all — rather than silently returning fewer entries,
which would read as a tool that takes no parameters.
Discover → Describe → Execute Example
Section titled “Discover → Describe → Execute Example”Step 1 — Find the right tool:
{ "tool": "falcon_search_tools", "arguments": { "query": "search detections", "module": "detections" }}The response is a results list alongside total and truncated. Each entry names the tool,
describes it, and flags whether it mutates — but carries no parameters.
Step 2 — Get its parameters:
{ "tool": "falcon_search_tools", "arguments": { "tool_names": ["falcon_search_detections"] }}Now the entry includes the full parameter schema, with FQL field hints already inlined for filter parameters.
Step 3 — Execute it:
{ "tool": "falcon_execute_tool", "arguments": { "tool_name": "falcon_search_detections", "parameters": { "filter": "severity_name:'Critical'+status:'new'", "limit": 10 } }}Results are returned in full. Use each tool’s limit parameter to control result volume and
avoid large responses.
Search Tips
Section titled “Search Tips”falcon_search_tools supports keyword and module filtering:
{ "query": "host containment", "limit": 5 }{ "module": "intel", "limit": 20 }{ "query": "quarantine release" }{ "tool_names": ["falcon_search_hosts", "falcon_get_host_details"] }Results are ordered by relevance. A tool whose name matches the query outranks one that only
mentions it in its description, and an exact tool name — with or without the falcon_ prefix —
ranks first. When two tools are otherwise tied — a bare noun like iocs matches falcon_search_iocs
and falcon_remove_iocs equally — the read-only one ranks first, so the order never steers toward a
mutator by default. Ordering is deterministic: the same query returns the same order on every server
process. A query with no keywords (module browsing) is ordered by tool name.
Every token in query is matched against the tool’s name, description, module, and parameter
names. Tools matching every token are preferred; when no tool matches all of them, the search falls
back to tools matching at least one, so a phrase like real-time response command returns ranked
candidates instead of nothing. The hint field says when that fallback was used. The order is a
keyword match with no view of intent, so read each candidate’s description and its read_only /
destructive flags and pick the one that fits, rather than taking the first row on trust.
module ignores case and separators, so hostgroups, host_groups, and Host-Groups all select
the same module. falcon_list_enabled_tools returns a by_module map whose keys are the exact
module names this server accepts; it comes from the same catalog the search dispatches from, so it
cannot drift from what module will match. A key groups the tools that belong to that module and
are available here — with --tools, that can be a subset of the module’s full surface, so module=
returns only what the map lists.
Every response carries total (the number of tools matching the query, before any limit) and
truncated, so a capped result set is never mistaken for the complete set. When results are
truncated, raise limit (up to 500) or narrow the query. The default is 50: lean discovery entries
are cheap enough that a wide window costs less than a narrow one did with schemas attached, so a
query like host — which matches 35 tools — is not truncated at all. In schema mode total counts
the entries returned, since no query ran for it to describe.
If no tools match, no word in the query appears anywhere in the available surface. The response says
so and points at falcon_list_enabled_tools. A capability absent from that full inventory is not
available on that server — report that rather than searching again.
Tool Filtering in Dynamic Mode
Section titled “Tool Filtering in Dynamic Mode”--read-only, --tools, and --exclude-tools apply here as they do in normal mode: a withheld
tool is absent from falcon_search_tools and cannot be run through falcon_execute_tool. Omitting
it from the catalog is the enforcement, so the executor is not a bypass.
Because a withheld tool is missing rather than flagged, its absence would otherwise be
indistinguishable from a tool that never existed — leading an agent to tell the user the capability
does not exist when the operator simply disabled it. This matters here in particular: dynamic mode
dispatches by name, so an agent can name a withheld tool, whereas in normal mode the tool is not in
tools/list at all. Two things prevent the misreport:
falcon_execute_toolon a withheld name reports that the tool exists but the server’s configuration withholds it, naming the single rule responsible —read-onlyordeny-list, not every rule the server has enabled — so an operator debugging their config is pointed at the right flag. A name that was never available still returns the plain unknown-tool error, so the two cases stay distinguishable. The message warns against reproducing the withheld effect through another tool, not against using other tools at all.falcon_list_enabled_toolscarries afilters_activefield describing the rules in effect. The field is absent when no filter is configured.
A tool from a module that was never enabled is not a filtered tool — it reports as unknown, since no rule withheld it.
When to Use Dynamic Mode
Section titled “When to Use Dynamic Mode”Dynamic mode is a good fit when:
- You enable a large number of modules and want to keep the context window lean.
- Your AI client has a limited context budget or charges per token of registered tool schemas.
- The agent only needs a small subset of tools per session but you want the full module set available.
The trade-off is the round-trips before a new tool call: one to find it, one to fetch its
parameters. For sessions that call a stable, known set of tools repeatedly, that overhead adds up —
though an agent that already knows the name can skip discovery and go straight to tool_names. For
exploratory or broad security-analysis workflows, dynamic mode often pays for itself quickly.