Getting Started with the ant CLI: Deploy Claude Agents
From install to a running managed agent in under 10 minutes. The ant CLI is Anthropic's Go-based command-line client for the Claude API, and it's the fastest way to create, configure, and manage cloud-hosted agents without writing application code.
- The ant CLI is Anthropic's official Go-based CLI for the Claude API, launched April 2026. It manages agents, environments, and sessions from your terminal.
- Install on macOS with
brew install anthropics/tap/ant. Linux and Go installs are also supported. - Define agents as YAML files, check them into Git, and deploy through CI - full GitOps for your agent configs.
- Sessions cost $0.08/hour (billed to the millisecond) plus standard Claude token rates. Idle time is free.
What Is the ant CLI?
The ant CLI is Anthropic's official command-line client for the Claude API. It shipped alongside Claude Managed Agents on April 8, 2026, and it's built specifically for developers who want to create, configure, and run cloud-hosted agents without writing wrapper code. The GitHub repo already has over 300 stars in its first ten days.
It follows a resource-based command structure: ant [resource] <command> [flags...]. Think of it like kubectl for Claude agents. You can pipe YAML into it, extract fields with GJSON transforms, and chain commands in shell scripts. If you've worked with any modern infrastructure CLI, the patterns will feel familiar.
One thing to clarify early: the ant CLI and Claude Code solve different problems. Claude Code is your interactive coding assistant in the terminal - you talk to it, it writes code, and you pay through a subscription. The ant CLI is a programmatic API client for managing hosted agent infrastructure. You authenticate with an API key, and you're billed at standard API rates. I use both daily, and they complement each other well. Claude Code even understands how to shell out to ant natively.
How to Install the ant CLI
There are three installation paths depending on your platform. I'll cover all of them, but if you're on macOS, Homebrew is the fastest route.
macOS (Homebrew)
# Install from Anthropic's tap
brew install anthropics/tap/ant
# Clear the macOS quarantine flag (required)
xattr -d com.apple.quarantine "$(brew --prefix)/bin/ant"
# Verify
ant --versionThat quarantine step trips people up. macOS flags unsigned binaries downloaded by Homebrew, and without clearing it you'll get a "cannot be opened because the developer cannot be verified" error. It's a one-time thing.
Linux / WSL (curl)
VERSION=1.2.1
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m | sed -e 's/x86_64/amd64/' -e 's/aarch64/arm64/')
curl -fsSL \
"https://github.com/anthropics/anthropic-cli/releases/download/v${VERSION}/ant_${VERSION}_${OS}_${ARCH}.tar.gz" \
| sudo tar -xz -C /usr/local/bin antFrom Source (Go 1.22+)
go install github.com/anthropics/anthropic-cli/cmd/ant@latest
export PATH="$PATH:$(go env GOPATH)/bin"Set Your API Key
Once installed, set your Anthropic API key. The CLI reads it from the ANTHROPIC_API_KEY environment variable:
export ANTHROPIC_API_KEY="sk-ant-your-key-here"You can generate an API key from the Anthropic Console. I keep mine in a .env file that my shell sources on startup, but any secret management approach works.
Shell Completions
The ant CLI supports completions for bash, zsh, fish, and PowerShell. For zsh (the default macOS shell):
# Generate zsh completions
ant completion zsh > ~/.zfunc/_ant
# Add to your .zshrc if not already there
echo 'fpath=(~/.zfunc $fpath)' >> ~/.zshrc
echo 'autoload -Uz compinit && compinit' >> ~/.zshrcTab completion saves a lot of time when working with the beta: namespaced commands, which can get long.
Core Concepts - Agents, Environments, and Sessions
Before you create anything, it helps to understand how the four core pieces fit together. The mental model is straightforward once you see it.
A versioned configuration defining the model, system prompt, tools, and MCP server connections. Think of it as a blueprint. Each update creates a new version, so you can roll back if needed.
A container template specifying pre-installed packages (pip, npm) and networking rules. Create it once, reference it by ID. Multiple sessions can share one environment config, but each gets its own isolated container.
A running instance that pairs an agent with an environment. It has its own container, filesystem, and conversation history. Sessions are where the actual work happens.
The communication protocol. You send user events (messages, interrupts, tool confirmations) and receive agent events (messages, tool calls, thinking). Everything is event-based and streamable.
The flow works like this: you create an agent (the what), create an environment (the where), start a session linking them together, and then communicate through events. Anthropic handles the container orchestration, tool execution, and conversation state. According to the official docs, sessions cost $0.08 per session-hour billed to the millisecond, and idle time doesn't count.
Creating Your First Agent with the ant CLI
Let's build a simple code review agent. I'll walk through each step so you can see exactly what the CLI does at each stage. All managed agent commands sit under the beta: prefix since the feature is still in beta.
Step 1: Create the Agent
ant beta:agents create \
--name "Code Reviewer" \
--model claude-sonnet-4-6 \
--system "You are a senior code reviewer. Read the code carefully, check for bugs, security issues, and style problems. Be specific about line numbers and provide fix suggestions." \
--tool '{"type": "agent_toolset_20260401"}'The response comes back as JSON with the agent ID and version. I like to extract just the ID for scripting:
# Extract the agent ID
AGENT_ID=$(ant beta:agents create \
--name "Code Reviewer" \
--model claude-sonnet-4-6 \
--system "You are a senior code reviewer." \
--tool '{"type": "agent_toolset_20260401"}' \
--transform id --format raw)
echo "Created agent: $AGENT_ID"The --transform flag uses GJSON syntax to pluck a specific field from the response, and --format raw strips the quotes. This is one of the CLI's best features for scripting.
Step 2: Create an Environment
ENV_ID=$(ant beta:environments create \
--name "python-dev" \
--pip-packages '["pytest", "ruff", "mypy"]' \
--networking unrestricted \
--transform id --format raw)
echo "Created environment: $ENV_ID"Environments define what's pre-installed in the container. I'm giving this one Python linting tools since it's a code review agent. The unrestricted networking flag lets the agent fetch external resources if needed. You can also lock it down if you want a sandboxed environment.
Step 3: Start a Session
SESSION_ID=$(ant beta:sessions create \
--agent-id "$AGENT_ID" \
--environment-id "$ENV_ID" \
--transform id --format raw)
echo "Started session: $SESSION_ID"Step 4: Send a Message and Stream the Response
# Send a review request
ant beta:sessions:events send \
--session-id "$SESSION_ID" \
--type user.message \
--content-type text \
--content-text "Review this Python function for bugs:
def divide(a, b):
return a / b
"
# Stream the agent's response in real-time
ant beta:sessions stream --session-id "$SESSION_ID"The stream command opens a real-time SSE connection to the session. You'll see the agent's thinking, tool calls (it might run the code through ruff), and its final review - all printed to your terminal as they happen.
Tip: Want to explore the response interactively? Replace --format raw with --format explore on any command to open the TUI explorer. It lets you navigate nested JSON with arrow keys - really useful when debugging agent responses.
YAML Version Control for Agents
This is the ant CLI's best feature, and the one I haven't seen anyone write about yet. Instead of passing flags inline, you can define agents and environments as YAML files, check them into Git, and deploy through your CI pipeline.
name: Code Reviewer
model: claude-sonnet-4-6
system: |
You are a senior code reviewer. Read the code carefully,
check for bugs, security issues, and style problems.
Be specific about line numbers and provide fix suggestions.
tools:
- type: agent_toolset_20260401
configs:
- name: web_fetch
enabled: falsename: python-dev
pip_packages:
- pytest
- ruff
- mypy
networking: unrestrictedNow you can create the agent directly from the file:
# Create from YAML
ant beta:agents create < code-reviewer.agent.yaml
# Update an existing agent (version is required for safety)
ant beta:agents update \
--agent-id "$AGENT_ID" \
--version 1 \
< code-reviewer.agent.yamlThe versioning requirement matters. When you update an agent, you must pass the current version number. If someone else updated it since you last pulled, the command fails rather than silently overwriting. It's optimistic concurrency control - the same pattern you'd find in Kubernetes or Terraform.
This YAML approach is where the ant CLI really shines for teams. Your agent configs live in the same repo as your application code, go through pull request review, and deploy through the same pipeline. I wrote more about the broader Managed Agents architecture in my Managed Agents vs Agent SDK comparison, but the YAML workflow is what makes the CLI my preferred interface.
Why this matters: According to the official CLI docs, Anthropic designed the YAML workflow specifically for GitOps-style agent management. If you're already doing infrastructure as code, this slots right in.
ant CLI vs curl vs SDK - Why Use the CLI?
You can hit the Managed Agents API three ways: raw HTTP with curl, a language SDK (Python, TypeScript, Go, etc.), or the ant CLI. Each has its place.
| Feature | curl | ant CLI | Python SDK |
|---|---|---|---|
| Setup time | None | 2 minutes | 5 minutes |
| JSON body authoring | Manual | Typed flags / YAML | Typed objects |
| Auto-pagination | Manual | Built-in | Built-in |
| File references | Manual base64 | @path syntax | File objects |
| Response filtering | Pipe to jq | --transform | Code |
| Shell scripting | Verbose | Ergonomic | Requires Python |
| CI/CD fit | OK | Excellent | Good |
| Best for | Quick tests | Ops / automation | App integration |
The ant CLI sits in a sweet spot. It's faster than writing curl commands by hand (no JSON body construction, no header management), and lighter than pulling in a full SDK when you just want to script some agent operations. For anything that lives in a shell script or CI workflow, it's the right tool.
If you're building an application that embeds agent interactions - a web app, a Slack bot, a data pipeline - use the SDK. The ant CLI is for the operational layer: provisioning agents, rotating credentials, monitoring sessions, deploying config changes.
Scripting and Automation Patterns
Here are a few patterns I've found useful when automating agent workflows with the ant CLI.
Extract IDs from Create Commands
#!/bin/bash
set -euo pipefail
# Create agent and capture the ID
AGENT_ID=$(ant beta:agents create \
< agents/reviewer.agent.yaml \
--transform id --format raw)
# Create environment and capture the ID
ENV_ID=$(ant beta:environments create \
< agents/reviewer.environment.yaml \
--transform id --format raw)
echo "Agent: $AGENT_ID"
echo "Environment: $ENV_ID"
# Store for later use
echo "AGENT_ID=$AGENT_ID" >> .env.agents
echo "ENV_ID=$ENV_ID" >> .env.agentsGitHub Actions Deployment
name: Deploy Agents
on:
push:
branches: [main]
paths: ['agents/**']
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install ant CLI
run: |
curl -fsSL \
"https://github.com/anthropics/anthropic-cli/releases/download/v1.2.1/ant_1.2.1_linux_amd64.tar.gz" \
| sudo tar -xz -C /usr/local/bin ant
- name: Update agent config
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
ant beta:agents update \
--agent-id "${{ vars.AGENT_ID }}" \
--version "${{ vars.AGENT_VERSION }}" \
< agents/reviewer.agent.yamlList All Agents and Environments
# List agents in a readable table
ant beta:agents list --format yaml
# List environments with just names and IDs
ant beta:environments list --transform "data.#.{id,name}" --format yaml
# Check session status
ant beta:sessions retrieve \
--session-id "$SESSION_ID" \
--transform status --format rawThe --transform flag accepts full GJSON path syntax. You can filter arrays, project specific fields, and even do conditional extraction. It's much cleaner than piping to jq for simple extractions, though for complex transformations I still reach for jq.
What Tools Can Managed Agents Use?
When you include {"type": "agent_toolset_20260401"} in your agent config, it gets access to a standard set of tools: bash, read, write, edit, glob, grep, and web_fetch. All are enabled by default.
You can selectively disable tools you don't want the agent to have. For a read-only code review agent, you might disable write and edit:
name: Read-Only Reviewer
model: claude-sonnet-4-6
system: Review code without modifying it.
tools:
- type: agent_toolset_20260401
configs:
- name: write
enabled: false
- name: edit
enabled: false
- name: web_fetch
enabled: falseOr flip the default and whitelist only what you need:
tools:
- type: agent_toolset_20260401
default_config:
enabled: false
configs:
- name: bash
enabled: true
- name: read
enabled: trueAgents can also connect to external MCP servers for tools beyond the built-in set. If you've built a custom MCP server (like the Jenkins MCP server I wrote about), a managed agent can use it by adding an mcp_servers block to the agent config.
Frequently Asked Questions
Related Reading
Not sure whether to use Managed Agents or the Agent SDK? I wrote a full comparison with pricing math and a decision flowchart.
Read the comparisonCLAUDE.md patterns that managed agents can also benefit from. The system prompt patterns translate directly.
Read the guide