Self-Hosted Runner

A self-hosted runner lets SetForth's agents run on hardware you control — your own laptop, a server, or a machine inside your network. You install a small program, register it with SetForth from your dashboard, and it picks up agent work for your organization and runs it on that machine.

The runner only makes outbound connections to SetForth over HTTPS, so there is nothing inbound to open on your network. Each agent session runs inside Docker on the host, isolated from your other work.

Supported platforms

The runner is supported on macOS and Linux:

  • macOS — supported. Runs as a managed service via launchd.
  • Linux — supported. Runs as a managed service via systemd.
  • Windows — not supported directly. Run the runner inside WSL2 (a Linux distribution such as Ubuntu) or a Linux virtual machine, then follow the Linux instructions. Docker Desktop's WSL2 backend works for this.

Prerequisites

  • A macOS or Linux host. Windows is not supported directly — run the runner via WSL2 or a Linux VM and follow the Linux instructions.
  • Node.js 20 or newer on the machine that will run the runner.
  • Docker (Desktop or Engine), installed and running. The runner always runs agents inside containers, so Docker must be available on the host.
  • Anthropic credentials on the host. The agent is powered by Claude, so the host must provide credentials one of two ways (see Anthropic credentials below).
  • A SetForth account with a role that can manage runners in your organization. If you cannot see the Runners page in your dashboard, ask an organization admin to grant you access or to register the runner for you.

Anthropic credentials

The agent runs inside a Docker container on the host and is powered by Claude, so the host must supply Anthropic credentials. You do not need the Claude CLI installed for normal operation — the agent runs in the container, not from your shell. Provide credentials one of two ways:

  • ANTHROPIC_API_KEY environment variable. Set this in the runner's environment. Usage is billed to your Anthropic API account.
  • A Claude subscription via claude login. Sign in once on the host with the Claude CLI, and the runner uses that subscription. Usage counts against your Claude subscription. The CLI is only needed to perform that one-time login; it is not used at runtime.

Either option works. If both are present, the runner uses the ANTHROPIC_API_KEY.

Install

Install the runner CLI globally on the machine that will run your agents:

npm install -g @setforth/self-hosted-runner

This installs the set-forth-runner command.

Register the runner

In your SetForth dashboard, open Runners and add a runner. SetForth registers it and generates a runner.config.yml file with the values this runner needs to connect:

runnerId:    # this runner's id
orgId:       # your organization id
platformUrl: # the SetForth API origin to connect to
apiKey:      # this runner's secret access token

The apiKey is shown once, at registration time, and is not retrievable afterward. Copy the generated config right away and save it to a stable path, for example ~/.set-forth-runner/runner.config.yml.

Keep the apiKey secret. It is this runner's credential: anyone who has it can connect a runner to your organization and run agent work as you, so treat it like a password. Keep runner.config.yml out of version control and off shared machines. If the key is ever exposed, rotate it from the runner's menu in the dashboard (Rotate API key), which revokes the old one.

By default the runner reads runner.config.yml from the current directory. Start it from the folder that holds the file, or point at the file explicitly with --config /path/to/runner.config.yml.

Run the runner

There are two ways to run it.

Best for an always-on runner. It starts at boot, restarts on crash, and keeps running across logout (launchd on macOS, systemd on Linux):

set-forth-runner install-service --config ~/.set-forth-runner/runner.config.yml

The absolute path of the config file is recorded when you install the service, so keep runner.config.yml where it is afterward. A background service has no shell environment, so the connection values must all be present in the config file itself (the dashboard-generated file already includes them). Remove the service later with:

set-forth-runner uninstall-service

In the foreground

Runs in the terminal, which is handy for a quick test. It stops when you close the terminal, so it will not come back after a logout or reboot:

set-forth-runner start

Stopping cleanly

To stop a runner without interrupting work in progress, drain it. The runner finishes its current session and then exits:

set-forth-runner drain

Pressing Ctrl-C (or sending SIGTERM) does the same thing.

Checking the config

To confirm a config file resolves to a complete runner identity without actually starting the runner:

set-forth-runner validate-config --config ~/.set-forth-runner/runner.config.yml

Configuration reference

Beyond the connection values, runner.config.yml accepts optional settings:

  • agent.permission_modedefault runs the agent with its normal permission prompts; skip bypasses them. Use skip with caution.
  • agent.allowed_tools — a list restricting which tools the agent may use (for example Read, Edit, Write, Bash). Omit it to allow the defaults.
  • agent.disallowed_tools — a list of tools to deny. A denied tool wins over the allow list.
  • agent.max_turns — a cap on how many turns the agent may take per session.
  • agent.env — extra environment variables to pass to the agent process.
  • local_logs — write per-session logs on the host for local troubleshooting. Set enabled: true and, optionally, a directory (you can also override the location with the RUNNER_LOG_DIR environment variable).

A sample config with the connection values plus a few optional settings:

runnerId: your-runner-id
orgId: your-org-id
platformUrl: https://api.setforth.app
apiKey: your-secret-api-key

agent:
  permission_mode: default
  allowed_tools:
    - Read
    - Edit
    - Write
    - Bash
  max_turns: 100
  env:
    MY_CUSTOM_VAR: "value"

local_logs:
  enabled: true
  directory: ~/.set-forth-runner/logs

Updating

Upgrades are manual. Install the latest version, then drain the runner so it restarts on the new build:

npm install -g @setforth/self-hosted-runner@latest
set-forth-runner drain

If you run the runner as a managed service, it restarts automatically after draining. If you run it in the foreground, start it again after the upgrade.