Service: Claude Runner - EyevinnOSC/community GitHub Wiki

Getting Started

Run headless Claude Code sessions as one-shot jobs in Eyevinn Open Source Cloud. You provide a git repository and a prompt; Claude Runner clones the repo and executes the task non-interactively inside a container.

This is useful for automated code review, report generation, CI-triggered agent runs, batch processing, and scheduled agentic tasks where you want Claude Code's full file system and tool access without running it locally.

Prerequisites

Authentication

Claude Runner supports two authentication methods. At least one is required.

Option 1: Anthropic API Key

Obtain an API key from console.anthropic.com. The key starts with sk-ant-. This is the standard way to authenticate with the Claude API and works for all use cases.

Option 2: Claude OAuth Token (Recommended)

The Claude OAuth token is the recommended approach when you want access to all Claude Code features, including features tied to a Claude subscription. Generate one by running the following command in your terminal:

claude setup-token

Complete the OAuth flow in the browser that opens. When it finishes, the terminal outputs a token you can copy and store as a secret.

Store Credentials as OSC Secrets

Keep sensitive values out of your commands by storing them as OSC service secrets. Read the guide on how to work with secrets for instructions on how to create a secret and refer to it.

Recommended secrets to create before running jobs:

Secret name Value
claudeoauthtoken Your Claude OAuth token (from claude setup-token)
anthropicapikey Your Anthropic API key (if using API key auth instead)
gittoken A GitHub PAT or Gitea token, for private repositories
oscaccesstoken Your OSC personal access token, if the job manages OSC services via MCP

Once created, reference a secret in any option value using the {{secrets.secretname}} syntax.

Inject Environment Variables with a Parameter Store

For jobs that need additional configuration such as API keys for Slack, webhook URLs, database credentials, or any other environment variables, use an OSC Application Config Service (parameter store) together with the ConfigSvc option.

When ConfigSvc is set (along with OscAccessToken), Claude Runner loads all key-value pairs from the parameter store and injects them as environment variables before the Claude session starts. This means your CLAUDE.md or skills can reference these variables, and any tools Claude runs (such as Bash commands or scripts) will have access to them.

Setting up a parameter store

  1. Create a parameter store using the OSC CLI or web console:
npx -y @osaas/cli create eyevinn-app-config-svc myagentconfig \
  -o RedisUrl="<valkey-url>"

Or use the setup-parameter-store helper which creates both the Valkey instance and the config service in one step.

  1. Set the environment variables your job needs:
curl -X PUT "https://<tenant>-myagentconfig.eyevinn-app-config-svc.auto.prod.osaas.io/api/v1/config/SLACK_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{"value": "https://hooks.slack.com/services/T00/B00/xxxx"}'
  1. Reference the parameter store name in ConfigSvc when creating a Claude Runner job (see the example below).

Examples

Here are some examples of use cases that Claude Runner can handle and how to create jobs with the Open Source Cloud CLI. Before running any of the examples, set your personal access token in the environment variable OSC_ACCESS_TOKEN.

% export OSC_ACCESS_TOKEN=<your-personal-access-token>

You find your personal access token in the Open Source Cloud web console (Settings/API).

Code Review

Analyze a public repository for potential bugs and security issues.

% npx -y @osaas/cli create birme-claude-runner codereview \
  -o ClaudeCodeOauthToken="{{secrets.claudeoauthtoken}}" \
  -o SourceUrl="https://github.com/myorg/myrepo" \
  -o Prompt="Review the code in src/ for potential bugs and security issues. Write a summary report to review.md." \
  -o MaxTurns="10"

Run a Scheduled Task from an Agent Repository

Run a daily report task defined in a dedicated agent repo containing a CLAUDE.md with instructions.

% npx -y @osaas/cli create birme-claude-runner dailyreport \
  -o ClaudeCodeOauthToken="{{secrets.claudeoauthtoken}}" \
  -o SourceUrl="https://github.com/myorg/agent-tasks#main" \
  -o Prompt="Run the daily report task" \
  -o Model="claude-sonnet-4-5-20250514" \
  -o MaxTurns="25"

The #main suffix pins the job to the main branch. Use any valid branch name or omit the fragment to use the default branch.

Work on a Specific Subdirectory in a Monorepo

Use SubPath to scope Claude to a single package within a larger repository.

% npx -y @osaas/cli create birme-claude-runner analyze \
  -o ClaudeCodeOauthToken="{{secrets.claudeoauthtoken}}" \
  -o SourceUrl="https://github.com/myorg/monorepo" \
  -o SubPath="packages/api" \
  -o Prompt="Analyze the API package and suggest performance improvements." \
  -o DisallowedTools="Edit,Write" \
  -o MaxTurns="15"

Setting DisallowedTools="Edit,Write" makes this a read-only analysis run; Claude can explore and report but cannot modify files.

With OSC MCP Integration

Supply OscAccessToken to give Claude Runner access to the OSC MCP server at mcp.osaas.io/mcp. This lets Claude manage OSC services, check instance health, and perform operations through the platform's AI interface.

