zag
One CLI for all your AI coding agents.
zag wraps Claude, Codex, Gemini, Copilot, and Ollama behind a single command so you can switch between them without learning five different CLIs. It adds cross-provider features on top: model size aliases, automatic provider/model selection, git worktree isolation, Docker sandboxing, structured JSON output with schema validation, unified session logs, and a programmatic Rust API.
Why zag?
- One CLI, five agents — Switch between Claude, Codex, Gemini, Copilot, and Ollama without learning five different CLIs
- Cross-provider features — Model size aliases, JSON schema validation, git worktree isolation, and Docker sandboxing work with every provider
- Orchestration primitives — Spawn, wait, collect, pipe, and chain agents in shell scripts for multi-agent workflows
- Programmatic API — Rust library crate plus TypeScript, Python, C#, Swift, Java, and Kotlin SDKs
Prerequisites
- Rust 1.85+ (edition 2024) — for building from source
- git — required for
--worktreeisolation - Docker — required for
--sandboxisolation (optional) - At least one agent CLI installed (see below)
Install
From crates.io
From GitHub Releases
Download a pre-built binary from GitHub Releases, extract it, and place it in your PATH.
From source
As a library
Agent CLIs
You need at least one underlying agent CLI installed:
| Provider | Install command | Link |
|---|---|---|
| Claude | curl -fsSL https://claude.ai/install.sh | bash |
docs |
| Codex | npm install -g @openai/codex |
repo |
| Gemini | npm install -g @anthropic-ai/gemini-cli |
repo |
| Copilot | npm install -g @github/copilot |
docs |
| Ollama | See ollama.com/download | site |
zag checks for the required binary before running and provides install hints if it's missing.
Quick start
# Interactive session with Claude (the default provider)
# Non-interactive — prints the response and exits
# Pick a different provider
# Use size aliases instead of provider-specific model names
# Let an LLM pick the best provider and model for the task
# Code review (delegates to Codex)
Providers
| Provider | Default model | Size aliases (small / medium / large) |
|---|---|---|
| claude | default | haiku / sonnet / default |
| codex | gpt-5.4 | gpt-5.4-mini / gpt-5.3-codex / gpt-5.4 |
| gemini | auto | gemini-3.1-flash-lite-preview / gemini-2.5-flash / gemini-3.1-pro-preview |
| copilot | claude-sonnet-4.6 | claude-haiku-4.5 / claude-sonnet-4.6 / claude-opus-4.6 |
| ollama | qwen3.5:9b | 2b / 9b / 35b (parameter sizes, any model from ollama.com) |
Size aliases let you write zag -m large exec "..." and get the right model regardless of which provider you're using. For Claude, default delegates model selection to the Claude CLI itself.
Commands
zag run [prompt] Interactive session (optional initial prompt)
zag exec <prompt> Non-interactive — print output and exit
zag review Code review (--uncommitted, --base, --commit)
zag config [key] [value] View or set configuration
zag session list|show|import|delete|update List/inspect/manage sessions
zag listen <id> Tail a session's log events in real-time
zag ps list|show|stop|kill List, inspect, and manage agent processes
zag search <query> Search through session logs
zag input [message] Send a user message to a single session
zag broadcast [message] Send a message to all sessions in the project
zag spawn <prompt> Launch background agent, return session ID
zag spawn -I [prompt] Spawn long-lived interactive session (FIFO-based)
zag wait <id>... [--timeout] Block until session(s) complete
zag status <id> Machine-readable session health check
zag collect [--tag <tag>] Gather results from multiple sessions
zag env [--session <id>] Export session environment variables
zag pipe <ids>... -- <prompt> Chain session results into a new session
zag events <id> [--type ...] Query structured events from session logs
zag cancel <id>... [--tag] Gracefully cancel running sessions
zag summary <id>... [--tag] Log-based session summary and stats
zag watch <id> --on <event> Execute command on matching log events
zag subscribe [--tag <tag>] Multiplexed event stream from all sessions
zag log <message> [--session] Append custom event to a session log
zag output [<id>] [--latest] Extract final result text from a session
zag retry <id>... [--failed] Re-run failed sessions with same config
zag gc [--force] [--older-than] Clean up old session data and logs
zag serve [--port] [--token] Start HTTP/WS server for remote access
zag connect <url> --token Connect to a remote zag server
zag disconnect Disconnect from remote server
zag capability Show provider capability declarations
zag skills list|show|add|remove|sync|import Manage provider-agnostic skills
zag mcp list|show|add|remove|sync|import Manage MCP servers across providers
zag whoami Show current session identity (for agents)
zag man [command] Built-in manual pages
Flags
| Flag | Short | Description |
|---|---|---|
--provider <name> |
-p |
claude, codex, gemini, copilot, ollama, auto |
--model <name> |
-m |
Model name, size alias (small/medium/large), or auto |
--system-prompt <text> |
-s |
Appended to the agent's system prompt |
--root <path> |
-r |
Root directory for the agent |
--auto-approve |
-a |
Skip permission prompts |
--add-dir <path> |
Additional directories to include (repeatable) | |
--env <KEY=VALUE> |
Environment variable for the agent subprocess (repeatable) | |
--worktree [name] |
-w |
Run in an isolated git worktree |
--sandbox [name] |
Run inside a Docker sandbox | |
--json |
Request structured JSON output | |
--json-schema <schema> |
Validate output against a JSON schema | |
--json-stream |
Stream JSON events (NDJSON) | |
--session <uuid> |
Pre-set the session ID | |
--name <name> |
Human-readable session name (for discovery) | |
--description <text> |
Short description of the session's purpose | |
--tag <tag> |
Session tag (repeatable, for discovery/filtering) | |
--max-turns <n> |
Maximum number of agentic turns | |
--timeout <duration> |
Timeout duration (e.g., 30s, 5m, 1h). Kills the agent if exceeded. | |
--mcp-config <config> |
MCP server config: JSON string or file path (Claude only) | |
--size <size> |
Ollama parameter size (e.g., 2b, 9b, 35b) | |
--show-usage |
Show token usage statistics (JSON output mode) | |
--debug |
-d |
Debug logging |
--quiet |
-q |
Suppress all output except the agent's response |
--verbose |
-v |
Styled output with icons in exec mode |
Session management
Every interactive session gets a session ID. You can name and tag sessions for discovery, resume them, and zag tracks provider-native session IDs automatically.
# Create sessions with metadata for discovery
# Resume a specific session
# Resume the most recent session
# List and filter sessions
# Send messages by name
# Broadcast to all sessions in the project (or filter by tag)
# Update session metadata
# Tail a session's logs in real-time (from another terminal)
Orchestration
zag provides primitives for launching, synchronizing, and collecting results from multiple agent sessions. These are building blocks — not an orchestration engine — designed for shell scripts and pipelines.
# Spawn parallel agents
sid1=
sid2=
sid3=
# Check health
# Block until all finish (exit code reflects success)
# Collect results
# Feed a session's result into a new agent
# Propagate agent failure as a non-zero exit code
||
# Export session env for nested invocations
# Query parent-child process trees
# Filter listen to specific event types
# Chain session results into a new agent session
# Query structured events from a session log
# Gracefully cancel sessions
# Get session summaries (no LLM call — log-based)
# Watch for events and react
# Subscribe to a multiplexed event stream from all sessions
|
# Long-lived interactive sessions (Claude only)
sid=
# DAG workflows with spawn dependencies
sid_a=
sid_b=
sid_c=
sid_d=
Filesystem lifecycle markers are written to ~/.zag/events/ (.started and .ended files) for external non-Rust orchestrators that prefer inotifywait over polling.
Remote access
Run agents on your home machine and control them from anywhere (mobile, laptop, another server).
# On the server machine — start the zag server
# Output: Generated token: a1b2c3...
# With TLS (recommended for non-VPN networks)
# On the client machine — connect to the server
# Now all commands transparently proxy through the remote server
# Spawn an interactive session on the remote machine
sid=
# Disconnect when done
The server exposes REST and WebSocket endpoints at /api/v1/. See zag man serve and zag man connect for details.
Worktree and sandbox isolation
# Worktree: isolated git worktree per session
# Sandbox: Docker microVM isolation
# Both track sessions — resume restores the correct workspace
After interactive sessions, you're prompted to keep or remove the workspace. Exec sessions with changes are kept automatically with a resume command printed.
JSON output
# Request JSON output
# Validate against a schema (inline or file path)
# Stream events as NDJSON
Claude uses its native --json-schema support. Other providers get JSON instructions injected into the system prompt. On validation failure, zag retries up to 3 times via session resume.
Output formats
With exec -o <format>:
| Format | Description |
|---|---|
| (default) | Streamed text — beautiful formatting for Claude, plain for others |
text |
Raw agent output, no parsing |
json |
Compact unified JSON (AgentOutput) |
json-pretty |
Pretty-printed unified JSON |
stream-json |
NDJSON event stream (unified format) |
native-json |
Claude's raw JSON format (Claude only) |
Configuration
Per-project config lives at ~/.zag/projects/<sanitized-path>/zag.toml. Falls back to ~/.zag/zag.toml outside of git repos.
[]
= "claude"
= "medium"
= false
# max_turns = 10
# system_prompt = ""
[]
= "opus"
= "gpt-5.4"
[]
= "claude"
= "sonnet"
[]
= "qwen3.5"
= "9b"
Settings priority: CLI flags > config file > agent defaults.
Skills
zag supports provider-agnostic skills using the Agent Skills open standard. Skills are stored in ~/.zag/skills/ and automatically synced to each provider's native skill directory via symlinks.
MCP Servers
Manage MCP (Model Context Protocol) servers across all providers from a single place. Each server is stored as an individual TOML file in ~/.zag/mcp/ (global) or ~/.zag/projects/<path>/mcp/ (project-scoped), and synced into each provider's native config format with a zag- prefix.
Supported providers: Claude (~/.claude.json), Gemini (~/.gemini/settings.json), Copilot (~/.copilot/mcp-config.json), Codex (~/.codex/config.toml).
Programmatic API
The zag-agent crate exposes an AgentBuilder for driving agents from Rust code:
use AgentBuilder;
let output = new
.provider
.model
.auto_approve
.exec
.await?;
println!;
See the zag-agent crate for the full API including JSON schema validation, custom progress handlers, and interactive sessions.
Language bindings
SDK packages are available for TypeScript, Python, C#, Swift, Java, and Kotlin. Each wraps the zag CLI and exposes a fluent builder API with typed output models.
TypeScript (bindings/typescript/)
import { ZagBuilder } from "@nlindstedt/zag-agent";
const output = await new ZagBuilder()
.provider("claude")
.model("sonnet")
.autoApprove()
.exec("write a hello world program");
console.log(output.result);
// Streaming
for await (const event of new ZagBuilder().provider("claude").stream("analyze code")) {
console.log(event.type);
}
Python (bindings/python/)
= await \
\
\
\
# Streaming
C# (bindings/csharp/)
using Zag;
var output = await new ZagBuilder()
.Provider("claude")
.Model("sonnet")
.AutoApprove()
.ExecAsync("write a hello world program");
Console.WriteLine(output.Result);
// Streaming
await foreach (var evt in new ZagBuilder().Provider("claude").StreamAsync("analyze code"))
{
Console.WriteLine(evt.Type);
}
Swift (bindings/swift/)
import Zag
let output = try await ZagBuilder()
.provider("claude")
.model("sonnet")
.autoApprove()
.exec("write a hello world program")
print(output.result ?? "")
// Streaming
for try await event in ZagBuilder().provider("claude").stream("analyze code") {
print(event)
}
Java (bindings/java/)
;
var output ;
System.out.;
// Streaming
for
Kotlin (bindings/kotlin/)
import zag.ZagBuilder
val output = ZagBuilder()
.provider("claude")
.model("sonnet")
.autoApprove()
.exec("write a hello world program")
println(output.result)
// Streaming
ZagBuilder().provider("claude").stream("analyze code").collect { event ->
println(event.type)
}
Examples
The examples/ directory contains complete projects demonstrating zag usage:
- cv-review — A Rust program that uses the
zaglibrary crate to review CVs against job descriptions using parallel agent invocations - orchestration — Shell scripts demonstrating multi-agent patterns: sequential pipelines, fan-out/gather, generator-critic loops, coordinator dispatch, and more
- react-claude-interface — A React web app that provides a Claude Code-like chat interface powered by
zag execandzag inputwith streaming NDJSON events over Server-Sent Events
See the examples directory for details on each.
Troubleshooting
"CLI not found in PATH" — The agent CLI binary isn't installed or isn't in your PATH. Install it using the commands in the Agent CLIs table above.
"Invalid model 'X' for Y" — You specified a model name that the provider doesn't recognize. Use zag capability -p <provider> --pretty to see available models, or use size aliases (small, medium, large).
--worktree fails — You must be inside a git repository. The worktree is created under ~/.zag/worktrees/.
--sandbox fails — Docker must be installed and running. Sandbox mode uses docker sandbox run for microVM isolation.
Config not taking effect — Check which config file is being used with zag config path. Config is per-project (based on git repo root). CLI flags always override config.
Documentation
- Getting Started — Step-by-step tutorial for new users
- Providers — Feature comparison, model recommendations
- Configuration — Complete config reference
- Events & Logging — NDJSON event format reference
- Troubleshooting — Common issues and solutions
- Contributing — Development workflow and guidelines
zag man <command>— Built-in manual pages for every command
Architecture
zag (binary crate)
CLI parsing (clap) → dispatch to zag-agent and zag-orch
Session logs, worktree/sandbox lifecycle, JSON mode, auto-selection
zag-agent (library crate)
Agent trait, provider implementations, AgentBuilder API
Config, output types, session logs, skills, process helpers
zag-orch (orchestration crate)
spawn, wait, collect, pipe, cancel, status, events
watch, subscribe, summary, retry, gc, and more
Each provider implementation spawns the respective CLI tool as a subprocess. The Agent trait defines the common interface (run, resume, cleanup, model resolution). AgentOutput normalizes output from all providers into a unified event stream.
Development