Claude Code · Advanced · Part 7 of 8
Automation and teams: scripts, CI, GitHub Actions, and organisation-wide setup
Everything so far assumed you, a terminal and a conversation. The next step is Claude Code without the conversation: running from a script, a scheduled job or a pull request, and then rolling it out to a whole team with shared conventions and organisation rules. This part covers non-interactive mode, GitHub Actions, scheduling, and team and admin setup. Automation means Claude acts with nobody watching, so the safety advice here matters more than anywhere else in the series.
claude -p "prompt"runs Claude once, non-interactively, and prints the result. It works with pipes, JSON output and CI.- In unattended runs, pre-approve only the tools the job needs, and make everything else fail instead of prompt.
- The GitHub Action lets you mention
@claudeon an issue or pull request, or run a prompt on any GitHub event. - For a team: commit shared conventions, keep personal overrides local, and let admins enforce policy with managed settings.
- Never put keys in a repository, and treat any untrusted input as a potential prompt injection.
1. Non-interactive mode: claude -p
Add -p (or --print) to any claude command and it runs once without an interactive prompt, prints the answer, and exits. Under the hood it is the same engine as the Agent SDK, available as a command-line tool for scripts and CI.
claude -p "What does the auth module do?"
claude -p "Find and fix the bug in auth.py" --allowedTools "Read,Edit,Bash"
- Exit code: 0 on success and non-zero on failure, so scripts can branch on it.
- Sessions: a
-prun still creates a resumable session unless you pass--no-session-persistence. - Some commands differ: user-invoked skills work (put
/skill-namein the prompt), but terminal-only built-ins such as/logindo not.
Choose an output format
| Flag | You get | Use it for |
|---|---|---|
--output-format text (default) | Plain text | Humans, simple scripts |
--output-format json | One JSON object with the result text, session ID and metadata (including total_cost_usd as a client-side estimate) | Scripts that parse the answer |
--output-format stream-json | One JSON event per line, ending with a result message. Add --verbose --include-partial-messages for token-by-token output. | Live progress displays, real-time pipelines |
--json-schema '{...}' with json | The answer in a structure you define, in the structured_output field | Extracting data reliably |
# Plain answer to a file
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt
# Get the text result with jq
claude -p "Summarize this project" --output-format json | jq -r '.result'
# Structured output
claude -p "Extract the main function names from auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
| jq '.structured_output'
Piped input is capped at 10 MB. For larger inputs, write the content to a file and mention the path in your prompt.
Start faster and more predictably: --bare
By default a -p run loads the same context an interactive session would: your CLAUDE.md, auto memory, plugins and MCP servers. --bare skips all of that auto-discovery, so the run behaves the same on every machine. The docs recommend it for scripted and CI use and say it will become the default for -p in a future release. It does not use your subscription login, so set ANTHROPIC_API_KEY first, and pass any context you need explicitly:
claude --bare -p "Summarize README.md" --allowedTools "Read"
With --bare, you load extras on purpose: --append-system-prompt, --settings, --mcp-config, --agents or --plugin-dir.
Continuing a conversation across runs
claude -p "Review this codebase for performance issues"
claude -p "Now focus on the database queries" --continue
# Capture the session ID to resume a specific one
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"
2. Running unattended safely
In an interactive session you are the safety net. In a script nobody is watching, so decide in advance what Claude may do. There are three layers, from broad to narrow:
| Layer | Flag or setting | What it does |
|---|---|---|
| Permission mode | --permission-mode dontAsk | Denies anything that would otherwise prompt. File reads in your working folders and pre-approved tools still work. Suited to locked-down CI. |
--permission-mode acceptEdits | Lets Claude write files and run common file commands without asking. Other shell commands still need an allow rule. | |
--permission-mode auto | A classifier reviews actions. Convenient for long jobs; see the docs for what it blocks. | |
| Allowed tools | --allowedTools "Bash(git diff *),Read" | Pre-approves exactly the tools and command patterns the job needs. The trailing * enables prefix matching. |
| No prompts | --permission-prompts none | For runs with nobody to answer: anything that would prompt is denied, and Claude is told not to retry. Requires a recent version (v2.1.259 or later). |
The exact combination depends on the job. Two examples from the docs:
# A job that reviews staged changes and commits (note: no git push is allowed)
claude -p "Look at my staged changes and create an appropriate commit" \
--allowedTools "Bash(git diff *),Bash(git log *),Bash(git status *),Bash(git commit *)"
# Unattended auto-mode run where anything needing approval is denied
claude -p "Update the dependency pins and run the tests" \
--permission-mode auto --permission-prompts none
- Least privilege: allow only the commands the job needs. A bare
Bashallow is very broad. - Always set a permission mode on purpose. A run where nothing sets one takes the built-in starting mode, which can be auto.
- Cap the work:
--max-turnsand, where supported,--max-budget-usdlimit runaway jobs; add timeouts in your CI system. - Untrusted input is dangerous: text from issues, comments, web pages or logs can contain hidden instructions (prompt injection). Do not give a job that reads untrusted input broad write or network permissions.
- Without
--bare, a-prun still loads the project's own configuration and connects the MCP servers in its.mcp.json, even for a folder you have never trusted, and shows no trust dialog. Use--barein CI, or only run it on code you trust. - Review what it produced. Unattended does not mean unreviewed: use pull requests, not direct pushes.
3. Scripts, pipes and fan-out
Pipe anything in
git log --oneline -20 | claude -p "summarize these recent commits"
# Review a pull request with a custom role (save as review.sh, run: bash review.sh 123)
gh pr diff "$1" | claude -p \
--append-system-prompt "You are a security engineer. Review for vulnerabilities." \
--output-format json
Use Claude as a project-specific linter
This package.json script pipes the diff against main into Claude and asks only for typos. Piping the diff means Claude does not need shell permission to read it:
{
"scripts": {
"lint:claude": "git diff main | claude -p \"you are a typo linter. for each typo in this diff, report filename:line on one line and the issue on the next. return nothing else.\""
}
}
Fan out across many files
For a large migration, the docs describe two approaches. The built-in one is /batch <instruction>, which splits the change across 5 to 30 subagents, each in its own worktree. To drive it yourself, loop over claude -p:
for file in $(cat files.txt); do
claude -p "Migrate $file from Python 2 to Python 3. Return OK or FAIL." \
--allowedTools "Edit,Bash(git commit *)" \
--permission-mode dontAsk
done
The docs' advice: ask Claude to write the list of files first, test the prompt on two or three files, fix what goes wrong, then run it on everything. --permission-mode dontAsk matters here because nobody can answer prompts.
4. Running on a schedule
If you want Claude to do something repeatedly, such as reviewing open pull requests each morning, the common-workflows guide offers four places to run it:
| Option | Where it runs | Best for |
|---|---|---|
| Routines | The cloud (Anthropic-managed by default) | Tasks that should run even when your computer is off; can also trigger on API calls or GitHub events. |
| Desktop scheduled tasks | Your machine, via the desktop app | Tasks that need your local files, tools or uncommitted changes. |
| GitHub Actions | Your CI pipeline | Tasks tied to repository events, or cron schedules that live beside your workflow config. |
/loop | The current CLI session | Quick polling while a session is open. |
A tip straight from the docs: a scheduled task runs autonomously and cannot ask clarifying questions, so write the prompt with success in mind. Say what done looks like and what to do with the results, for example: “Review open PRs labeled needs-review, leave inline comments on any issues, and post a summary in the #eng-reviews Slack channel.”
5. GitHub Actions
Claude Code GitHub Actions runs Claude Code inside your repository's workflows. Mention @claude in a pull request or issue comment and it can analyse code, implement changes and push commits. You can also give it a prompt to run automatically on any GitHub event, to turn issues into pull requests or automate recurring tasks. It is built on the same SDK as claude -p.
Set it up
- Quick setup: in the repository, run
claude, then/install-github-appand follow the prompts. It installs the Claude GitHub App, saves your credential as a repository secret and opens a pull request with the workflow files. It needs admin access to the repository, the GitHub CLI signed in withgh auth login, and a github.com repository. For GitLab, see the GitLab CI/CD page. - Or set it up by hand: install the Claude GitHub App, add a secret named
ANTHROPIC_API_KEY(an API key from the Console) orCLAUDE_CODE_OAUTH_TOKEN(a token for your Claude subscription, created by runningclaude setup-token), and copy a workflow file into.github/workflows/. - Test it: comment
@claudeon an issue or pull request.
The @claude workflow
This is the docs' example. It runs in interactive mode: with no prompt input, Claude waits for the trigger phrase and replies in a comment.
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
jobs:
claude:
if: contains(github.event.comment.body, '@claude')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
actions: read
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}Then comment things like @claude implement this feature based on the issue description or @claude fix the TypeError in the user dashboard component.
Automation mode and who can trigger it
- Automation mode: add a
promptinput and Claude runs on any event you choose (a pull request opening, a cron schedule) without waiting for a mention. Results go to the workflow log unless the prompt tells Claude to post a comment and it has a tool that can. - Who can trigger it: by default the triggering user needs write access to the repository, and bot actors are rejected unless you list them in
allowed_bots, which stops bots from triggering Claude in a loop. - Pass options with
claude_args, for example--max-turns 5 --model claude-sonnet-5. Without a model argument the action uses the Claude Code default model. - Standards live in CLAUDE.md. Claude follows your repository's CLAUDE.md when it creates pull requests and answers requests (Part 2).
- Automatic review: if you want pull request review without maintaining a workflow, the docs point to the separate Code Review feature.
Costs and credentials
- Two costs: GitHub Actions minutes (the action runs on GitHub-hosted runners) and API tokens, unless you authenticate with a subscription token.
- Keep it cheap: write specific
@clauderequests, use issue templates for context, keep CLAUDE.md concise (it is read on every run), set--max-turns, add workflow timeouts and use GitHub's concurrency controls. - Never commit keys. Store them as GitHub Secrets and reference them, and grant the workflow only the permissions it needs.
- CI not running on Claude's commits? GitHub does not trigger workflows on commits made with the default
GITHUB_TOKEN. Remove an explicitgithub_tokeninput so the action authenticates as the Claude GitHub App. - Cloud providers: there are options to route the action through Amazon Bedrock, Google Cloud or Microsoft Foundry using identity federation, covered on a separate docs page.
6. Setting up a team
A team gets the most from Claude Code when everyone starts from the same baseline and each person can still personalise. The building blocks are all things you have met already:
| What | Where | Committed? | Who it affects |
|---|---|---|---|
| Project conventions, commands, gotchas | CLAUDE.md (and .claude/rules/) | Yes | Everyone on the repository |
| Shared workflows and know-how | .claude/skills/ | Yes | Everyone |
| Shared helpers | .claude/agents/ | Yes | Everyone |
| Shared permissions and defaults | .claude/settings.json | Yes | Everyone |
| Shared MCP servers | .mcp.json (project scope) | Yes | Everyone (each approves it) |
| Shared plugins | Project-scope plugin entry in .claude/settings.json | Yes | Everyone, after each runs the install once |
| Personal preferences | ~/.claude/CLAUDE.md, CLAUDE.local.md, settings.local.json | No (gitignore the local files) | Only you |
Habits that work, mostly from the docs and Part 3:
- Treat these files like code. Review changes in pull requests, because a bad rule or permission affects every future session.
- Turn mistakes into lines. When Claude gets something wrong that a teammate would also get wrong, add one line to CLAUDE.md. The official guide lists a repeated code-review comment as exactly that trigger.
- Pre-approve safe commands (tests, lint,
git status) in the shared settings so nobody clicks through the same prompt all day. - Agree on what Claude may not touch. Use deny rules for secrets and generated folders (Part 2).
- Pick a default surface and mode, and write down when to use plan mode and when to review manually.
- Use Claude to onboard people. The docs call asking a codebase the questions you'd ask another engineer “an effective onboarding workflow” that cuts ramp-up time and the load on other engineers.
7. For admins: managed settings and oversight
Shared files are conventions. If your organisation needs rules that cannot be overridden, the tool for it is managed settings: settings your organisation deploys to every developer's machine, applied above every other level. Per the docs, no user, project, local or --settings value overrides them, apart from a few security-sensitive exceptions where a stricter lower-level value still counts.
How it is delivered
| Mechanism | How | Use it when |
|---|---|---|
| Server-managed settings | Set in the claude.ai admin console; fetched at startup and polled hourly | You want one place to change policy for a claude.ai organisation without touching machines |
| MDM or OS-level policy | A macOS configuration profile or a Windows registry value, pushed with a tool such as Jamf, Intune or Group Policy | You already manage devices that way |
| A file on each machine | managed-settings.json in a system folder | No MDM, Linux hosts or images you build yourself |
The file locations are: macOS /Library/Application Support/ClaudeCode/managed-settings.json, Linux and WSL /etc/claude-code/managed-settings.json, and Windows C:\Program Files\ClaudeCode\managed-settings.json. The file uses the same shape as a normal settings.json. To check a machine, run /status in Claude Code: the “Setting sources” line shows Enterprise managed settings (file) when it applies. The docs offer starter templates for Jamf, Intune and Group Policy in an examples repository, and recommend testing on one machine before rolling out to the fleet.
What admins commonly control
- Permissions: allow, ask and deny rules for tools and files, and which permission modes are available. For example, an admin can turn auto mode off with a managed setting, which also removes it from the Shift+Tab cycle.
- MCP servers: restrict which servers may run, using managed MCP configuration. Reviewing
.mcp.jsonis not enough on its own, because servers can also come from other scopes, claude.ai connectors and plugins. - Plugins and marketplaces: which plugins users may install, and plugins that are required.
- Model and update behaviour: for example a minimum version, or which models are available.
Seeing usage and cost across a team
| Your setup | See spend | Cap spend |
|---|---|---|
| Claude Team or Enterprise | Spend report and an analytics dashboard in the claude.ai admin area | Seat allowance by default; usage credits with limits at organisation, group or member level |
| Claude Console (API) | The Console usage page and a Claude Code dashboard | Workspace spend limits |
| Amazon Bedrock, Google Cloud or Microsoft Foundry | Your cloud billing console | Your cloud's budget controls |
OpenTelemetry export works on every setup and is the only option that streams per-user token and cost metrics into your own monitoring stack in near real time. Remember from Part 3 that the official average is around $13 per developer per active day, with wide variation, so measure a small pilot before extrapolating.
Security basics for a team
- Claude Code starts with read-only permissions in Manual mode and asks before it edits or runs commands. You are responsible for reviewing what you approve.
- Use managed settings to enforce standards, share approved permission configurations through version control, and audit your permissions with
/permissions. - For sensitive work, run Claude Code in a sandbox or a dev container, and follow the docs' advice for untrusted content: review suggested commands, avoid piping untrusted content straight to Claude, and verify changes to critical files.
- Sandboxing (
/sandbox) restricts file and network access for shell commands so Claude can work more freely inside defined boundaries. - Report suspicious behaviour with
/feedback. Anthropic's Trust Center lists its compliance certifications for security reviews.
8. A rollout checklist
This list is my own suggestion, built from the docs above:
- Pilot with a few people and a small project, and measure cost and time saved before widening.
- Commit a shared baseline: a short CLAUDE.md, shared settings with safe allow rules and secret deny rules, and the skills your team actually repeats.
- Choose a delivery route for policy (admin console, MDM or file) and test it on one machine with
/status. - Decide the guardrails: which modes, which MCP servers, which plugins, and whether auto mode is allowed.
- Set up cost visibility before launch: dashboards, spend limits or OpenTelemetry.
- Automate carefully: start with a read-only review job before any job that writes, and keep humans in the merge step.
- Review and prune monthly: CLAUDE.md, skills, plugins and permissions all drift.
9. Wrap-up and glossary
claude -pturns Claude into a command-line tool with text or JSON output.- Unattended runs need explicit, narrow permissions and a way to fail rather than prompt.
- GitHub Actions brings
@claudeto issues and pull requests, with humans reviewing the result. - Teams share conventions in committed files and enforce policy with managed settings.
- Track cost from day one, and keep keys out of repositories.
Part 8, the last in the series, steps back from code: using the Claude apps for everyday work, plus a first-week learning plan and where to keep learning.
| Term | In plain words |
|---|---|
-p / print mode | Run Claude once without a conversation and print the answer. |
--bare | Skip auto-loading of plugins, memory, MCP servers and CLAUDE.md for repeatable runs. |
dontAsk | A permission mode that denies anything that would prompt. |
| Runner | The machine (for example a GitHub-hosted one) that executes a CI job. |
| Workflow | A GitHub Actions file describing when and how a job runs. |
| Managed settings | Organisation-deployed settings that users cannot override. |
| MDM | Mobile device management: tools that push policy to company computers. |
| OpenTelemetry | An open standard for exporting usage and performance data to monitoring tools. |