From Assistant to Agent — Headless & Unattended Runs
The Shift That Changes Everything
Up to now, every time you've used Claude Code, you've been sitting there. You type a request, Claude works, you review, you type the next thing. It's a conversation. Claude is your assistant — brilliant, but it only moves when you do.
This module is about the next step: making Claude do work when you're not there. A script that runs at 7am and emails you a summary before you've had coffee. A job that watches a folder and reacts when a file lands. A workflow that checks something every hour and only pings you when something's wrong.
That's the shift from assistant to agent: from "Claude responds to me" to "Claude does a job on my behalf."
The foundation for all of it is one feature: headless mode.
What "Headless" Means
"Headless" just means no interface, no human in the loop. Instead of opening an interactive Claude Code session and chatting, you give Claude a single instruction, it runs, and it prints the result — then it's done. No back-and-forth.
This is the difference between:
| Interactive mode | Headless mode |
|---|---|
You type claude and chat | You run one command with the whole instruction baked in |
| Claude waits for your next message | Claude does the task and exits |
| Output appears on screen for you to read | Output is printed so a script (or another program) can use it |
| Great for building and exploring | Great for automation, schedules, and pipelines |
Headless mode is the building block. Everything else in this module — scheduling, multi-step workflows, agents — is just headless runs wired together cleverly.
Print Mode: claude -p
The command that makes Claude run unattended is print mode, triggered with the -p flag (short for "print"):
claude -p "Summarize the README.md file in this folder in 3 bullet points"
Claude reads the prompt, does the work, prints the answer to your terminal, and exits. No session, no chat. That printed answer is the whole point — because anything printed to the terminal can be captured, saved to a file, emailed, or fed into the next step.
You can save the output to a file like this:
claude -p "Summarize today's git commits" > summary.txt
Now summary.txt contains Claude's answer. A human never had to copy-paste it.
Piping: Feeding Data In
Print mode can also read input that's piped to it. "Piping" (the | symbol) means taking the output of one command and feeding it straight into the next. This lets you hand Claude a chunk of data without pasting it into a prompt.
cat customer-feedback.txt | claude -p "Group these comments into themes and count each theme"
Here, the contents of customer-feedback.txt are streamed into Claude along with your instruction. You can pipe in anything text-based — a log file, the output of another tool, a list of records:
git log --since="1 day ago" | claude -p "Write a friendly daily standup update from these commits"
This is the heart of automation thinking: data flows in, Claude transforms it, a result flows out.
Output Formats: Text vs. JSON
By default, Claude prints plain, human-readable text. That's perfect when a person will read it. But sometimes another program needs the result — and programs prefer structured data they can pick apart reliably.
For that, ask for JSON output:
claude -p "List the 3 main risks in this contract" --output-format json
| Format | Use it when… |
|---|---|
text (default) | A human reads the result, or you just want the answer |
json | Another program will process the result — it also includes useful metadata like the session ID, token usage, and cost |
stream-json | You want results as they're generated, line by line (advanced; needs the --verbose flag) |
You don't need JSON for most of what you'll build. Start with text. Reach for json when you're connecting Claude to other software that needs clean, predictable fields.
When Does Unattended Actually Make Sense?
Headless mode is powerful, but it removes you from the loop — so use it where that's an advantage, not a liability.
Good fits for unattended runs:
- Repetitive, well-defined tasks — "summarize today's signups," "check if the site is up," "categorize new support emails." The instruction is the same every time.
- Things that should happen on a schedule — a daily digest, a weekly report.
- Reactions to events — a file arrives, a form is submitted, a webhook fires.
- Read-and-report work — gathering and summarizing, where Claude isn't changing anything important.
Poor fits (keep yourself in the loop):
- High-stakes actions with no safety net — deleting data, sending money, posting publicly, emailing customers — without a review step.
- Fuzzy, judgment-heavy tasks where you'd want to react to what Claude finds before deciding the next move.
- Anything you can't yet describe precisely. If you couldn't write the instruction down clearly, you're not ready to automate it.
A good rule: automate the gathering and the thinking; keep a human checkpoint before anything irreversible. We'll build exactly that pattern in the next lessons.
Your First Headless Example
Let's make Claude do a real job unattended. Imagine you keep a folder of meeting notes and you want a one-paragraph recap of the latest one, saved to its own file.
claude -p "Read the most recently modified .md file in the notes/ folder. Write a 4-sentence recap covering decisions made and action items. Save it as recap.txt" --allowedTools "Read" "Write"
Notice that last part — --allowedTools "Read" "Write". Because no human is there to approve actions, you tell Claude exactly which capabilities it's allowed to use: it may read files and write files, and nothing else. This is your first taste of permissions for automation, which we'll go deep on in the guardrails lesson. For now, the principle: when you step away, you hand Claude a defined set of keys — not the whole keyring.
Run that command and you'll come back to a recap.txt you never had to write. That's the assistant-to-agent shift in a single line.
A Note on Building Agents Programmatically
Everything in this module is built on the claude -p command — which is plenty for most people. But it's worth knowing that for more serious, custom agents, Anthropic offers the Claude Agent SDK (a toolkit available for TypeScript and Python). It packages the same agent engine that powers Claude Code as a library you can build software around — with persistent sessions, subagents, and turn limits.
You don't need it to follow this module, and we won't use it. Just know it exists: when "a command on a schedule" isn't enough and you want to build a real product around an agent, that's the door.
The Mental Model Going Forward
Hold onto this picture for the rest of the module:
A headless run is a tiny, self-contained worker. You give it one clear instruction, a defined set of permissions, and data to work on. It produces a result.
Scheduling (Lesson 2) decides when that worker runs. Workflows (Lesson 3) chain several workers into something that monitors, decides, acts, and notifies. Guardrails (Lesson 4) keep all of it safe. But it always comes back to this one unit: claude -p, doing a job, while you're somewhere else.
Summary
- The leap in this module is assistant → agent: Claude doing work while you're not watching.
- Headless / print mode (
claude -p "<prompt>") runs Claude once, prints the result, and exits — the building block for all automation. - You can save output to a file (
> file.txt) and pipe data in (cat data.txt | claude -p "..."). - Use
--output-format jsonwhen another program needs the result; plaintextis fine for humans. - Automate repetitive, well-defined, low-risk tasks; keep a human checkpoint before anything irreversible.
- Unattended runs need explicit permissions (
--allowedTools) — when you step away, hand Claude only the keys it needs.