June 20, 2026 8 min read by Mykola Samila

Most developers use Claude interactively — open the IDE, type a prompt, read the answer. That works fine for one-off tasks. But a growing chunk of AI-assisted work doesn't need a human in the loop at all: automated code reviews, scheduled dependency audits, PR summarisation, test generation on push. For those, you want Claude running somewhere in the cloud, triggered by events, without you sitting in the chair. This article covers exactly that.

Why run Claude remotely

The interactive loop is great for exploration, but it's the wrong shape for automation. When you're trying to run Claude on every pull request, or nightly on your documentation, or whenever a particular file changes — you need a non-interactive, scriptable, repeatable execution model.

Remote execution unlocks three things that interactive use can't give you:

The three main approaches are: Claude Code's headless (non-interactive) mode for script-level automation, the Anthropic Messages API for custom agent loops, and the Claude Agent SDK for orchestrating multi-step agents that run in isolated cloud environments.

Claude Code in headless mode

Claude Code ships with a --print flag that puts it into non-interactive mode. It reads a prompt, executes it against the current working directory, prints the result, and exits. No TTY required.

claude --print "Review the changes in the last commit and list any type errors"

You can pipe the output directly into another command, write it to a file, or POST it to an API:

claude --print "Summarise this PR in three bullet points" > /tmp/summary.txt

# Or pipe into jq if the output is JSON
claude --print "List all exported functions in src/api.ts as JSON" | jq '.[]'

The --output-format flag controls what you get back. Use json when you need machine-readable output:

claude --print "Find all TODO comments in src/ and return them as a JSON array with file and line fields" \
  --output-format json

To pass file content as context, pipe it into stdin:

cat src/auth/middleware.ts | claude --print "Identify any security issues in this file"

The --allowedTools flag controls what Claude can actually do during execution. In remote contexts you often want to restrict this:

claude --print "Generate unit tests for the exported functions in utils.ts" \
  --allowedTools "Read,Write" \
  --output-format text

Wiring it into CI/CD

A GitHub Actions workflow is the most natural place to start. Here's a real pattern I use for automated PR review:

# .github/workflows/claude-review.yml
name: Claude PR Review

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install Claude Code
        run: npm install -g @anthropic-ai/claude-code

      - name: Run review
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: |
          git diff origin/${{ github.base_ref }}...HEAD > /tmp/diff.txt
          REVIEW=$(cat /tmp/diff.txt | claude --print \
            "Review this diff. Focus on correctness bugs and security issues only. \
             Output a markdown list. If nothing significant, respond with 'LGTM'." \
            --output-format text)
          echo "REVIEW_BODY=$REVIEW" >> $GITHUB_ENV

      - name: Post review comment
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: process.env.REVIEW_BODY
            });

The key things to get right in CI: set ANTHROPIC_API_KEY as a secret, pin Claude Code to a specific version so runs are reproducible, and use --output-format text or json to get clean output rather than the interactive UI stream.

Keeping costs in check in pipelines

CI triggers on every push, which adds up. A few things that help:

The Claude Agent SDK for remote agents

Headless mode is great for simple prompts. For multi-step work — agents that read files, make decisions, call tools, and write back results — the Claude Agent SDK gives you proper orchestration with isolation and structured outputs.

The SDK lets you spawn agents that run in isolated environments (their own worktree copy of the repo, or a full remote cloud container) and return structured results:

import { Agent } from '@anthropic-ai/agent-sdk';

const result = await Agent({
  description: "Dependency audit",
  isolation: "remote",
  prompt: `Audit the package.json dependencies.
    For each dependency: check if it's outdated, flag any with known CVEs,
    and suggest whether to update, replace, or remove it.
    Return a JSON array with { name, currentVersion, latestVersion, action, reason }.`,
  model: "claude-sonnet-4-6",
});

With isolation: "remote", the agent runs in a cloud-hosted environment — it gets a fresh copy of your repo to work in, can read and write files, run shell commands, and return results, all without touching your local machine or any shared state.

The isolation: "worktree" option is lighter — it creates a temporary git worktree on the same machine. Good for local CI runners or when you want the agent to make code changes you can inspect before merging:

const result = await Agent({
  description: "Generate missing tests",
  isolation: "worktree",
  prompt: `Find all exported functions in src/utils/ that have no corresponding test file.
    For each one, generate a test file at the matching path in __tests__/.
    Use the existing test files as style reference.`,
});

