TL;DR
You don’t need an API key, a LiteLLM proxy, or a custom agent framework to script Claude. If you already pay for a Claude Code subscription, claude -p "..." runs a one-shot, headless prompt from your terminal - same model, same tools, same skills you already wrote - and exits. Pipe it into bash, cron, a Git hook, or a CI job. That’s your agent.
The setup most people pick (and why it’s overkill)
The default architecture for “AI in my pipeline” usually looks like:
- Open an Anthropic / OpenAI account
- Plug an API key into a
.env - Pull in LiteLLM or LangChain or some agentic framework
- Reimplement tool use, retries, prompt templates, context loading
- Pay per token, separately from any subscription you already have
For a hobby script or a personal automation, that’s all overhead. You’re stitching together a parallel agent stack and paying API rates while your subscription sits there unused.
The trick: claude -p
The Claude Code CLI ships a flag called -p (or --print) that runs a single prompt non-interactively and prints the answer to stdout. No REPL, no UI, no session to manage:
claude -p "summarize the last 10 commits on this branch in 5 bullets"
That’s it. The CLI:
- Uses your existing Claude Code subscription (no API key, no separate billing)
- Runs in the current working directory, so it can read your repo
- Honors your
CLAUDE.md, your.claudeignore, and every skill in.claude/skills/ - Can use the same tools the interactive version uses (file reads, shell, etc.)
- Exits cleanly with the result on stdout
That last point is the unlock. Anything that consumes stdout is now an agent host: pipes, scripts, cron, Make targets, Git hooks, GitHub Actions, you name it.
A real “agent” in nine lines of bash
Drop this in bin/release-notes.sh:
#!/usr/bin/env bash
set -euo pipefail
PREV_TAG=$(git describe --tags --abbrev=0)
RANGE="${PREV_TAG}..HEAD"
claude -p "
You are writing release notes for the range ${RANGE}.
Group commits by category (feat, fix, chore).
Output Markdown only. No preamble, no closing.
" > RELEASE_NOTES.md
echo "Wrote RELEASE_NOTES.md"
That is a real agent. It reads the repo, calls a model, writes a file, exits. No framework, no API key, no LiteLLM, no LangChain. Wire it into a make release target or a pre-tag Git hook and you’re done.
Reuse the skills you already wrote
The interactive Claude Code session you use every day already activates skills based on their description. Headless mode reuses the same .claude/skills/ folder. That means:
- The
end-of-sessionhandoff skill you wrote? Trigger it from a daily cron:claude -p "wrap up today's session and write a handoff". - The
review this diffskill? Run it from a pre-push hook:claude -p "review the staged diff for security and style". - The custom domain expert skill for your team’s quirks? Run it in CI on every PR:
claude -p "review changed files using the X-Corp coding standard".
You wrote the skill once. The interactive UI gets it. The headless script gets it too. Nothing else to wire.
What you give up vs the API route
To be honest about it:
- No streaming UI.
claude -preturns the full answer when it’s done. Fine for batch, not great for “watch the model think live.” - Rate limits follow your subscription, not the per-key API quota. For automation that runs all day, you may need to think about pacing.
- No multi-step “deep agent” loops out of the box. You get a single prompt and a single response per invocation. If you need persistent state across runs, you save it to disk yourself (handoff files, JSON, whatever).
- No model routing per token. You get the model the CLI is configured with. If you need Haiku for triage and Opus for hard work, you switch with
claude --modelper invocation - still no API key, just a flag.
For 90% of “I wish I could automate this small thing” tasks, none of that matters.
When you actually need the API
The API route earns its complexity when:
- You’re serving Claude to other users (multi-tenant product, embedded assistant).
- You need streaming responses to a UI you control.
- You need fine-grained model orchestration (parallel calls, fan-out / fan-in, custom retry).
- Your script needs to run on a machine where you can’t or won’t log into Claude Code.
Everything else: claude -p, your skills, a shell loop. That’s the poor man’s agent. It’s also, most days, the smart man’s agent.
