@bunny-agent/runner-cli
Bunny Agent Runner CLI - A lightweight, local command-line interface for running AI agents in your terminal.
Like gemini-cli, claude-code, or codex-cli, this tool runs directly on your local filesystem. It has two subcommands, one per output protocol: run streams AI SDK UI messages to stdout for a single task, and acp serves as a long-lived Agent Client Protocol agent over stdio for editors like Zed and JetBrains.
🎯 Key Features
- 🔌 Choose Different Runners: Switch between Claude, Codex, Gemini, Copilot with
--runnerflag - 🚀 Local Execution: Runs directly on your filesystem, no sandbox required
- 💨 Lightweight: No manager dependency, minimal overhead
- 📡 Streaming: Real-time AI SDK UI streaming (
run) or ACP JSON-RPC over stdio (acp)
📐 Architecture
runner-cli
├─ run → @bunny-agent/runner-harness → runner-claude / runner-codex / ...
└─ acp → @bunny-agent/server-acp → runner-harness → same runners
Dependencies:
✅ @bunny-agent/runner-harness (dispatches to every runner)
✅ @bunny-agent/server-acp (the `acp` subcommand's ACP agent + stdio transport)
❌ NO @bunny-agent/manager
❌ NO @bunny-agent/sandbox-*
Difference from manager-cli:
runner-cli: Local filesystem, no isolation, lightweight, direct runner usagemanager-cli: Sandboxed execution, uses manager + sandbox adapters + runner
Installation
# Global install (recommended if you want the `bunny-agent` command)
npm install -g @bunny-agent/runner-cli@latest
# Or add to a project
npm install @bunny-agent/runner-cli@latest
Usage
bunny-agent run [options] -- "<user input>"
Without installing globally, you can also run it via npx:
npx -y @bunny-agent/runner-cli@latest run -- "Create a hello world script"
Basic Examples
# Using Claude (default)
bunny-agent run -- "Create a hello world script"
# Explicitly choose Claude
bunny-agent run --runner claude -- "Create a hello world script"
# Using Codex
bunny-agent run --runner codex -- "Build a REST API with Express"
# Using Gemini
bunny-agent run --runner gemini -- "Build a REST API with Express"
# Using GitHub Copilot
bunny-agent run --runner copilot -- "Refactor this code"
# With custom system prompt
bunny-agent run --runner claude --system-prompt "You are a coding assistant" -- "Build a REST API with Express"
Options
| Option | Short | Description | Default |
|---|---|---|---|
--runner <runner> | -r | Runner to use: claude, codex, gemini, opencode, copilot, pi | claude |
--model <model> | -m | Model to use | claude-sonnet-4-20250514 |
--cwd <path> | -c | Working directory | Current directory |
--system-prompt <prompt> | -s | Custom system prompt | - |
--max-turns <n> | -t | Maximum conversation turns | - |
--allowed-tools <tools> | -a | Comma-separated list of allowed tools | - |
--yolo | - | Automatically approve tool permission requests | false |
--effort <level> | - | Reasoning effort or thinking level, depending on runner | - |
--resume <session-id> | - | Resume a previous session | - |
--help | -h | Show help message | - |
--allowed-tools limits built-in runner tools. Custom tools are provided
through the SDK streamText({ tools }) API, not directly through runner-cli.
Output Format
bunny-agent run always outputs AI SDK data stream (SSE) format, one-shot —
it runs the task and exits.
bunny-agent run -- "Calculate 2+2"
Output:
data: {"type":"start","messageId":"msg_123"}
data: {"type":"text-delta","id":"text_1","delta":"The answer is 4."}
data: [DONE]
For the ACP protocol instead, use bunny-agent acp — see below. The two are
separate subcommands, not a flag on run: ACP is a long-lived session
(initialize → session/new → possibly many session/prompt calls from the
connected editor), not a single request/response.
bunny-agent acp
Serves BunnyAgent as an Agent Client Protocol
agent over stdio — the transport editors use when they spawn an agent
binary directly, e.g. Zed's "custom agent" setup or JetBrains' AI Assistant
agent integration. The process stays alive handling JSON-RPC over
stdin/stdout until the connecting client disconnects; it does not take a
task argument like run does.
bunny-agent acp --runner claude
bunny-agent acp --runner pi --model gemini-2.0-flash --cwd ./my-project
| Option | Short | Description | Default |
|---|---|---|---|
--runner <runner> | -r | Runner to use: claude, codex, gemini, opencode, copilot, pi | claude |
--model <model> | -m | Model to use | claude-sonnet-4-20250514 |
--cwd <path> | -c | Working directory | Current directory |
--yolo | - | Automatically approve tool permission requests | false |
--help | -h | Show help message | - |
These flags set the session default. ACP's session/new has no native
runner/model field, so a connecting client can still override per-session
through the protocol's _meta extension, namespaced under "bunny-agent":
{ "cwd": "/workspace", "mcpServers": [],
"_meta": { "bunny-agent": { "runner": "pi", "model": "gemini-2.0-flash" } } }
Point an ACP client at the CLI itself as the agent command (exact configuration is client-specific — see each editor's ACP docs):
{ "command": "bunny-agent", "args": ["acp", "--runner", "claude"] }
For the HTTP equivalent (POST /api/coding/acp, used by the daemon instead
of a spawned subprocess), see
apps/daemon/README.md. Both are
backed by @bunny-agent/server-acp and support every runner this CLI does.
Environment Variables
| Variable | Description | Required |
|---|---|---|
ANTHROPIC_API_KEY | Anthropic API key (Claude runner) | No |
OPENAI_API_KEY or CODEX_API_KEY | OpenAI API key (Codex runner) | No |
GEMINI_API_KEY | Gemini API key (Gemini runner) | No |
GITHUB_TOKEN or GH_TOKEN | GitHub token (Copilot runner); falls back to the logged-in Copilot user | No |
BUNNY_AGENT_WORKSPACE | Default workspace path | No |
BUNNY_AGENT_LOG_LEVEL | Logging level (debug, info, warn, error) | No |
Advanced Examples
Specify Working Directory
bunny-agent run --cwd ./my-project -- "Fix the bug in main.ts"
Combined Options
bunny-agent run \
-m claude-sonnet-4-20250514 \
--system-prompt "You are a helpful coding assistant" \
--max-turns 10 \
-- "Build a REST API"
Architecture
The CLI is designed to:
- Execute in a specific working directory
- Load settings from
.claude/settings.jsonandCLAUDE.mdin the project - Stream AI SDK UI messages directly to stdout
- Output AI SDK data stream (SSE) format
🐳 Docker Image Build
Build Docker images with agent templates baked in:
# Build image
bunny-agent image build --name vikadata/bunny-agent-seo --tag 0.1.0 --template ./templates/seo-agent
# Build and push
bunny-agent image build --name vikadata/bunny-agent-seo --tag 0.1.0 --template ./templates/seo-agent --push
# Without template
bunny-agent image build --name vikadata/bunny-agent --tag 0.1.0
Image Build Options
| Option | Description | Default |
|---|---|---|
--name <name> | Full image name (e.g. vikadata/bunny-agent-seo) | bunny-agent |
--tag <tag> | Image tag | latest |
--image <full> | Full image name override (e.g. myorg/myimage:v1) | - |
--platform <plat> | Build platform | linux/amd64 |
--template <path> | Path to agent template directory | - |
--push | Push image to registry after build | false |
Related Documentation
- Skills — Where skills live and how they are loaded (local and Docker)
- Claude Agent SDK
- AI SDK UI Stream Protocol
- Agent Client Protocol — the protocol
bunny-agent acpspeaks - Runner maturity / output protocols — how
runandacpcompare