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:
- A command-line flag, such as
--log-level. - An environment variable, such as
CODER_AGENT_RELAY_LOG_LEVEL. - A key in the YAML file that
--configpoints to, such aslogLevel.
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_TOKENenvironment variable. Do not put it in the configuration file. - Set each pool's
secret_envto 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
| Property | Value |
|---|---|
| Type | url |
| Environment | $CODER_AGENT_RELAY_CODERD_URL |
| YAML | coderdURL |
| Helm | coderd.url |
The access URL of the Coder deployment that Agent Relay serves. This flag is required.
--coderd-session-token
| Property | Value |
|---|---|
| Type | string |
| Environment | $CODER_AGENT_RELAY_CODERD_SESSION_TOKEN |
| YAML | coderSessionToken |
| Helm | coderd.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
| Property | Value |
|---|---|
| Type | path |
| 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
| Property | Value |
|---|---|
| Type | list of pools |
| Environment | $CODER_AGENT_RELAY_CLAUDE_CODE_RUNNER_POOLS |
| YAML | claudeCodeRunnerPools |
| Helm | pools.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
| Property | Value |
|---|---|
| Type | list of pools |
| Environment | $CODER_AGENT_RELAY_CURSOR_WORKER_POOLS |
| YAML | cursorWorkerPools |
| Helm | pools.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
| Field | Required | Description |
|---|---|---|
name | Yes | A unique label for the pool in Agent Relay logs and metrics. It has no meaning to the provider. |
secret_env | Yes | The 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. |
organization | Yes | The 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. |
template | Yes | The name or UUID of the template that the pool's workspaces build from. Each pool uses one template. |
template_parameters | No | Fixed 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_timeout | No | How 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_version | No | A 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
| Field | Required | Description |
|---|---|---|
claude_tag_channel_user | No | The 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
| Field | Required | Description |
|---|---|---|
cursor_pool_name | Yes | The 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_deadline | No | The 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_deadlineis 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
updateon 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.
| Provider | Reserved names |
|---|---|
| Claude Code | agent_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 |
| Cursor | agent_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
| Property | Value |
|---|---|
| Type | duration |
| Environment | $CODER_AGENT_RELAY_CURSOR_RELIST_INTERVAL |
| YAML | cursorRelistInterval |
| Default | 5m0s |
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
| Property | Value |
|---|---|
| Type | duration |
| Environment | $CODER_AGENT_RELAY_CURSOR_RELIST_JITTER |
| YAML | cursorRelistJitter |
| Default | 30s |
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
| Property | Value |
|---|---|
| Type | url |
| Environment | $CODER_AGENT_RELAY_CURSOR_API_URL |
| YAML | cursorAPIURL |
| Default | https://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
| Property | Value |
|---|---|
| Type | string |
| Environment | $CODER_AGENT_RELAY_LOG_LEVEL |
| YAML | logLevel |
| Helm | logLevel |
| Default | info |
The minimum log level: debug, info, warn, or error.
--log-format
| Property | Value |
|---|---|
| Type | string |
| Environment | $CODER_AGENT_RELAY_LOG_FORMAT |
| YAML | logFormat |
| Helm | logFormat |
| Default | human, 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
| Property | Value |
|---|---|
| Type | bool |
| Environment | $CODER_AGENT_RELAY_PROMETHEUS_ENABLE |
| YAML | prometheusEnable |
| Helm | prometheus.enable |
| Default | false, 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
| Property | Value |
|---|---|
| Type | host:port |
| Environment | $CODER_AGENT_RELAY_PROMETHEUS_ADDRESS |
| YAML | prometheusAddress |
| Helm | prometheus.port |
| Default | 127.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
| Property | Value |
|---|---|
| Type | int |
| Environment | $CODER_AGENT_RELAY_REAP_WORKERS |
| YAML | reapWorkers |
| Default | 5 |
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
| Property | Value |
|---|---|
| Type | duration |
| Environment | $CODER_AGENT_RELAY_REAP_KEEPALIVE_REFRESH_BEFORE |
| YAML | reapKeepaliveRefreshBefore |
| Default | 35m0s |
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
| Property | Value |
|---|---|
| Type | duration |
| Environment | $CODER_AGENT_RELAY_REAP_KEEPALIVE_BUMP_BY |
| YAML | reapKeepaliveBumpBy |
| Default | 10m0s |
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:
| Value | Default | Description |
|---|---|---|
image.repository | ghcr.io/coder/agent-relay | The Agent Relay image. |
image.tag | The chart's appVersion | The image tag. Set it to pin an image independently of the chart. |
image.pullPolicy | IfNotPresent | The 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.annotations | true | Add 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.enable | false | Create a Service for the metrics port. Annotation-based scraping targets pods directly and doesn't need it. |
service.type | ClusterIP | The Service type. |
service.annotations | {} | Annotations for the Service. |
serviceAccount.create | true | Create a Kubernetes service account. Agent Relay doesn't call the Kubernetes API, so the chart binds it to no roles. |
serviceAccount.name | coder-agent-relay | The 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, priorityClassName | Empty | Standard pod scheduling settings. |
podSecurityContext | Non-root user 65532 with the RuntimeDefault seccomp profile | The pod security context. |
securityContext | Read-only root filesystem, no privilege escalation, and all capabilities dropped | The container security context. |
terminationGracePeriodSeconds | 60 | The 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: 2mThe 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.