# Headless mode > Run Claude Code programmatically without interactive UI ## Overview The headless mode allows you to run Claude Code programmatically from command line scripts and automation tools without any interactive UI. ## Basic usage The primary command-line interface to Claude Code is the `claude` command. Use the `--print` (or `-p`) flag to run in non-interactive mode and print the final result: ```bash theme={null} claude -p "Stage my changes and write a set of commits for them" \ --allowedTools "Bash,Read" \ --permission-mode acceptEdits ``` ## Configuration Options Headless mode leverages all the CLI options available in Claude Code. Here are the key ones for automation and scripting: | Flag | Description | Example | | :------------------------- | :----------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------ | | `--print`, `-p` | Run in non-interactive mode | `claude -p "query"` | | `--output-format` | Specify output format (`text`, `json`, `stream-json`) | `claude -p --output-format json` | | `--resume`, `-r` | Resume a conversation by session ID | `claude --resume abc123` | | `--continue`, `-c` | Continue the most recent conversation | `claude --continue` | | `--verbose` | Enable verbose logging | `claude --verbose` | | `--append-system-prompt` | Append to system prompt (only with `--print`) | `claude --append-system-prompt "Custom instruction"` | | `--allowedTools` | Space-separated list of allowed tools, or

string of comma-separated list of allowed tools | `claude --allowedTools mcp__slack mcp__filesystem`

`claude --allowedTools "Bash(npm install),mcp__filesystem"` | | `--disallowedTools` | Space-separated list of denied tools, or

string of comma-separated list of denied tools | `claude --disallowedTools mcp__splunk mcp__github`

`claude --disallowedTools "Bash(git commit),mcp__github"` | | `--mcp-config` | Load MCP servers from a JSON file | `claude --mcp-config servers.json` | | `--permission-prompt-tool` | MCP tool for handling permission prompts (only with `--print`) | `claude --permission-prompt-tool mcp__auth__prompt` | For a complete list of CLI options and features, see the [CLI reference](/en/docs/claude-code/cli-reference) documentation. ## Multi-turn conversations For multi-turn conversations, you can resume conversations or continue from the most recent session: ```bash theme={null} # Continue the most recent conversation claude --continue "Now refactor this for better performance" # Resume a specific conversation by session ID claude --resume 550e8400-e29b-41d4-a716-446655440000 "Update the tests" # Resume in non-interactive mode claude --resume 550e8400-e29b-41d4-a716-446655440000 "Fix all linting issues" --no-interactive ``` ## Output Formats ### Text Output (Default) ```bash theme={null} claude -p "Explain file src/components/Header.tsx" # Output: This is a React component showing... ``` ### JSON Output Returns structured data including metadata: ```bash theme={null} claude -p "How does the data layer work?" --output-format json ``` Response format: ```json theme={null} { "type": "result", "subtype": "success", "total_cost_usd": 0.003, "is_error": false, "duration_ms": 1234, "duration_api_ms": 800, "num_turns": 6, "result": "The response text here...", "session_id": "abc123" } ``` ### Streaming JSON Output Streams each message as it is received: ```bash theme={null} claude -p "Build an application" --output-format stream-json ``` Each conversation begins with an initial `init` system message, followed by a list of user and assistant messages, followed by a final `result` system message with stats. Each message is emitted as a separate JSON object. ## Input Formats ### Text Input (Default) ```bash theme={null} # Direct argument claude -p "Explain this code" # From stdin echo "Explain this code" | claude -p ``` ### Streaming JSON Input A stream of messages provided via `stdin` where each message represents a user turn. This allows multiple turns of a conversation without re-launching the `claude` binary and allows providing guidance to the model while it is processing a request. Each message is a JSON 'User message' object, following the same format as the output message schema. Messages are formatted using the [jsonl](https://jsonlines.org/) format where each line of input is a complete JSON object. Streaming JSON input requires `-p` and `--output-format stream-json`. ```bash theme={null} echo '{"type":"user","message":{"role":"user","content":[{"type":"text","text":"Explain this code"}]}}' | claude -p --output-format=stream-json --input-format=stream-json --verbose ``` ## Agent Integration Examples ### SRE Incident Response Bot ```bash theme={null} #!/bin/bash # Automated incident response agent investigate_incident() { local incident_description="$1" local severity="${2:-medium}" claude -p "Incident: $incident_description (Severity: $severity)" \ --append-system-prompt "You are an SRE expert. Diagnose the issue, assess impact, and provide immediate action items." \ --output-format json \ --allowedTools "Bash,Read,WebSearch,mcp__datadog" \ --mcp-config monitoring-tools.json } # Usage investigate_incident "Payment API returning 500 errors" "high" ``` ### Automated Security Review ```bash theme={null} # Security audit agent for pull requests audit_pr() { local pr_number="$1" gh pr diff "$pr_number" | claude -p \ --append-system-prompt "You are a security engineer. Review this PR for vulnerabilities, insecure patterns, and compliance issues." \ --output-format json \ --allowedTools "Read,Grep,WebSearch" } # Usage and save to file audit_pr 123 > security-report.json ``` ### Multi-turn Legal Assistant ```bash theme={null} # Legal document review with session persistence session_id=$(claude -p "Start legal review session" --output-format json | jq -r '.session_id') # Review contract in multiple steps claude -p --resume "$session_id" "Review contract.pdf for liability clauses" claude -p --resume "$session_id" "Check compliance with GDPR requirements" claude -p --resume "$session_id" "Generate executive summary of risks" ``` ## Best Practices * **Use JSON output format** for programmatic parsing of responses: ```bash theme={null} # Parse JSON response with jq result=$(claude -p "Generate code" --output-format json) code=$(echo "$result" | jq -r '.result') cost=$(echo "$result" | jq -r '.cost_usd') ``` * **Handle errors gracefully** - check exit codes and stderr: ```bash theme={null} if ! claude -p "$prompt" 2>error.log; then echo "Error occurred:" >&2 cat error.log >&2 exit 1 fi ``` * **Use session management** for maintaining context in multi-turn conversations * **Consider timeouts** for long-running operations: ```bash theme={null} timeout 300 claude -p "$complex_prompt" || echo "Timed out after 5 minutes" ``` * **Respect rate limits** when making multiple requests by adding delays between calls ## Related Resources * [CLI usage and controls](/en/docs/claude-code/cli-reference) - Complete CLI documentation * [Common workflows](/en/docs/claude-code/common-workflows) - Step-by-step guides for common use cases