# CLI Reference

All Rocannon subcommands. For per-module help: `rocannon <fqcn> --help`.

## rocannon quickstart

Scaffold a localhost profile and print MCP client wiring.

    rocannon quickstart [--dir DIR] [--force]

Flag | Default | Description
--- | --- | ---
`--dir` | `.rocannon` | Directory to write the profile and inventory
`--force` | false | Overwrite existing files

Writes `quickstart.yml` (profile) and `inventory.ini` (localhost), then prints the exact `claude mcp add` and `.mcp.json` snippets for your client.

## rocannon mcp serve

Start the MCP server. This is the command your MCP client runs.

    rocannon mcp serve [--profile PROF] [--inventory INV] [--modules MOD]
                      [--transport stdio|http] [--log-level LEVEL]

Flag | Default | Description
--- | --- | ---
`--profile / -p` | auto-discover | Profile path or name from `.rocannon/profiles/`
`--inventory / -i` | — | Inventory file (repeatable). Alternative to --profile.
`--modules / -m` | — | Module/collection/namespace spec (repeatable)
`--transport` | `stdio` | `stdio` for MCP clients; `http` for HTTP/SSE transport
`--log-level` | `INFO` | `DEBUG` / `INFO` / `WARNING` / `ERROR`

Environment variables that tune the server:

Variable | Default | Description
--- | --- | ---
`ROCANNON_TIMEOUT` | 300 | Global execution timeout per tool call (seconds)
`ROCANNON_IDLE_TIMEOUT` | 60 | Idle timeout within a run
`ROCANNON_MAX_CONCURRENT_TOOLS` | 10 | Global concurrent tool call cap
`ROCANNON_MAX_CONCURRENT_PER_HOST` | 3 | Per-host concurrent cap
`ROCANNON_MAX_RESPONSE_BYTES` | 1 000 000 | Max response size before truncation
`ROCANNON_LOG_FORMAT` | text | Set to `json` for structured JSON logs
`ROCANNON_DATA_DIR` | CWD | Root for `.rocannon/playbooks/` writes

## rocannon mcp doctor

Construct the MCP server in-process and report what registered.

    rocannon mcp doctor [--profile PROF] [--inventory INV] [--modules MOD]

Prints tool count, resource count, resource template count, and prompt count. Use this to verify your profile before pointing an LLM at it.

## rocannon doctor

System health check: binaries, inventory parsing, optional connectivity ping.

    rocannon doctor [--profile PROF] [--inventory INV] [--ping]

Flag | Description
--- | ---
`--ping` | Smoke-test SSH connectivity to each inventory host

Checks: rocannon/fastmcp/ansible-core/ansible-runner versions, binary locations, env vars, configured timeouts, inventory host counts, Ansible config resolution.

## rocannon repl

Interactive operator shell. Drives the same MCP server in-process with tab completion, call history, and `.save` to write playbooks.

    rocannon repl [--profile PROF] [--inventory INV] [--modules MOD]

REPL dot commands:

Command | Description
--- | ---
`.help` | Show all commands
`.target [HOST]` | Show or set the default target for module calls
`.inventory` | List loaded hosts and groups
`.modules` | List registered module tools
`.doc <module>` | Show parsed schema for a module
`.history` | Recent calls this session
`.resources` | List MCP resources
`.prompts` | List saved playbook prompts
`.save <name> ["desc"]` | Commit this session as a playbook
`.ai <prompt>` | LLM-driven mode (requires `rocannon[ai]` + `ROCANNON_AI_MODEL`)
`.exit` | Quit

Module call syntax: `<module> target=<host> key=value ...`

    rocannon> ping target=webservers
    rocannon> ansible.builtin.command target=db01 cmd="systemctl status postgresql"
    rocannon> .save check-db "verify postgresql is running"

## rocannon run

Execute a single module ad-hoc, routing through the same executor the server uses.

    rocannon run <module> --target HOST -i INV [--arg key=val] [--args-file FILE]
                [--timeout SECS] [--check] [--diff] [--pretty]

    rocannon run ansible.builtin.copy --target webservers -i hosts \
      --arg src=/etc/nginx/nginx.conf --arg dest=/etc/nginx/nginx.conf.bak \
      --check --diff --pretty

## rocannon <fqcn>

Invoke a module directly as a top-level subcommand. Flags are generated from `ansible-doc` at call time.

    rocannon ansible.builtin.copy --target h1 -i hosts --src /etc/app.conf --dest /etc/app.conf
    rocannon ansible.builtin.command --target db01 -i hosts --cmd "pg_dump mydb" --record session.yml

Reserved flag | Description
--- | ---
`--target / -t` | Host or group from inventory (required)
`--inventory / -i` | Inventory file (overrides profile)
`--profile / -p` | Profile to resolve inventory from
`--record FILE` | Append this call to FILE as an Ansible play
`--check` | Dry-run (if the module supports it)
`--diff` | Show what would change
`--pretty` | Pretty-print JSON output
`--timeout SECS` | Override execution timeout

## rocannon doc

Prints the parsed schema for a module in the same format the MCP server uses.

    rocannon doc ansible.builtin.copy
    rocannon doc community.docker.docker_container --json

## rocannon search

Find modules by name or description substring, case-insensitive.

    rocannon search postgres --limit 20
    rocannon search "manage users"

## rocannon ls

List hosts, groups, or modules from a profile or inventory.

    rocannon ls hosts   --profile prod
    rocannon ls groups  --inventory hosts.yml
    rocannon ls modules --profile staging

## rocannon playbook

Manage saved playbooks under `.rocannon/playbooks/`.

    rocannon playbook list
    rocannon playbook show  <name>
    rocannon playbook run   <name> -i hosts [--check] [--diff] [--pretty]

`playbook run` bypasses the LLM and executes the saved steps directly through the executor. Fails fast on the first step that returns a non-successful status.