Claude Code CLI Agent Primer
AI-Optimized Primer | Production-ready patterns for Claude Code CLI agents and automation
- Category: Development Tools
- Difficulty: Intermediate to Advanced
- Examples: 47 copy-paste code blocks
- Tokens: 16,500+ comprehensive coverage
- Last Updated: September 15, 2025
- AI-Ready: Optimized for agent consumption
A condensed guide for building and deploying CLI AI agents with Claude Code
Table of Contents
- Core Architecture & Philosophy
- Installation & Authentication
- Essential CLI Usage Patterns
- Agent Architecture Framework
- Tool System & Permissions
- Model Context Protocol (MCP) Integration
- Configuration & Settings Hierarchy
- Subagent System
- Hooks & Automation
- SDK Integration Patterns
- Production Deployment
- Security & Best Practices
Core Architecture & Philosophy
Design Principles
Claude Code follows Unix philosophy with modern AI capabilities:
- Composability: Works with pipes, scripts, and existing toolchains
- Transparency: All actions are explicit and auditable
- Stateful Context: Maintains conversation history and project awareness
- Permission-based Security: Granular control over tool access
- Extensibility: MCP servers, subagents, and hooks for customization
Architecture Overview
┌─────────────────┐ ┌──────────────┐ ┌─────────────────┐
│ User Input │───▶│ Claude Agent │───▶│ Tool System │
└─────────────────┘ └──────────────┘ └─────────────────┘
│ │
▼ ▼
┌──────────────────┐ ┌─────────────────┐
│ MCP Servers │ │ Permission Gate │
└──────────────────┘ └─────────────────┘
│ │
▼ ▼
┌──────────────────┐ ┌─────────────────┐
│ Subagents │ │ Hooks System │
└──────────────────┘ └─────────────────┘
Installation & Authentication
Installation Options
NPM Install (Recommended)
npm install -g @anthropic-ai/claude-code
Native Install (Beta)
# macOS, Linux, WSL
curl -fsSL https://claude.ai/install.sh | bash
# Windows PowerShell
irm https://claude.ai/install.ps1 | iex
Authentication Methods
Interactive Login
claude
# First run prompts for authentication
/login # Re-authenticate or switch accounts
API Key Authentication
export ANTHROPIC_API_KEY="your-api-key"
claude -p "query"
Third-party Providers
# Amazon Bedrock
export CLAUDE_CODE_USE_BEDROCK=1
# Configure AWS credentials separately
# Google Vertex AI
export CLAUDE_CODE_USE_VERTEX=1
# Configure Google Cloud credentials separately
Essential CLI Usage Patterns
Interactive Mode
# Start interactive session
claude
# With initial prompt
claude "explain this project structure"
# Continue most recent conversation
claude -c
# Resume specific conversation
claude -r
Headless Mode (SDK)
# Single query, then exit
claude -p "analyze this error log"
# With output formatting
claude -p "check for bugs" --output-format json
# Process piped content
cat error.log | claude -p "explain this error"
# Integration with scripts
claude -p "run tests and report failures" --max-turns 5
File and Directory References
# Reference specific files (includes full content)
claude -p "Explain the logic in @src/auth.js"
# Reference directories (shows structure)
claude -p "What's in @components directory?"
# Multiple references
claude -p "Compare @file1.js and @file2.js"
Permission Modes
# Start in plan mode (read-only analysis)
claude --permission-mode plan
# Start with auto-accept for edits
claude --permission-mode acceptEdits
# Dangerous: skip all permission prompts
claude --dangerously-skip-permissions
Agent Architecture Framework
Core Agent Loop
- Input Processing: Parse user intent and context
- Tool Selection: Choose appropriate tools based on task
- Permission Validation: Check tool usage against permission rules
- Execution: Run tools with proper error handling
- Result Integration: Synthesize outputs into coherent response
- Context Management: Update conversation state and memory
Session Management
# Session persistence
claude -c # Continue most recent
claude -r # Resume from picker
# Session with specific configuration
claude --model sonnet --verbose
# Background session management
claude -p "task" & # Run in background
Context Management
Claude Code automatically manages context through:
- Conversation History: Full message threads with tool results
- Project Awareness: Understands file structure and dependencies
- Memory Files: CLAUDE.md files for persistent context
- Automatic Compaction: Reduces context size while preserving key information
Tool System & Permissions
Core Tools Available
Tool | Description | Permission Required |
---|---|---|
Bash | Execute shell commands | Yes |
Edit | Targeted file modifications | Yes |
MultiEdit | Multiple atomic edits per file | Yes |
Read | File content access | No |
Write | Create/overwrite files | Yes |
Glob | Pattern-based file search | No |
Grep | Content search with regex | No |
WebFetch | HTTP content retrieval | Yes |
WebSearch | Web search with filtering | Yes |
Task | Subagent delegation | No |
TodoWrite | Task list management | No |
Permission Configuration
Allow specific tools
{
"permissions": {
"allow": [
"Bash(git diff:*)",
"Bash(npm run:*)",
"Read(~/.config/*)"
]
}
}
Deny sensitive operations
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(curl:*)",
"WebFetch"
]
}
}
CLI Permission Flags
# Allow specific tools
claude --allowedTools "Bash(git:*)" "Read" "Edit"
# Block dangerous tools
claude --disallowedTools "WebFetch" "Bash(rm:*)"
Model Context Protocol (MCP) Integration
MCP Server Types
Local Stdio Servers
# Basic installation
claude mcp add airtable --env AIRTABLE_API_KEY=key \
-- npx -y airtable-mcp-server
# With custom timeout
MCP_TIMEOUT=10000 claude mcp add slow-server \
-- python slow_server.py
Remote HTTP Servers
# Standard HTTP MCP
claude mcp add notion --transport http https://mcp.notion.com/mcp
# With authentication headers
claude mcp add api --transport http https://api.company.com/mcp \
--header "Authorization: Bearer token"
Server-Sent Events (SSE)
# Real-time streaming servers
claude mcp add linear --transport sse https://mcp.linear.app/sse
# OAuth authentication handled via /mcp command
MCP Configuration Scopes
Scope | Location | Sharing | Use Case |
---|---|---|---|
local | User settings | Personal | Development, testing |
project | .mcp.json | Team-wide | Shared integrations |
user | ~/.claude/ | Cross-project | Personal utilities |
MCP Resource Usage
# Reference MCP resources with @
claude -p "Analyze @github:issue://123"
# Multiple resource references
claude -p "Compare @db:schema://users with @docs:spec://user-model"
# MCP prompts as slash commands
/mcp__github__create_issue "Bug in auth" high
Popular MCP Servers
Development & Testing
- Sentry: Error monitoring and debugging
- Socket: Security analysis for dependencies
- Hugging Face: ML model and dataset access
- Jam: Debug recordings with video/logs
Project Management
- Linear, Asana, Monday: Issue tracking
- Notion, Confluence: Documentation
- Slack, Intercom: Communication
Data & Commerce
- Stripe, PayPal, Square: Payment processing
- Airtable, HubSpot: Database management
- Figma, Canva: Design integration
Infrastructure
- Cloudflare, Netlify, Vercel: Deployment
- AWS, GCP integrations via respective CLIs
Configuration & Settings Hierarchy
Settings Precedence (Highest to Lowest)
- Enterprise Managed Policies (
managed-settings.json
) - Command Line Arguments (session-specific)
- Local Project Settings (
.claude/settings.local.json
) - Shared Project Settings (
.claude/settings.json
) - User Settings (
~/.claude/settings.json
)
Configuration Structure
{
"model": "claude-3-5-sonnet-20241022",
"outputStyle": "Explanatory",
"permissions": {
"defaultMode": "plan",
"allow": ["Bash(git:*)", "Read", "Edit"],
"deny": ["WebFetch", "Read(./.env)"],
"additionalDirectories": ["../docs/"]
},
"env": {
"CLAUDE_CODE_MAX_OUTPUT_TOKENS": "50000",
"MCP_TIMEOUT": "15000"
},
"hooks": {
"PostToolUse": [{
"matcher": "Edit|MultiEdit|Write",
"hooks": [{"type": "command", "command": "prettier --write $file"}]
}]
},
"statusLine": {
"type": "command",
"command": "~/.claude/status.sh"
}
}
Environment Variables
Authentication
ANTHROPIC_API_KEY # Direct API access
ANTHROPIC_AUTH_TOKEN # Custom bearer token
CLAUDE_CODE_USE_BEDROCK=1 # Amazon Bedrock
CLAUDE_CODE_USE_VERTEX=1 # Google Vertex AI
Behavior Control
CLAUDE_CODE_MAX_OUTPUT_TOKENS=50000 # Token limits
MAX_MCP_OUTPUT_TOKENS=25000 # MCP response limits
MCP_TIMEOUT=10000 # MCP startup timeout
BASH_DEFAULT_TIMEOUT_MS=120000 # Command timeouts
DISABLE_TELEMETRY=1 # Privacy control
Subagent System
Subagent Architecture
Subagents are specialized AI instances with:
- Isolated Context: Separate conversation thread
- Custom System Prompts: Task-specific instructions
- Tool Restrictions: Limited access to specific tools
- Automatic Delegation: Invoked based on task matching
Creating Subagents
File Structure
---
name: code-reviewer
description: Expert code review specialist. Proactively reviews code for quality, security, and maintainability. Use immediately after writing or modifying code.
tools: Read, Grep, Glob, Bash
---
You are a senior code reviewer ensuring high standards of code quality and security.
When invoked:
1. Run git diff to see recent changes
2. Focus on modified files
3. Begin review immediately
Review checklist:
- Code is simple and readable
- Functions and variables are well-named
- No duplicated code
- Proper error handling
- No exposed secrets or API keys
- Input validation implemented
- Good test coverage
- Performance considerations addressed
Provide feedback organized by priority:
- Critical issues (must fix)
- Warnings (should fix)
- Suggestions (consider improving)
Include specific examples of how to fix issues.
Storage Locations
- Project:
.claude/agents/
(shared with team) - User:
~/.claude/agents/
(personal across projects)
Using Subagents
Automatic Delegation
# Claude automatically selects appropriate subagent
claude -p "review my recent code changes for security issues"
claude -p "run all tests and fix any failures"
Explicit Invocation
claude -p "use the code-reviewer subagent to check the auth module"
claude -p "have the debugger subagent investigate this error"
Management Interface
# Interactive subagent management
/agents
# Create new subagents
/agents # Select "Create New Agent"
Example Subagent Types
Development Specialists
code-reviewer
: Quality, security, maintainabilitydebugger
: Error diagnosis and resolutiontest-runner
: Automated testing and failure fixesperformance-auditor
: Optimization analysis
Domain Experts
rust-expert
: Ownership, lifetimes, systems programmingpython-expert
: Modern Python, libraries, architecturedata-scientist
: SQL, BigQuery, data analysis
Workflow Automation
git-helper
: Version control operationsdeployment-manager
: CI/CD and infrastructuredocumentation-writer
: API docs and guides
Hooks & Automation
Hook Event Types
Event | Timing | Use Cases |
---|---|---|
PreToolUse | Before tool execution | Validation, blocking, logging |
PostToolUse | After tool completion | Formatting, notifications, cleanup |
UserPromptSubmit | User input received | Preprocessing, context injection |
Notification | Claude needs attention | Custom notifications |
Stop | Response completed | Final processing, reporting |
SessionStart/End | Session lifecycle | Setup, teardown, logging |
Hook Implementation Patterns
Code Formatting
{
"hooks": {
"PostToolUse": [{
"matcher": "Edit|MultiEdit|Write",
"hooks": [{
"type": "command",
"command": "jq -r '.tool_input.file_path' | { read file; if echo \"$file\" | grep -q '\\.py$'; then black \"$file\"; fi; }"
}]
}]
}
}
Security Validation
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "python3 ~/.claude/hooks/validate_command.py"
}]
}]
}
}
Custom Notifications
{
"hooks": {
"Notification": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "osascript -e 'display notification \"Claude awaits input\" with title \"Claude Code\"'"
}]
}]
}
}
Advanced Hook Scripts
Python Hook Example
#!/usr/bin/env python3
import json
import sys
import os
def validate_bash_command():
"""Validate bash commands for safety"""
try:
data = json.load(sys.stdin)
command = data.get('tool_input', {}).get('command', '')
# Block dangerous commands
dangerous = ['rm -rf', 'sudo', 'chmod 777', 'curl | bash']
if any(danger in command for danger in dangerous):
print(f"BLOCKED: Dangerous command detected: {command}")
sys.exit(2) # Exit code 2 blocks execution
# Log all commands
with open(os.path.expanduser('~/.claude/command_log.txt'), 'a') as f:
f.write(f"{command}\n")
except Exception as e:
print(f"Hook error: {e}")
sys.exit(1)
if __name__ == "__main__":
validate_bash_command()
SDK Integration Patterns
SDK Modes
Headless Mode (CLI Scripts)
# Single query with structured output
result=$(claude -p "analyze this error" --output-format json)
# Pipe integration
cat logs.txt | claude -p "find errors" | jq '.messages[-1].content'
# Automation scripts
claude -p "run tests and commit if passing" --max-turns 10
Streaming Mode (Interactive Applications)
TypeScript SDK
import { Claude } from '@anthropic-ai/claude-code';
const claude = new Claude({
apiKey: process.env.ANTHROPIC_API_KEY,
workingDirectory: process.cwd()
});
// Streaming conversation
const stream = claude.query("Analyze this codebase for performance issues");
for await (const message of stream) {
if (message.type === 'assistant') {
console.log(message.content);
}
if (message.usage) {
console.log(`Tokens used: ${message.usage.input_tokens}`);
}
}
Python SDK
import anthropic_claude_code as claude
client = claude.Claude(
api_key=os.environ['ANTHROPIC_API_KEY'],
working_directory=os.getcwd()
)
# Async streaming
async for message in client.query("Optimize database queries"):
if message.type == 'assistant':
print(message.content)
if hasattr(message, 'usage'):
track_usage(message.usage)
Cost Tracking Implementation
// Message-level usage tracking
const usageTracker = new Map<string, Usage>();
for await (const message of stream) {
if (message.type === 'assistant' && message.usage) {
// Only count once per unique message ID
if (!usageTracker.has(message.id)) {
usageTracker.set(message.id, message.usage);
updateBilling(message.usage);
}
}
}
Session Management
# Resume sessions programmatically
session_id = await client.start_session()
# Process with interruption handling
try:
async for message in client.query("Long running task", session_id=session_id):
if should_interrupt():
await client.interrupt(session_id)
break
finally:
await client.save_session(session_id)
Production Deployment
CI/CD Integration
GitHub Actions Example
name: AI Code Review
on: [pull_request]
jobs:
ai-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: AI Code Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude -p "Review this PR for security issues and code quality.
Focus on the changed files and provide specific recommendations." \
--output-format json > review.json
- name: Post Review
run: |
jq -r '.messages[-1].content' review.json > review.md
gh pr comment --body-file review.md
Docker Integration
FROM node:18-alpine
# Install Claude Code
RUN npm install -g @anthropic-ai/claude-code
# Copy MCP configurations
COPY .mcp.json /app/.mcp.json
COPY .claude/ /app/.claude/
WORKDIR /app
# Authentication via environment variables
ENV ANTHROPIC_API_KEY=""
ENV CLAUDE_CODE_USE_BEDROCK=1
# Disable interactive features for automation
ENV DISABLE_TELEMETRY=1
ENV DISABLE_AUTOUPDATER=1
CMD ["claude", "-p", "analyze this codebase", "--output-format", "json"]
Kubernetes Deployment
apiVersion: batch/v1
kind: CronJob
metadata:
name: code-analysis
spec:
schedule: "0 2 * * *" # Daily at 2 AM
jobTemplate:
spec:
template:
spec:
containers:
- name: claude-analyzer
image: your-repo/claude-code:latest
env:
- name: ANTHROPIC_API_KEY
valueFrom:
secretKeyRef:
name: claude-secrets
key: api-key
command:
- /bin/sh
- -c
- |
claude -p "Analyze codebase for technical debt and security issues.
Generate daily report with priorities." \
--output-format json > /reports/daily-$(date +%Y%m%d).json
volumeMounts:
- name: reports
mountPath: /reports
volumes:
- name: reports
persistentVolumeClaim:
claimName: analysis-reports
restartPolicy: OnFailure
Monitoring & Observability
# Enable comprehensive logging
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
# Custom status line for monitoring
echo '#!/bin/bash
echo "Session: $CLAUDE_SESSION_ID | Model: $CLAUDE_MODEL | Tokens: $CLAUDE_USAGE_TOKENS"
' > ~/.claude/status.sh
Security & Best Practices
Permission Security Model
Principle of Least Privilege
{
"permissions": {
"allow": [
"Read(./src/**)",
"Edit(./src/**)",
"Bash(npm run test)",
"Bash(git diff:*)"
],
"deny": [
"Read(./.env*)",
"Read(./secrets/**)",
"Bash(curl:*)",
"Bash(wget:*)",
"WebFetch",
"Write(./package.json)"
]
}
}
Enterprise Security Policies
// /etc/claude-code/managed-settings.json
{
"permissions": {
"deny": [
"WebFetch",
"Bash(rm:*)",
"Bash(sudo:*)",
"Read(/etc/**)",
"Write(/var/**)"
],
"disableBypassPermissionsMode": "disable"
},
"forceLoginMethod": "console",
"forceLoginOrgUUID": "org-uuid-here"
}
Sensitive Data Protection
File Exclusion Patterns
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Read(./config/credentials.*)",
"Read(./**/*key*)",
"Read(./**/*secret*)",
"Read(./**/*token*)"
]
}
}
Git Integration Security
# Prevent accidental commits of sensitive data
echo ".claude/settings.local.json" >> .gitignore
echo "*.log" >> .gitignore
echo ".env*" >> .gitignore
Hook Security
Safe Hook Implementation
#!/usr/bin/env python3
import json
import sys
import subprocess
import shlex
def secure_hook():
"""Secure hook implementation with input validation"""
try:
# Parse input safely
data = json.load(sys.stdin)
# Validate input structure
if 'tool_input' not in data:
sys.exit(0)
# Sanitize file paths
file_path = data['tool_input'].get('file_path', '')
if not file_path or '..' in file_path or file_path.startswith('/'):
print("Invalid file path")
sys.exit(1)
# Use safe command execution
cmd = ['prettier', '--write', file_path]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if result.returncode != 0:
print(f"Formatting failed: {result.stderr}")
sys.exit(1)
except Exception as e:
print(f"Hook error: {e}")
sys.exit(1)
if __name__ == "__main__":
secure_hook()
MCP Security
Server Validation
# Review MCP servers before installation
claude mcp get server-name
# Use project-scoped servers for team review
claude mcp add server --scope project
# Enable specific servers only
{
"enabledMcpjsonServers": ["approved-server-1", "approved-server-2"],
"disabledMcpjsonServers": ["untrusted-server"]
}
Audit & Compliance
Command Logging
{
"hooks": {
"PreToolUse": [{
"matcher": "*",
"hooks": [{
"type": "command",
"command": "python3 ~/.claude/audit_logger.py"
}]
}]
}
}
Audit Logger Implementation
#!/usr/bin/env python3
import json
import sys
import datetime
import os
def audit_log():
"""Log all tool usage for compliance"""
try:
data = json.load(sys.stdin)
log_entry = {
"timestamp": datetime.datetime.utcnow().isoformat(),
"tool": data.get("tool_name"),
"input": data.get("tool_input", {}),
"user": os.environ.get("USER"),
"session": os.environ.get("CLAUDE_SESSION_ID")
}
with open("/var/log/claude-audit.log", "a") as f:
f.write(json.dumps(log_entry) + "\n")
except Exception as e:
print(f"Audit logging failed: {e}")
# Don't block execution for logging failures
if __name__ == "__main__":
audit_log()
Network Security
{
"env": {
"HTTP_PROXY": "http://proxy.company.com:8080",
"HTTPS_PROXY": "http://proxy.company.com:8080",
"NO_PROXY": "localhost,127.0.0.1,*.company.com"
},
"permissions": {
"deny": ["WebFetch", "WebSearch"]
}
}
Advanced Patterns & Best Practices
Multi-Agent Orchestration
# Chain specialized agents
claude -p "First use the code-analyzer to identify performance issues,
then use the optimizer to fix them,
finally use the test-runner to verify improvements"
Workflow Automation
# Git workflow integration
claude commit # Smart commit message generation
# Unix pipeline integration
find . -name "*.py" -exec claude -p "check {} for security issues" \;
# Continuous monitoring
tail -f application.log | claude -p "alert me to any anomalies"
Context Management
<!-- .claude/CLAUDE.md -->
# Project Context
This is a TypeScript/React project with:
- Authentication via JWT tokens
- PostgreSQL database with Prisma ORM
- Microservices architecture on AWS
- Jest for testing, ESLint for linting
## Coding Standards
- Use functional components with hooks
- Implement proper TypeScript types
- Follow security best practices for auth
- Write comprehensive tests for business logic
## Architecture Decisions
- API routes in /api directory
- Database models in /prisma/schema.prisma
- Custom hooks in /hooks directory
- Shared components in /components directory
This primer provides a comprehensive foundation for building production-grade CLI agents with Claude Code. The modular architecture, extensive tool system, and robust security model make it suitable for everything from personal development workflows to enterprise-scale automation systems.