
Parse Claude Code's Work in CI: The --output-format json Pattern for Scriptable Agents
Chris Harper
2 min read
Jul 27, 2026 · 04:05 UTC
claude -p with --output-format json and --json-schema gives you schema-validated output from any Claude task -- the building block for reliable CI pipelines and automation scripts.
When you run Claude Code in a CI pipeline or cron job, you need machine-readable output, not a chat session. The -p flag puts Claude in print mode (one-shot, no interactive session). Add --output-format json for structured output, and --json-schema to enforce an exact output shape.
The basic pattern
result=$(claude -p "Review the diff in the last commit and output a severity score 1-5" --output-format json --no-session-persistence)
echo "$result"
# {"type":"result","subtype":"success","result":"The diff looks safe. Severity: 2.","session_id":"..."}
Parse result with jq -r '.result' to extract the text.
Add --json-schema for a guaranteed output shape
review=$(claude -p "Scan this file for security issues. Return JSON." --output-format json --json-schema '{"type":"object","properties":{"issues":{"type":"array","items":{"type":"string"}},"safe":{"type":"boolean"}},"required":["issues","safe"]}' --no-session-persistence < src/auth.py)
safe=$(echo "$review" | jq -r '.result | fromjson | .safe')
issues=$(echo "$review" | jq -r '.result | fromjson | .issues[]')
if [ "$safe" = "false" ]; then
echo "Security issues found:"
echo "$issues"
exit 1
fi
With --json-schema, Claude calls a structured-output tool internally and retries on mismatch -- so your jq never blows up on malformed prose.
Useful flags for pipeline mode
| Flag | What it does |
|---|---|
--max-turns 5 | Cap how many agent turns the task can take |
--max-budget-usd 0.10 | Hard spend cap per invocation |
--no-session-persistence | Skip writing session to disk (faster in CI) |
--verbose | Include tool call details (useful for debugging) |
--output-format stream-json | Get streaming JSON events for long-running tasks |
A real GitHub Actions step
- name: Claude Code security scan
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
review=$(claude -p "Scan the staged diff for security issues" --output-format json --json-schema '{"type":"object","properties":{"safe":{"type":"boolean"},"reason":{"type":"string"}}}' --max-budget-usd 0.25 --no-session-persistence)
safe=$(echo "$review" | jq -r '.result | fromjson | .safe')
reason=$(echo "$review" | jq -r '.result | fromjson | .reason')
echo "Safe: $safe — $reason"
[ "$safe" = "true" ] || exit 1
The -p flag is what makes Claude Code composable with the rest of your shell toolchain. Treat it like curl: call it, pipe the output, parse with jq.
Sources: Claude Code CLI Reference · Structured outputs in Claude Code · Non-interactive mode