Modern CLI builder for the agentic era

Define each command with input and output schemas. Get composability, JSON I/O, and LLM-ready manifests baked in.

From schema to shipping CLI

Sane defaults, every escape hatch, no extra plumbing.

Schema-first

Inputs and outputs are zod schemas. Descriptions, defaults, choices, and variadics propagate to commander automatically.

Validated end-to-end

Zod validates every input before your handler runs and every output before it ships. One source of truth for types and runtime.

Fully composable

Share common parameters via zod composition (.extend, .merge, shape spread). Group leaves into programs and nest programs in programs — same builder shape at every level.

Built-in --json

Every command takes JSON in and emits JSON out via --json. Drive it from a script, a pipeline, or another agent — same binary.

Built-in --llms

Each binary publishes an MCP-shaped tools/list manifest. LLM agents read it and call straight back through --json.

Powered by Commander

The thing you get back is a commander Command. Every commander API stays available — fireargs just fills in the boring parts.

One schema, every interface

The same zod schema drives --help, --json, and the LLM manifest.

greet.ts
import { f } from "fireargs"
import { z } from "zod"

const greet = f
  .command({ name: "greet" })
  .input(z.object({
    name: f.argument().string(),
    times: z.number().default(1),
  })) 
  .output(z.object({ greeting: z.string() })) 
  .handler(input => ({
    greeting: `hello ${input.name}`.repeat(input.times),
  }))

greet.parseAsync(process.argv)
greet --llms
$ greet --llms
{
  "tools": [
    { "name": "help", ... }, 
    {
      "name": "greet",
      "description": "Greet someone politely",
      "inputSchema": { "type": "object", ... },
      "outputSchema": { "type": "object", ... }
    }
  ]
}

JSDoc descriptions surface in --help and the JSON Schema.

Defaults, choices, and optionality flow to commander automatically.

Every leaf gets --json '<value>' and --llms for free.

Stop hand-rolling argument parsers. Write a schema.

Install, write a command, ship a CLI that humans, scripts, and LLMs can all call.