Cloud & Background Agents
|
This content was generated with the assistance of AI and should be verified against the official documentation of each tool and framework before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
This page covers the two background-agent products in the AI section’s tool set: the Copilot cloud agent
(formerly called Copilot coding agent) and Claude Code on the web / GitHub Actions, checked
against the official Copilot docs and
Claude Code — GitHub Actions as of 2026-09-28. Both run a task
on a remote machine from a short instruction — an assigned issue or an @-mention — and open a pull request
for review, instead of working in a session you drive turn by turn the way
Claude Code and
Copilot do locally. The running example is again
DocsAssistant API, the Spring Boot + Python sample with its controller at
src/main/java/com/example/docsassistant/DocsController.java and a Python ingestion script under ingest/.
Copilot cloud agent
Assigning an issue
The most direct way to start a cloud-agent run is assigning a GitHub issue to Copilot the same way you would
assign it to a teammate: open the issue on github.com and set Copilot as the assignee (or, on a pull request,
comment @copilot with the change you want). Copilot then researches the repository, drafts an implementation
plan, and starts making changes on a new branch — all inside a GitHub Actions-backed environment, so the whole
run is visible as commit history and job logs rather than a private session. Suppose issue #241 in the
DocsAssistant repository reads:
Title: Add a health endpoint
Body: Add GET /api/health to DocsController that returns 200 with {"status":"ok"}.
Add a test for it under src/test/java/com/example/docsassistant/.
Assigning that issue to Copilot starts a run that ends with a draft pull request implementing it. See GitHub — About Copilot cloud agent.
Setting up the environment: copilot-setup-steps.yml
By default, the cloud agent’s environment starts from a base image with common language runtimes already
installed and no repository-specific setup. A workflow file at
.github/workflows/copilot-setup-steps.yml, containing a single job named exactly copilot-setup-steps, runs
before the agent starts working, so its steps can install dependencies, restore caches, or install project
tooling the agent will need; only steps, permissions, runs-on, services, snapshot and
timeout-minutes are read from this job, and the workflow must exist on the repository’s default branch. For
DocsAssistant API, a Java + Python repo, one job installs both toolchains and pre-fetches their dependencies:
name: "Copilot Setup Steps"
on: workflow_dispatch
jobs:
copilot-setup-steps:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v6
- uses: actions/setup-java@v5
with:
java-version: '21'
distribution: 'temurin'
cache: maven
- name: Pre-fetch Maven dependencies
run: mvn -B dependency:go-offline
- uses: actions/setup-python@v6
with:
python-version: '3.12'
cache: pip
- name: Install ingestion script dependencies
run: pip install -r ingest/requirements.txt
The on: workflow_dispatch trigger lets you also run this job manually from the Actions tab to confirm the
setup steps still succeed, independent of any agent run. See
GitHub — Customizing the development environment for Copilot cloud agent.
The firewall and the allowlist
Once running, the cloud agent’s outbound network access goes through a firewall that is on by default: it
always allows the hosts Copilot itself needs to talk to GitHub, and a recommended allowlist (also on by
default) additionally permits common OS package repositories, container registries, language package
registries, certificate authorities and a few other categories, so mvn dependency:go-offline or pip install
inside a run works without extra configuration. A repository admin adds further addresses under repository
Settings → Copilot → Internet access → Custom allowlist, as either a bare domain (matches that domain and
its subdomains, e.g. packages.contoso.corp) or a full URL restricted to one scheme, host and path (e.g.
https://packages.contoso.corp/project-1/); the same settings page can also disable the firewall entirely
where an organization policy allows it. When a request is blocked, Copilot doesn’t fail silently: it adds a
warning to the pull request body (or a comment, if the PR already exists) naming the blocked address and the
command that tried to reach it, which is usually enough to decide whether to allowlist it or change the
approach. This firewall applies to commands the agent runs through its own shell tool; it does not cover MCP
servers or the copilot-setup-steps job itself, so a dependency the setup job needs must already be reachable
during that job. See
GitHub — Customizing or disabling the firewall for Copilot cloud agent.
The PR loop and iterating via comments
All of the agent’s work happens on GitHub, not in a hidden sandbox: Copilot pushes commits to the branch as it goes, opens a pull request once it has something to show, and the PR’s own timeline is the run’s audit trail. Once the PR is open, review it the way you would a teammate’s: reading the diff, checking CI, and leaving comments. Commenting with feedback is how you iterate —
@copilot the health endpoint should also check the database connection before returning "ok"
— picks the agent’s run back up, and it pushes a follow-up commit addressing the comment rather than starting a new PR. Repeating this comment-review cycle is the normal way to drive a cloud-agent task to completion, and it is the same PR review, merge and cross-linking machinery documented in Pull Requests. See GitHub — About Copilot cloud agent.
Choosing the model
Where you start a cloud-agent task determines whether you get to choose its model: assigning an issue on
github.com, @copilot-mentioning it in a pull request comment, or starting one from the Agents tab or panel
(also GitHub Mobile and the Raycast launcher) all show a model picker before the run starts, offering an Auto
option plus specific models from several providers; starting a run any other way defaults to Auto. Some
models expose a second dropdown for a reasoning-effort level, trading more time and usage for more careful
answers on harder tasks. Since the available models and their names change over time, pick from the picker’s
current list rather than a hard-coded one here, and see
Choosing Models in Your Assistant for
how this compares to model selection elsewhere in Copilot and in Claude Code. See
GitHub — Changing the AI model used by Copilot cloud agent.
Claude Code on the web / GitHub Actions
Claude Code reaches a repository on GitHub in two different ways that this sub-section keeps distinct:
Claude Code in the cloud at claude.ai/code runs a full session on hosted
infrastructure instead of your machine, started from the browser, the Claude app or claude --cloud; the
Claude Code GitHub Action (anthropics/claude-code-action) is a workflow you add to the repository so
@claude mentions and other GitHub events start a run inside GitHub Actions itself. Their GitHub prerequisites
differ. A cloud session connects GitHub in one of two ways: authorizing the Claude GitHub App during web
onboarding, or running /web-setup in a local Claude Code session, which sends your local gh CLI token to your
Claude account so sessions can reach any repository that token can. The GitHub Action, and Auto-fix for pull
requests in cloud sessions, require the Claude GitHub App installed on the repository, granting it read/write
access to contents, issues and pull requests so it can push commits and comment.
Starting a cloud session
Open claude.ai/code, pick the DocsAssistant repository and type the task, or start the
same session from a local checkout with the --cloud flag:
$ claude --cloud "add GET /api/health to DocsController that returns 200 with a JSON status of ok,
plus a test under src/test/java/com/example/docsassistant/"
The cloud VM clones the repository’s GitHub remote at your current branch, not your local working tree, so push
any local commits first; the session keeps running after you close the terminal, and claude --teleport pulls it
back into a local session later. As of 2026-09-28, cloud sessions are available on Pro, Max and Team plans and for
Enterprise premium or Chat + Claude Code seats. See
Claude Code — Use Claude Code in the cloud.
Installing the GitHub App and @claude mentions
The fastest path is running /install-github-app inside a local Claude Code session, which installs the
Claude GitHub App, stores an ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN repository secret, and opens a
pull request adding the workflow file:
$ claude
> /install-github-app
Without a local Claude Code session, install the Claude GitHub App manually,
add one of those two secrets under repository Settings → Secrets and variables → Actions, and copy the
workflow file from the action’s own
examples/claude.yml into
.github/workflows/. Either way, once the workflow is merged, mentioning @claude in an issue or pull request
comment starts a run:
@claude add a GET /api/health endpoint to DocsController that returns {"status":"ok"}, with a test
Claude replies on that same issue or PR with a comment, and updates it as it works. See Claude Code — GitHub Actions.
The claude-code-action workflow
The action detects two modes from the workflow’s own inputs: leaving out a prompt puts it in interactive
mode, responding only when the trigger phrase (@claude by default) appears; setting a prompt puts it in
automation mode, running on whatever event triggers the workflow with no mention needed. A minimal
interactive workflow, the "Respond to @claude mentions" example from the Claude Code GitHub Actions docs:
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 }}
The if condition keeps the job from starting a runner for every comment; the action itself checks the trigger
phrase again, and separately requires the commenting user to have write access to the repository and not be a
bot, unless explicitly allowed. id-token: write is needed for the action’s GitHub App authentication and
actions: read lets Claude read CI results on the PR. Passing CLI options — for example capping turns and
naming a model — goes through claude_args, using the same baseline model as the rest of this sub-section:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
claude_args: |
--max-turns 5
--model claude-sonnet-5
See Claude Code — GitHub Actions and
Headless & CI Automation for claude -p and
other non-interactive uses of the CLI itself.
Choosing tasks and reviewing the result
A checklist for bounded, measurable tasks
Both agents run unattended for minutes at a time before you see a result, so the task you hand one matters more
than with an interactive session where you can redirect it mid-turn. Before assigning an issue or firing off an
@claude mention, check that the task is:
-
Bounded — one endpoint, one bug, one refactor; not "improve the API" or "modernize the codebase".
-
Locatable — the issue or prompt names the file or module to change, e.g.
DocsController.java, not just a symptom. -
Verifiable — there is an existing test, or the task asks for one, that the agent (and you) can run to check the result, rather than relying on eyeballing the diff.
-
Independent — it doesn’t depend on another in-flight change to the same files, which invites merge conflicts once the PR is ready.
-
Reviewable in one pass — the expected diff is small enough that Reviewing AI-Generated Code's checklist can be applied to the whole PR at once.
A task like "add GET /api/health returning \{"status": "ok"}, with a test" satisfies all five; "clean up
the ingestion pipeline" satisfies none of them and is better run as an interactive session where you can steer
it, per Agent Mode.
"Coherent incorrectness"
A background agent’s plan-then-execute loop tends to produce pull requests that are internally consistent — matching naming, matching style, a plausible-looking test — even when the underlying approach is wrong, for
example solving the wrong ambiguity in the issue, or adding a health check that always returns ok without
actually checking the database. Nothing about the diff looks wrong, which is exactly what makes this failure
mode easy to approve without reading closely; a well-formed PR is not the same signal as a correct one. The
practical defense is unchanged from any other PR: read the diff against the original issue’s acceptance
criteria, not just against "does this compile and pass CI", and treat a cloud-agent PR as a first draft from an
unfamiliar contributor rather than as ground truth.
See Pull Requests for the review and merge mechanics this loop relies on, and Issue for a worked issue-to-PR pipeline built on top of the same idea.