Skip to content
Coder Docs

Agent Relay configuration reference

Every Agent Relay option, pool field, and Helm chart value for the beta.

On this page

This page lists the Agent Relay options, pool fields, and Helm chart values that the beta supports. For a guided installation, refer to Set up Agent Relay.

Configuration sources

Agent Relay reads each option from three sources, in this order of precedence:

  1. A command-line flag, such as --log-level.
  2. An environment variable, such as CODER_AGENT_RELAY_LOG_LEVEL.
  3. A key in the YAML file that --config points to, such as logLevel.

The Helm chart sets options through environment variables and doesn't use a configuration file. Each option below lists its Helm value. Refer to Helm values for chart settings that aren't Agent Relay options.

Keep credentials out of the configuration file:

  • Set the session token with the CODER_AGENT_RELAY_CODERD_SESSION_TOKEN environment variable. Do not put it in the configuration file.
  • Set each pool's secret_env to the name of an environment variable that holds the pool's secret.

Agent Relay validates its options and pool fields at startup. An invalid value stops the daemon with an error that names the option or pool.

Coder deployment

--coderd-url

PropertyValue
Typeurl
Environment$CODER_AGENT_RELAY_CODERD_URL
YAMLcoderdURL
Helmcoderd.url

The access URL of the Coder deployment that Agent Relay serves. This flag is required.

--coderd-session-token

PropertyValue
Typestring
Environment$CODER_AGENT_RELAY_CODERD_SESSION_TOKEN
YAMLcoderSessionToken
Helmcoderd.sessionToken.secretName and coderd.sessionToken.key

The session token of the Agent Relay service account. This flag is required. Prefer the environment variable to the flag or the coderSessionToken configuration file key. The Helm chart reads it from a Kubernetes secret and doesn't accept it as a plain value. Refer to Step 1: Create a service account.

--config

PropertyValue
Typepath
Environment$CODER_AGENT_RELAY_CONFIG_PATH

The path to a YAML configuration file.

Pools

A pool maps a provider credential to a Coder organization and template. Configure at least one pool across both providers. A provider without pools is turned off.

Set pools in the YAML file, in Helm values, or as a JSON array in the pool option's environment variable:

export CODER_AGENT_RELAY_CLAUDE_CODE_RUNNER_POOLS='[{"name":"example","secret_env":"CLAUDE_ENVIRONMENT_SECRET","organization":"coder","template":"claude-code-relay"}]'
export CODER_AGENT_RELAY_CURSOR_WORKER_POOLS='[{"name":"example","secret_env":"CURSOR_SERVICE_ACCOUNT_KEY","cursor_pool_name":"example-pool","organization":"coder","template":"cursor-relay"}]'

--claude-code-runner-pools

PropertyValue
Typelist of pools
Environment$CODER_AGENT_RELAY_CLAUDE_CODE_RUNNER_POOLS
YAMLclaudeCodeRunnerPools
Helmpools.claudeCode

The Claude Code self-hosted environments to serve. Each pool maps an environment key to a Coder organization and template. Refer to Pool fields and Agent Relay for Claude Code.

--cursor-worker-pools

PropertyValue
Typelist of pools
Environment$CODER_AGENT_RELAY_CURSOR_WORKER_POOLS
YAMLcursorWorkerPools
Helmpools.cursor

The Cursor self-hosted pools to serve. Each pool maps a Cursor service account API key to a Coder organization and template. Refer to Pool fields and Agent Relay for Cursor.

Pool fields

Fields for every pool

FieldRequiredDescription
nameYesA unique label for the pool in Agent Relay logs and metrics. It has no meaning to the provider.
secret_envYesThe name of the environment variable that holds the pool's secret: the environment key for Claude Code, or the service account API key for Cursor. Agent Relay doesn't start if the variable is unset or empty.
organizationYesThe name or UUID of the Coder organization whose members run sessions from this pool. The Agent Relay service account must be a member of it.
templateYesThe name or UUID of the template that the pool's workspaces build from. Each pool uses one template.
template_parametersNoFixed parameter values that Agent Relay sets on every build from this pool, as a map of parameter names to values. Use it for required or environment-specific parameters. Agent Relay doesn't log the values.
idle_release_timeoutNoHow long a session can go without a new message after the agent finishes a turn before it's released and its workspace is deleted, as a duration such as 30m. Defaults to 1h. 0 turns off idle release. Claude Code needs whole minutes, up to 168h. Cursor needs whole seconds and logs a warning at startup for values below 5m. Agent Relay refuses to start on a number without a unit.
template_versionNoA version name or UUID of template that every build from this pool uses, including rebuilds. Leave it unset to use the active version. Refer to Pin a template version.

