Search
Search documentation
LLMs mode
Updated Oct 21, 2026
--llms prints a manifest describing every tool reachable through this
program, in the shape of MCP's tools/list
response. An LLM agent reads the manifest once and then calls back through
--json to actually invoke a tool.
Enabled by default on every command and program. Disable per command or
program with llms_option=False, or customize the flag and its help with
llms_option={"flags": ..., "description": ...}.
Manifest shape
{
"tools": [
{
"name": "help",
"description": "Documentation tool, not callable. Each `tools[].name` is the space-separated path beneath this binary. Invoke a tool with `<binary> <name> --json '<value>'` matching that tool's `inputSchema`; output is JSON on stdout matching `outputSchema`.",
"inputSchema": { "type": "object", "properties": {} },
"outputSchema": { "type": "object", "properties": {} }
},
{
"name": "greet",
"inputSchema": { "properties": { "name": { "description": "user's name", "title": "Name", "type": "string" }, ... }, "required": ["name"], "title": "GreetInput", "type": "object" },
"outputSchema": { "properties": { "greeting": { "title": "Greeting", "type": "string" } }, "required": ["greeting"], "title": "Greeting", "type": "object" },
"description": "Greet someone politely"
}
]
}MCP requires a tool's outputSchema to describe an object. A command with a
list or scalar output still gets a valid JSON Schema here, but an MCP client
that validates strictly will reject it: return a model from a CLI meant to be
served over MCP.
The reserved help tool
The first entry is always a help tool whose description carries the
calling convention. MCP descriptions are first-class and always surfaced to
the model, so this is the most reliable place to put guidance. Its schemas
are empty so an accidental invocation is a no-op.
How it composes for programs
The same shape comes back from a Program's --llms. Each leaf in the tree
becomes a tool whose name is the space-separated path:
myapp api greet --json '{"name":"world"}'⇒ tools[] entry with "name": "api greet". Nested programs flatten the
same way — myapp db migrate becomes "db migrate". A leaf mounted under two
router keys appears once per key; aliases add no tools.
Why MCP shape
MCP is the standard for exposing tools
to LLMs. Matching its tools/list shape means an MCP-aware client can
consume a fireargs CLI's --llms output directly, and the JSON Schemas
inside follow JSON Schema Draft 2020-12 — what every LLM tool-use framework
(Anthropic SDK, OpenAI function calling, …) already understands.
What flows from pydantic into the manifest
inputSchema is the input model's model_json_schema(mode="validation");
outputSchema is the output type's JSON Schema in serialization mode. Per
property they include:
type— derived from the Python type;X | Noneis ananyOfwithnull.title— pydantic adds one per field and per model.description— fromdescription=onField(...),Argument(...)orOption(...).default— from the field's default.enum— fromLiteral[...], or anEnumunder$defs.format,pattern,minimum,maxLength, … — from the type (datetime,UUID, …) and the field's constraints.requiredarray — fields without a default; inoutputSchemadefaulted fields too, exceptX | None = Noneones.$defsand$ref— nested models and enums.
inputSchema describes what --json accepts: a defaulted field is optional
there, keys are field names or their aliases, and a field with a
parse shows its own type, since
parse applies to CLI strings only. outputSchema describes the validated
value the handler's output becomes.
A type pydantic cannot describe — an arbitrary class allowed with
arbitrary_types_allowed — makes --llms fail with pydantic's
PydanticInvalidForJsonSchema. Keep input and output types to what JSON
Schema can express.
Fireargs config attached by Argument() / Option() (short flags,
env vars, conflicts, …) is not part of the JSON Schema in the manifest —
it's CLI-only and irrelevant to a JSON-mode call.
Dates
Pydantic reads and writes datetime, date and time as ISO 8601 strings
and documents them with format: date-time, date or time, so a date
round-trips through --json and an agent learns the wire format from the
manifest. See Outputs for the other rich
types.
Created with ❤ and Livemark