What the GitHub Action actually does
anthropics/claude-code-action runs Claude Code inside your repository's workflows. Two distinct uses come out of that:
Mention @claude in an issue or pull request comment and it analyses code, implements changes, and pushes commits — replying in a comment on the same thread and updating it as it works.
Give it a prompt and it runs automatically on any GitHub event: on every pull request, on a cron schedule, on a label being added. No mention needed.
The second is where most of the durable value is. A review that runs on every PR without anyone remembering to ask is worth more than a helpful assistant you have to summon.
Four things share the name — pick the right one
Worth two minutes now, because choosing wrong means building a workflow you did not need.
| If you want | Use |
|---|---|
@claude in comments, and custom automation you control |
Claude Code GitHub Actions — this article |
| Automatic review on every PR, with no workflow file to maintain | Code Review, a separate product |
| Claude Code sessions from a browser or phone | Claude Code on the web |
| Automation outside GitHub entirely | Claude Agent SDK — the Action is built on it |
If all you want is PR review and you do not care how it is configured, use Code Review and stop reading. Everything below is for people who want control of the prompt, the model, the triggers, and the tools.
Setting it up
Two routes. Both need admin access to the repository.
Quick setup
Install the GitHub CLI and run gh auth login first — Claude Code checks for it and warns if it is missing. Then, in the repository:
claude
/install-github-app
That installs the Claude GitHub App, stores an authentication secret, pushes a branch with the workflow files you select, and opens a pull request ready to create. Merge it and @claude works.
The secret is named ANTHROPIC_API_KEY for an API key, or CLAUDE_CODE_OAUTH_TOKEN for a subscription token.
Manual setup
Use this if you do not run Claude Code locally, if the command fails, or if you want the workflow files under your own control.
- Install the Claude GitHub App. The Action relies on three of its permissions: Contents, Issues, and Pull requests, all read and write.
-
Add a secret. Either
ANTHROPIC_API_KEYfrom the Console, orCLAUDE_CODE_OAUTH_TOKENgenerated locally withclaude setup-token(available on Pro, Max, Team, and Enterprise). -
Copy a workflow file into
.github/workflows/. The examples in the action's repository are working workflows, not sketches.
One note on the app's permissions that catches security teams: the Claude GitHub App is shared by every Claude feature that integrates with GitHub, so its permission set is broader than this Action uses — it includes Actions, Checks, Discussions, Members, Statuses and more. GitHub does not let you accept a subset. If your organisation will only grant what is actually needed, create a custom GitHub App with Contents, Issues, and Pull requests. A custom app covers this Action only; Code Review and web auto-fix still require the official one.
Interactive mode and automation mode
You do not choose the mode. The Action infers it from one thing: whether you supplied a prompt input.
| Interactive | Automation | |
|---|---|---|
| Triggered by |
@claude in a comment, review, or new issue |
Any GitHub event |
prompt input |
Absent | Present |
| Where output goes | A comment on the issue or PR | The workflow run log, unless the prompt says otherwise |
That last row is the one that confuses people. In automation mode Claude writes to the run log by default. If you want the output on the pull request, the prompt has to say so and Claude needs a tool that can post.
Workflow 1: respond to @claude
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 }}
Four lines in there are doing real work and are easy to omit:
-
id-token: write— required for the Action's default GitHub App authentication. -
actions: read— lets Claude read CI results on the PR. Without it, it cannot see why your build failed. -
actions/checkout— gives Claude a local copy to work in. - The
if:condition — stops a runner starting on every comment. The Action checks the trigger phrase itself too, but by then you have already paid for the runner.
Then in any issue or PR:
@claude fix the TypeError in the user dashboard component @claude how should I implement authorisation for this endpoint?
The trigger phrase is configurable via trigger_phrase. It must appear as a complete word — /claude and @claude-bot do not match.
Workflow 2: review every pull request
The higher-value workflow, because it runs whether or not anyone remembers.
name: Code Review
on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]
jobs:
review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
plugin_marketplaces: "https://github.com/anthropics/claude-code.git"
plugins: "code-review@claude-code-plugins"
prompt: "/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number }}"
claude_args: '--allowedTools "mcp__github_inline_comment__create_inline_comment"'
Two lines control where the review ends up, and both are non-obvious:
--comment makes Claude post the review on the pull request — inline on each issue it finds, or one summary comment when it finds none. Leave it out and the findings sit in the run log where nobody reads them.
claude_args with --allowedTools must name the inline-comment tool even though the skill's own allowed-tools frontmatter already does. The Action starts the MCP server that posts inline comments only when --allowedTools in claude_args names it. Omit this and the review runs, finds things, and silently posts nothing.
Note also that prompt accepts a skill invocation, not just plain text. For a skill in your own repository, run actions/checkout first and pass /skill-name. For one in a plugin, install it via plugin_marketplaces and plugins, then pass the namespaced /plugin-name:skill-name.
Claude skips draft and closed pull requests, ones it judges trivial or automated, and ones that already carry a comment from it. On public repositories GitHub withholds secrets from fork pull requests, so reviews run only on same-repository branches.
Workflow 3: run on a schedule
name: Daily Report
on:
schedule:
- cron: "0 9 * * *"
jobs:
report:
runs-on: ubuntu-latest
permissions:
contents: read
issues: read
id-token: write
steps:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: "Generate a summary of yesterday's commits and open issues"
claude_args: |
--model claude-opus-4-8
--allowedTools "mcp__github__list_commits,mcp__github__list_issues"
Notice there is no checkout step. Claude reads commits and issues through the GitHub API using the two MCP tools granted in claude_args, so it never needs the files.
The critical detail for scheduled runs: with a plain-text prompt, Claude has no shell or GitHub API access until you grant it. Either --allowedTools in claude_args, or a permissions.allow rule in the settings input. Invoke a skill instead and it gets whatever its allowed-tools frontmatter grants.
Two GitHub behaviours to plan around: scheduled workflows run only from the default branch, and on public repositories GitHub disables the schedule after 60 days without repository activity.
Who can trigger a run
Before Claude starts, the Action runs two checks on the triggering actor. Either one failing fails the run.
Write access. On issue and pull request events the user must have write access to the repository. To allow specific users without it, set allowed_non_write_users and pass your own github_token. Events with no author — a schedule trigger — skip this check.
Human actor. Bot actors are rejected unless listed in allowed_bots. This exists to stop bots triggering Claude in a loop, and it catches a case people do not expect: GitHub attributes scheduled runs to a repository user, usually whoever last changed the cron line. If that account is a bot, your schedule silently never runs until you list it.
Credentials, and the org-wide case
Never commit a key. Store it as a GitHub Secret and reference it as ${{ secrets.ANTHROPIC_API_KEY }}. That is the whole rule for a single repository.
Across an organisation:
- Install the GitHub App once at the organisation level.
- Store the secret as an organisation-level Actions secret so each repository does not need a copy.
- Use an API key rather than an OAuth token for a shared secret — an OAuth token is tied to the subscription of whoever ran
claude setup-token. - Define the job once as a reusable workflow that each repository calls, rather than copying YAML into dozens of repositories.
To avoid a long-lived secret entirely, authenticate through workload identity federation: the Action exchanges the workflow's GitHub OIDC token for Claude API access via a Console service account. Set anthropic_federation_rule_id and anthropic_organization_id, and grant the workflow id-token: write — which is needed for the federation exchange even when you pass your own github_token.
The wider deployment picture, including routing through Bedrock, Google Cloud's Agent Platform or Microsoft Foundry with use_bedrock, use_vertex and use_foundry, is covered in Claude Code for teams and enterprise.
Keeping the bill down
Every run spends two things: GitHub Actions minutes on the runner, and tokens.
The levers, in rough order of effect:
-
--max-turnsinclaude_args— a hard cap on iterations. The single most effective control. - Workflow-level timeouts, so a stuck job cannot burn an hour of runner time.
- Concurrency controls to limit parallel runs on a busy repository.
-
A concise
CLAUDE.md— it is read on every run, so every unnecessary line is billed repeatedly. This is the same argument for keeping it short that applies locally, with a meter attached. -
Specific requests. A vague
@claudemention costs more because it takes more turns to work out what you meant.
If you authenticate with an OAuth token, runs draw on your Claude subscription rather than API billing.
The four failures worth knowing in advance
Claude does not respond to @claude
Check, in order: the GitHub App is installed on this repository; workflows are enabled; the secret is set; the comment contains @claude as a complete word; and the commenting user has write access.
CI does not run on Claude's commits
GitHub does not trigger workflows on commits made with the default GITHUB_TOKEN. If you passed github_token: ${{ secrets.GITHUB_TOKEN }}, remove it so the Action authenticates as the Claude GitHub App instead — or pass a custom app token. This one looks like a broken CI configuration and is not.
The review runs but posts nothing
Almost always the missing --comment flag or the missing --allowedTools entry. Check the run log; the findings will be sitting in it.
Your old workflow stopped working
If it references @beta, migrate: change @beta to @v1, remove the mode input (the Action detects it now), rename direct_prompt to prompt, and move options like max_turns and model into claude_args.
Where to go next
The review this Action runs is a skill, usually delivered by a plugin — those two guides cover what to put in yours. For enforcing standards locally rather than in CI, see Claude Code hooks, and for the project context every run inherits, a production CLAUDE.md. The prompts worth automating are in the prompt library, and where CI fits in a full build is in the complete website workflow.
Sources and further reading
- Claude Code: GitHub Actions — setup, modes, parameters, troubleshooting
- anthropics/claude-code-action — the action itself, with example workflows
-
Claude Code: CLI reference — everything
claude_argsaccepts - GitHub: using secrets in Actions