Agent Relay also accepts an inline secret field in place of secret_env. Set exactly one of the two. Use secret_env to keep the secret out of configuration files and Helm values.

Claude Code pool fields

FieldRequiredDescription
claude_tag_channel_userNoThe Coder user who owns workspaces for Claude Tag channel sessions. Set me for the Agent Relay service account, or the UUID of a user in the pool's organization. When it's unset, Agent Relay rejects channel sessions. Refer to Configure Slack for Agent Relay.

Cursor pool fields

FieldRequiredDescription
cursor_pool_nameYesThe pool name that workers register under in Cursor and that developers select. It's separate from name, which only labels the pool in Agent Relay.
dispatch_deadlineNoThe longest time from claim to a ready workspace, as a duration such as 10m. Defaults to 10m, with a maximum of 15m. 0 turns off the deadline, but Agent Relay still deletes a workspace that is building after 15 minutes.

Agent Relay refuses to start if:

  • More than four pools share one API key.
  • Two pools that share an API key use the same cursor_pool_name.
  • A dispatch_deadline is longer than 15 minutes.

Pin a template version

Leave template_version unset so that builds use the template's active version, and roll out changes by promoting a version in Coder. When a pool sets template_version, all of its builds use that version, including rebuilds of existing workspaces:

  • If the template requires the active version, Coder refuses builds from any other version unless the Agent Relay service account has update on the template. Agent Relay marks the pool degraded before it starts serving if the account lacks that permission, but doesn't check again. If someone promotes a newer version later, every session fails at build time.
  • If the version is deleted, archived, or renamed, the pool degrades and its sessions fail without retry until you fix the configuration.
  • The pool doesn't pick up newly promoted versions, so module and contract changes don't reach it.

Reserved template parameter names

Agent Relay sets these parameters on every build to carry the session's identity. It refuses to start if a pool's template_parameters uses one of them.

ProviderReserved names
Claude Codeagent_relay_session_id, agent_relay_delivery_id, agent_relay_pool, agent_relay_client_platform, agent_relay_claude_code_release_idle_session_min, agent_relay_credential, agent_relay_claude_code_lock_to_account, agent_relay_attempt
Cursoragent_relay_session_id, agent_relay_delivery_id, agent_relay_pool, agent_relay_cursor_pool_name, agent_relay_cursor_repo_url, agent_relay_credential, agent_relay_cursor_idle_release_timeout, agent_relay_cursor_credential_kind

Cursor request queue

These options apply to every Cursor pool. The Helm chart has no dedicated values for them. Set them with extraEnv.

--cursor-relist-interval

PropertyValue
Typeduration
Environment$CODER_AGENT_RELAY_CURSOR_RELIST_INTERVAL
YAMLcursorRelistInterval
Default5m0s

How often each Cursor pool lists pending requests. Agent Relay also follows Cursor's event stream, but the list is the source of truth. A shorter interval makes more Cursor API calls in exchange for a more current view of the queue. Cursor expires a stream position 5 minutes after the list that issued it, so a longer interval still lists again when the position expires.

--cursor-relist-jitter

PropertyValue
Typeduration
Environment$CODER_AGENT_RELAY_CURSOR_RELIST_JITTER
YAMLcursorRelistJitter
Default30s

The longest random delay that Agent Relay adds to each pool's list interval, so that pools don't list in lockstep. Set 0 to list exactly on the interval.

--cursor-api-url

PropertyValue
Typeurl
Environment$CODER_AGENT_RELAY_CURSOR_API_URL
YAMLcursorAPIURL
Defaulthttps://api.cursor.com/

The base URL of Cursor's fleet management API.

Logging

For log fields and examples, refer to Monitor Agent Relay.

--log-level

PropertyValue
Typestring
Environment$CODER_AGENT_RELAY_LOG_LEVEL
YAMLlogLevel
HelmlogLevel
Defaultinfo

The minimum log level: debug, info, warn, or error.

--log-format

PropertyValue
Typestring
Environment$CODER_AGENT_RELAY_LOG_FORMAT
YAMLlogFormat
HelmlogFormat
Defaulthuman, or json in the Helm chart

The log output format: human or json. Use json for log aggregation.

Prometheus metrics

For the metrics that Agent Relay exports, refer to Monitor Agent Relay.

--prometheus-enable

PropertyValue
Typebool
Environment$CODER_AGENT_RELAY_PROMETHEUS_ENABLE
YAMLprometheusEnable
Helmprometheus.enable
Defaultfalse, or true in the Helm chart