If the agent makes changes, the worktree path and branch are returned in the result — you can then review, commit, or open a PR from that branch.

Scheduled and webhook-triggered agents

Cron-based agents are useful for recurring tasks: weekly dependency reviews, nightly documentation freshness checks, monthly dead code audits. The Claude Agent SDK's scheduling interface wraps this:

import { schedule } from '@anthropic-ai/agent-sdk';

await schedule({
  name: "weekly-dep-audit",
  cron: "0 9 * * 1", // Mondays at 9am
  prompt: `Audit outdated dependencies in package.json.
    Post a summary to the #engineering Slack channel with packages to update this sprint.`,
  model: "claude-haiku-4-5",
});

For webhook triggers — reacting to GitHub events, Jira ticket creation, a Slack command — wrap the agent call in a standard HTTP handler:

// api/webhooks/github.ts
import { Agent } from '@anthropic-ai/agent-sdk';

export async function POST(req: Request) {
  const payload = await req.json();

  if (payload.action !== 'opened') return new Response('ok');

  const prBody = payload.pull_request.body ?? '';
  const diff = await fetchPRDiff(payload.pull_request.diff_url);

  const result = await Agent({
    description: "PR summary",
    prompt: `Given this PR description and diff, write a one-paragraph plain-English summary
      of what changed and why. Keep it under 100 words.

      PR description: ${prBody}

      Diff:
      ${diff}`,
    model: "claude-sonnet-4-6",
    run_in_background: true,
  });

  await postGitHubComment(payload.pull_request.number, result);

  return new Response('ok');
}

The run_in_background: true flag is important for webhook handlers — it returns immediately (so GitHub doesn't time out the webhook) and notifies you when the agent finishes.

Security considerations

Remote execution means the agent can do real things: read files, write code, run commands. That makes the permission model worth thinking about carefully.

Limit tool access explicitly

Both in headless mode and the Agent SDK, you can restrict what tools the agent is allowed to use. For a read-only audit task, there's no reason to grant write permissions:

claude --print "Find all hardcoded API keys in the codebase" \
  --allowedTools "Read,Bash(grep,find)" \
  --disableTools "Write,Edit"

Never commit the API key

This sounds obvious but it bites people in pipelines. Use secrets management — GitHub Actions secrets, Vercel environment variables, AWS Secrets Manager, whatever your deployment stack offers. The ANTHROPIC_API_KEY should never appear in a YAML file or a .env committed to the repo.

Validate agent output before acting on it

If an agent's output is going to trigger another action — posting a comment, opening a PR, deploying code — treat it like any other external input. Sanitise it, validate the shape, and apply business logic before the downstream action runs. Agents can be prompt-injected through malicious content in the files they read.

Scope permissions to the task

A code review agent doesn't need write access to the production branch. A documentation agent doesn't need deploy credentials. Scope the API token permissions and the agent's allowed tools to the minimum required for each task. If the agent is compromised or produces unexpected output, the blast radius is contained.

What to watch out for

Context window limits in pipelines

Passing entire codebases to an agent doesn't scale. A 50,000-line repo will blow past the context limit and produce worse results than a well-scoped 500-line excerpt. Be deliberate about what you pass in: the specific file, the relevant diff, the function under review. More context is not always better.

Flaky outputs when the format isn't enforced

Interactive Claude tolerates loose prompts. Automated pipelines don't. If your downstream code expects JSON, say so explicitly in the system prompt, specify the schema, and validate the output before parsing. Add a retry with a stricter prompt if validation fails — don't let a malformed response crash a CI job silently.

Rate limits hitting in parallel pipelines

If ten PRs open simultaneously and each triggers an agent, you'll hit the Anthropic API rate limits fast. Add a queue with concurrency control rather than firing all requests at once. For high-volume pipelines, contact Anthropic about tier upgrades before you scale.

Agents modifying files you didn't expect

When an agent has write permissions and a vague prompt, it will sometimes modify files you didn't intend. Prefer isolation: "worktree" so changes happen on a separate branch you can review, rather than directly on the working tree. Treat agent output as a proposal, not a direct commit.

Building AI-powered pipelines or automating your development workflow?

Let's talk

← All articles  ·  Portfolio