Claude-skill-registry headless-cli-agents
Build agentic systems using Claude CLI in headless mode or the Claude Agent SDK. Use when building automation pipelines, CI/CD integrations, multi-agent orchestration, or programmatic Claude interactions. Covers CLI flags (-p, --output-format), session management (--resume, --continue), Python SDK (claude-agent-sdk), custom tools, and agent loop patterns.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/headless-cli-agents" ~/.claude/skills/majiayu000-claude-skill-registry-headless-cli-agents && rm -rf "$T"
manifest:
skills/data/headless-cli-agents/SKILL.mdsource content
Headless CLI Agents
Build agentic systems using Claude Code CLI or the Claude Agent SDK.
CLI Headless Mode
Use
-p flag for non-interactive execution:
# Basic query claude -p "Explain this code" # With JSON output for parsing claude -p "Create a REST API" --output-format json # Streaming JSON for real-time output claude -p "Build a CLI app" --output-format stream-json # Restrict tools claude -p "Stage changes" --allowedTools "Bash,Read" --permission-mode acceptEdits
Output Formats
| Format | Flag | Use Case |
|---|---|---|
| Text | (default) | Simple scripts |
| JSON | | Programmatic parsing |
| Stream JSON | | Real-time streaming |
JSON response includes:
session_id, total_cost_usd, duration_ms, num_turns, result.
Multi-Turn Sessions
# Get session ID session_id=$(claude -p "Start review" --output-format json | jq -r '.session_id') # Continue conversation claude -p --resume "$session_id" "Now implement the plan" # Or continue most recent claude --continue "Add tests"
Key Flags
| Flag | Purpose |
|---|---|
| Non-interactive mode |
| text/json/stream-json |
| Resume by session ID |
| Resume most recent |
| Restrict available tools |
| Block specific tools |
| Add custom instructions |
| Load MCP servers from JSON |
| Detailed logging |
Python Agent SDK
pip install claude-agent-sdk
Basic Usage
import anyio from claude_agent_sdk import query async def main(): async for message in query(prompt="What is 2 + 2?"): print(message) anyio.run(main)
Custom Tools (In-Process MCP)
from claude_agent_sdk import tool, create_sdk_mcp_server, ClaudeSDKClient @tool("greet", "Greet a user", {"name": str}) async def greet_user(args): return {"content": [{"type": "text", "text": f"Hello, {args['name']}!"}]} server = create_sdk_mcp_server(name="my-tools", version="1.0.0", tools=[greet_user]) client = ClaudeSDKClient(mcp_servers=[server])
ClaudeSDKClient Options
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions options = ClaudeAgentOptions( system_prompt="You are a helpful assistant", working_directory="/path/to/project", allowed_tools=["Bash", "Read", "Write"], permission_mode="acceptEdits" ) client = ClaudeSDKClient(options=options)
Agent Loop Pattern
Agents follow a core feedback loop:
- Gather Context - Read files, search, web fetch
- Take Action - Execute tools, generate code
- Verify Work - Evaluate output, iterate if needed
Subagents
Use subagents for parallel execution with isolated context. Each subagent has its own context window and returns only relevant data to parent.
Best Practices
- Use JSON output for reliable parsing
- Check exit codes and stderr for errors
- Implement timeouts:
timeout 300 claude -p "$prompt" - Use session management for multi-step workflows
- Parse costs:
echo "$result" | jq -r '.total_cost_usd'
Integration Examples
CI/CD Pipeline
#!/bin/bash result=$(claude -p "Review PR diff for security issues" \ --output-format json \ --allowedTools "Read,Grep,WebSearch") if echo "$result" | jq -e '.result | contains("vulnerability")' > /dev/null; then echo "Security issues found" exit 1 fi
Multi-Step Workflow
# Step 1: Plan plan_result=$(claude -p "Create implementation plan for: $TASK" --output-format json) session_id=$(echo "$plan_result" | jq -r '.session_id') # Step 2: Implement claude -p --resume "$session_id" "Implement the plan" # Step 3: Test claude -p --resume "$session_id" "Write tests for the implementation"
Rust CLI Integration
use std::process::Command; async fn call_claude(prompt: &str) -> Result<String> { let output = Command::new("claude") .args(["-p", prompt, "--output-format", "json"]) .output()?; let response: serde_json::Value = serde_json::from_slice(&output.stdout)?; Ok(response["result"].as_str().unwrap_or("").to_string()) }