% npx -y @osaas/cli create birme-claude-runner oscops \
  -o ClaudeCodeOauthToken="{{secrets.claudeoauthtoken}}" \
  -o OscAccessToken="{{secrets.oscaccesstoken}}" \
  -o SourceUrl="https://github.com/myorg/infra-config" \
  -o Prompt="Check the health of all my OSC service instances and create a status report in status.md." \
  -o MaxTurns="20"

Inject Environment Variables from a Parameter Store

Use ConfigSvc to load environment variables (such as API keys for Slack or other services) from an OSC parameter store into the job. This requires OscAccessToken to be set as well.

% npx -y @osaas/cli create birme-claude-runner slackreport \
  -o ClaudeCodeOauthToken="{{secrets.claudeoauthtoken}}" \
  -o OscAccessToken="{{secrets.oscaccesstoken}}" \
  -o ConfigSvc="myagentconfig" \
  -o SourceUrl="https://github.com/myorg/agent-tasks" \
  -o Prompt="Generate the weekly status report and post it to Slack using the SLACK_WEBHOOK_URL environment variable." \
  -o MaxTurns="15"

In this example, the parameter store myagentconfig contains a key SLACK_WEBHOOK_URL. Claude Runner loads it as an environment variable before starting, so Claude can use it in Bash commands or scripts.

Private Repository with Git Token

Pass a GitHub PAT or Gitea token via GitToken to clone private repositories.

% npx -y @osaas/cli create birme-claude-runner privreview \
  -o ClaudeCodeOauthToken="{{secrets.claudeoauthtoken}}" \
  -o GitToken="{{secrets.gittoken}}" \
  -o SourceUrl="https://github.com/myorg/private-repo" \
  -o Prompt="Run the test suite and report any failures with suggested fixes." \
  -o MaxTurns="20"

Preparing Your Repository

Claude Runner clones whatever repository you point it to, then executes Claude Code from the root (or SubPath if set). For best results, prepare the repository as follows.

Add a CLAUDE.md file at the repository root. This is Claude Code's primary context document. Include:

  • A description of what the project does
  • Coding conventions and style guidelines
  • Instructions for how Claude should approach tasks in this repo
  • Any environment details or constraints

Optionally add a .claude/ directory containing:

  • settings.json for tool permissions and environment configuration
  • skills/ for reusable prompt templates Claude can invoke during the session

The repository should contain whatever source code, configuration files, or data Claude needs to accomplish the task you specify in Prompt.

Tool Control

AllowedTools and DisallowedTools let you restrict which Claude Code tools are available during a job. Both accept a comma-separated list of tool names.

Use DisallowedTools to block specific tools while keeping everything else available:

DisallowedTools="Edit,Write,Bash"

Use AllowedTools to create a whitelist; only the listed tools will be available:

AllowedTools="Read,Grep,Glob,WebFetch"

Common patterns:

Goal Setting
Read-only code analysis DisallowedTools="Edit,Write"
Pure research, no file access AllowedTools="WebFetch,WebSearch"
Read files only, no shell AllowedTools="Read,Grep,Glob"
Full access (default) Leave both options unset

Configuration Options

Option Required Secret Description
name Yes No Job name (alphanumeric and underscores only)
Prompt Yes No The task or instruction for Claude to execute
SourceUrl Yes No Git repository URL; append #branch for a specific branch
AnthropicApiKey One of these two Yes Anthropic API key (sk-ant-...)
ClaudeCodeOauthToken One of these two Yes Claude OAuth token from claude setup-token
GitToken No Yes GitHub PAT or Gitea token for private repositories
Model No No Claude model to use, e.g. claude-sonnet-4-5-20250514
MaxTurns No No Maximum agentic turns; limits runaway loops
AllowedTools No No Comma-separated whitelist of permitted tools
DisallowedTools No No Comma-separated blacklist of tools to block
SubPath No No Working subdirectory within the repo, for monorepos
OscAccessToken No Yes OSC personal access token; auto-configures the OSC MCP server
ConfigSvc No No Name of an OSC parameter store instance; loads its keys as env vars

Troubleshooting

Job exits immediately with an auth error: Verify that ClaudeCodeOauthToken or AnthropicApiKey is set and that the secret reference ({{secrets.name}}) matches an existing secret in your OSC account.

Repository not found or clone fails: For private repositories, ensure GitToken is set with a token that has read access to the repo. Double-check the SourceUrl for typos.

Claude stops mid-task: The job may have reached MaxTurns. Increase MaxTurns or split the task into smaller jobs.

Claude modifies files you did not want changed: Use DisallowedTools="Edit,Write" to prevent file modifications, or use AllowedTools to define an explicit whitelist.

SubPath not found: The path is relative to the repository root. Check the exact directory name in the repository and ensure it exists on the branch you are targeting.

Support

Join our Slack workspace for real-time support and to connect with other users.

⚠️ **GitHub.com Fallback** ⚠️