burgee

Getting started

One file, one command, and your agent connected to it while you write it.

1. Start it

npx burgee init my-cli && cd my-cli && npm install
node cli.mjs --name ada                # greeting: hello, ada

init writes two files: cli.mjs, the quick start from burgee's README, and a package.json that runs it. --install runs the install too, with the package manager you ran init under. Nothing it writes refers back to init.

2. Write the CLI

One file. No build step, no directory layout.

// cli.ts
import { defineCommand, defineProgram, run } from 'burgee';

export const program = defineProgram({
  name: 'hello',
  commands: [
    defineCommand({
      name: 'greet',
      description: 'Greet someone',
      effects: 'read_only',
      arguments: [{ name: 'name', required: true }],
      options: { shout: { type: 'boolean', description: 'uppercase it' } },
      run: ({ positionals, options }) => {
        const line = `Hello, ${positionals[0]}`;
        return options.shout ? line.toUpperCase() : line;
      },
    }),
  ],
});

if (import.meta.main) await run(program);

Already on commander or yargs? Swap the import for burgee/commander or burgee/yargs and export the Command or the yargs instance as program. Nothing else changes.

3. Keep your agent connected while you write it

npx burgee dev ./cli.ts

burgee dev serves the program as an MCP server on stdio and watches the entry. On every save it re-imports the file as a fresh module graph, swaps the served tools, sends notifications/tools/list_changed so a connected client re-lists, and prints on stderr what changed and the rendered help. Point your agent's MCP configuration at that command and it sees a command the moment it is written — no rebuild, no restart.

It is a developer tool and nothing more: a CLI built without ever running it is byte for byte the same, and nothing a shipped CLI imports can reach it.

4. Everything else is already there

node cli.ts greet ada --shout          # HELLO, ADA
node cli.ts greet ada --json           # {"ok":true,"data":"Hello, ada","meta":{...}}
node cli.ts --schema                   # the program as JSON Schema
node cli.ts --mcp                      # the same server, without the watcher
node cli.ts completion zsh             # a static completion script

Every one of those is a projection of the declaration above. See agent surfaces for what each one carries.

On this page