Define each command with typed input and output schemas. Get composability, structured JSON I/O, and LLM-ready manifests baked in — for humans, pipelines, and agents alike.
pnpm add fireargs zod commander
# or
npm install fireargs zod commanderimport { f } from "fireargs"
import { z } from "zod"
const greet = f
.command({ name: "greet", description: "Greet someone politely." })
.input(
z.object({
name: f.argument().string().describe("The user's name."),
times: z.number().default(1).describe("Repeat the greeting n times."),
verbose: f.option({ short: "v" }).boolean(),
}),
)
.output(z.object({ greeting: z.string() }))
.handler(input => ({
greeting: `hello ${input.name}`.repeat(input.times),
}))
greet.parseAsync(process.argv)That gets you:
$ greet world --times 3
$ greet world --json # CLI input, JSON output
$ greet --json '{"name":"world"}' # JSON input, JSON output
$ greet --llms # MCP-shaped manifest for LLMs
$ greet --helpGroup leaves with f.program(...).commands({ ... }):
const cli = f
.program({ name: "myapp", description: "My CLI", version: "1.0.0" })
.commands({ greet, deploy, db: dbCli })
cli.parseAsync(process.argv)Programs nest — commands accepts other programs the same way it accepts
leaves. myapp db migrate --json '...' routes through both levels.
Every command and program ships with --llms, which prints an
MCP-tools/list-shaped manifest:
{
"tools": [
{ "name": "help", "description": "Documentation tool, not callable. ...", "inputSchema": {}, "outputSchema": {} },
{ "name": "greet", "description": "...", "inputSchema": { ... }, "outputSchema": { ... } },
{ "name": "db migrate", "description": "...", "inputSchema": { ... }, "outputSchema": { ... } }
]
}An LLM agent reads the manifest, picks a tool, and invokes it with
<binary> <name> --json '<value>'. Output comes back as JSON on stdout.
- Commands — the
f.command(...)chainable builder. - Inputs —
f.argument()/f.option()and per-field commander config. - Outputs — the output schema, serialization, and JSON Schema in
--llms. - Programs — subcommand trees, nesting, and program-level config.
- JSON mode —
--jsonfor programmatic and pipeline use. - LLMs mode —
--llmsand the MCP-shaped manifest. - Composability — share common params across commands by composing zod schemas.
- Contributing — local setup, conventions, release flow.
MIT.