Serve Prometheus metrics, and the /readyz readiness endpoint, on the address in --prometheus-address. Metrics are served over plain HTTP. /readyz returns 200 once at least one pool has passed verification and 503 before that, and lists each pool that is still verifying or has failed. The Helm chart uses /readyz as the pod's readiness probe.

--prometheus-address

PropertyValue
Typehost:port
Environment$CODER_AGENT_RELAY_PROMETHEUS_ADDRESS
YAMLprometheusAddress
Helmprometheus.port
Default127.0.0.1:2112

The address that the metrics listener binds to. The default binds to loopback, which isn't reachable from outside a container. In Docker, set 0.0.0.0:2112. The Helm chart always binds to 0.0.0.0 on prometheus.port.

Workspace reaper

--reap-workers

PropertyValue
Typeint
Environment$CODER_AGENT_RELAY_REAP_WORKERS
YAMLreapWorkers
Default5

How many workspaces the reaper handles at the same time during each sweep. Workspace statuses and session attachment arrive with the workspace list, so this option limits only the delete, cancel, nack, and deadline extension calls that a sweep makes. The Helm chart has no dedicated value for this option. Set it with extraEnv.

--reap-keepalive-refresh-before

PropertyValue
Typeduration
Environment$CODER_AGENT_RELAY_REAP_KEEPALIVE_REFRESH_BEFORE
YAMLreapKeepaliveRefreshBefore
Default35m0s

Extends an attached workspace when its autostop deadline is less than this duration away and its attachment sample is fresh. Must be at least 5m. The sum of this option and --reap-keepalive-bump-by must be at least 31m. This option is shared by every pool and is independent of idle_release_timeout. The Helm chart has no dedicated value for this option. Set it with extraEnv. Refer to Keep attached workspaces running.

--reap-keepalive-bump-by

PropertyValue
Typeduration
Environment$CODER_AGENT_RELAY_REAP_KEEPALIVE_BUMP_BY
YAMLreapKeepaliveBumpBy
Default10m0s

Extra time beyond --reap-keepalive-refresh-before for the new deadline. Agent Relay measures the new deadline from now, not from the old deadline. Must be positive. The workspace TTL takes precedence when it's longer, and the build's maximum deadline still caps the new deadline. The Helm chart has no dedicated value for this option. Set it with extraEnv.

Helm values

The chart's Agent Relay options are listed with each option above. The chart also accepts these values:

ValueDefaultDescription
image.repositoryghcr.io/coder/agent-relayThe Agent Relay image.
image.tagThe chart's appVersionThe image tag. Set it to pin an image independently of the chart.
image.pullPolicyIfNotPresentThe image pull policy.
image.pullSecrets[]Secrets for pulling the image. The published image is public.
secretEnv[]Pool secrets, one entry per secret_env. Each entry has a name, secretName, and key, and becomes an environment variable read from a Kubernetes secret.
prometheus.annotationstrueAdd the prometheus.io/* pod annotations that annotation-based service discovery uses.
extraEnv[]More environment variables, added last. Use it for options without a dedicated value.
service.enablefalseCreate a Service for the metrics port. Annotation-based scraping targets pods directly and doesn't need it.
service.typeClusterIPThe Service type.
service.annotations{}Annotations for the Service.
serviceAccount.createtrueCreate a Kubernetes service account. Agent Relay doesn't call the Kubernetes API, so the chart binds it to no roles.
serviceAccount.namecoder-agent-relayThe name of the Kubernetes service account to create or use.
serviceAccount.annotations{}Annotations for the Kubernetes service account.
podAnnotations{}More pod annotations, merged over the prometheus.io/* annotations.
podLabels{}More pod labels.
resources{}Resource requests and limits.
nodeSelector, tolerations, affinity, priorityClassNameEmptyStandard pod scheduling settings.
podSecurityContextNon-root user 65532 with the RuntimeDefault seccomp profileThe pod security context.
securityContextRead-only root filesystem, no privilege escalation, and all capabilities droppedThe container security context.
terminationGracePeriodSeconds60The shutdown grace period. Agent Relay stops claiming sessions as soon as it receives a shutdown signal.

For example, to set options that have no dedicated value:

extraEnv:
  - name: CODER_AGENT_RELAY_REAP_WORKERS
    value: "10"
  - name: CODER_AGENT_RELAY_CURSOR_RELIST_INTERVAL
    value: 2m

The chart always runs one replica with the Recreate strategy. Two relays that serve the same pools both claim sessions and compete over the same workspaces.

Learn more