Skip to main content
Experimental version.This is the latest in-development version of AI-Implement. Features may change without notice and behavior is not guaranteed. Switch to the latest stable version here.
The AI-Implement orchestrator is configured entirely through environment variables. Variables fall into three contexts depending on where you configure them:
  • On the orchestrator service itself
  • As GitHub Actions secrets on the orchestrator’s own repo (for CI auto-deploy)
  • As GitHub Actions secrets on each target repo (read by the synced workflow files when Claude runs).
The variables are read at startup; restart the app after changing them. Pick the tab that matches where you’re configuring right now.
Variables the AI-Implement Node service reads at startup.
  • For local development, set on the orchestrator’s .env file.
  • For Fly.io deployment, set on the Fly.io app via fly secrets set (for sensitive values) or in fly.toml’s [env] block (for non-sensitive defaults).
Several variables in this tab also appear as GitHub Actions secrets in the other tabs — same value, different name. The Credentials at a glance table below maps them.

Required

The orchestrator needs the GitHub App credentials plus at least one ticketing provider’s credentials to start.
GITHUB_APP_ID
string
required
Numeric ID of the GitHub App the orchestrator uses to authenticate with GitHub and dispatch workflows. Find this on the app’s settings page under General → App ID.
GITHUB_APP_PRIVATE_KEY
string
required
RSA private key (PEM format) for the GitHub App, used to generate installation tokens. When passing this as an environment variable, newlines in the PEM file must be replaced with literal \n characters.
The private key PEM file contains real newlines. When you set it as an environment variable (e.g. with fly secrets set), those newlines must be expressed as the two-character sequence \n. Example: "-----BEGIN RSA PRIVATE KEY-----\nMIIE...\n-----END RSA PRIVATE KEY-----".

Ticketing

The orchestrator can use Linear, Jira, or both. Expand the provider(s) you use:
LINEAR_API_KEY
string
required
Required when any project mapping uses ticketingProvider: linear.Linear personal API key used to poll for issues and update status, labels, and comments. Generate one in Linear under Settings → API → Personal API keys.
The key must have access to every Linear team you intend to map. Polling filters only by the AI-Implement label, not by team, so issues in teams the key cannot see are never picked up.
LINEAR_WORKSPACE_URL
string
default:"https://linear.app"
User-facing Linear workspace URL, used to render issue links in dispatch logs and comments. Optional.
JIRA_TOKEN
string
required
Required when any project mapping uses ticketingProvider: jira.Atlassian API token (Bearer auth). Create from your Atlassian account under Security → API tokens.
JIRA_CLOUD_ID
string
required
Required when any mapping uses Jira.Jira Cloud tenant ID. Find at https://<your-site>.atlassian.net/_edge/tenant_info (the cloudId field).
JIRA_SITE_URL
string
required
Required when any mapping uses Jira.User-facing Atlassian site URL, e.g. https://acme.atlassian.net. Used to render issue links in dispatch logs and comments.
Variables beyond this section have defaults or are safely omitted. Set them to override the defaults or to enable optional features.

Service

ADMIN_ACCESS_CODE
string
Password for the admin UI at /admin. If this variable is not set, the admin UI is disabled entirely and all /admin and /api/ routes return 404.
PORT
string
default:"8080"
HTTP port the orchestrator listens on. The Fly.io internal proxy routes traffic to this port automatically, so you typically do not need to change it.
POLL_INTERVAL_MS
string
default:"60000"
How often the orchestrator polls for new AI-Implement issues, in milliseconds. Lower values increase ticketing-API usage; values below 10000 are not recommended.
DEDUP_DB_PATH
string
default:"/data/dedup.sqlite"
Absolute path to the SQLite file used for deduplication, dispatch logging, and project-mapping storage. Defaults to /data/dedup.sqlite in production (the Fly.io volume mount point) and ./dedup.sqlite when running locally. Change this only if you are mounting the volume at a different path.
GITHUB_WEBHOOK_SECRET
string
HMAC-SHA256 secret used to validate incoming GitHub webhook payloads. Configure a webhook in each target repo (or at the org level) pointing to https://<orchestrator-host>/api/github/webhook with this secret. If unset, the orchestrator’s webhook endpoint rejects all requests.

Notifications

NOTIFY_TYPE
string
default:"slack"
Notification provider to use when a dispatch succeeds or fails. Accepted values: slack (default) or teams. Has no effect if NOTIFY_WEBHOOK_URL is not also set.
NOTIFY_WEBHOOK_URL
string
Incoming webhook URL for the notification provider. Notifications are skipped silently if this variable is unset. For Slack, this is the URL from your Incoming Webhooks app configuration. For Teams, use the connector webhook URL.

Runner mode

RUNNER_MODE
string
default:"default"
Global override for runner execution mode. Accepted values:
  • default (per-mapping setting wins)
  • gha (force GitHub Actions for all mappings)
  • fly (force Fly Machines)
  • local (force local Docker — for local development)
  • shadow (dispatch via GHA and additionally boot a shadow Fly Machine for testing).
FLY_SESSIONS_APP
string
Required when RUNNER_MODE=fly or any mapping uses executionMode: fly-machines.Fly.io app name that hosts the session runners.
FLY_SESSIONS_REGION
string
default:"iad"
Default Fly.io region for new session machines.
FLY_SESSIONS_TOKEN
string
Required when RUNNER_MODE=fly or any mapping uses Fly Machines.Fly API token scoped to the sessions app. Used to create and destroy Fly Machines for runs.
SESSION_IMAGE
string
default:"ghcr.io/builddownai/ai-implement-runner:latest"
Default container image for Fly Machine sessions. Per-repo overrides via .ai-implement/image.yml take precedence.
LOCAL_RUNNER_IMAGE
string
Container image to use when RUNNER_MODE=local. Built locally via npm run build:runner:local.
LOCAL_RUNNER_ORCHESTRATOR_URL
string
Base URL the local Docker runner uses to call back to the orchestrator. Typically http://host.docker.internal:8080 on macOS/Windows or the host’s IP on Linux.
These configure how Fly Machine and local-Docker runners authenticate their callbacks to the orchestrator. Defaults are correct for most setups.
RUNNER_CALLBACK_BASE_URL
string
Public base URL the runner uses to call back to the orchestrator (e.g. https://your-orchestrator.fly.dev). Required for Fly Machines and local Docker runner modes.
RUNNER_TOKEN_SECRET
string
Secret used to mint and validate short-lived runner-callback tokens. Required when RUNNER_CALLBACK_BASE_URL is set.
GAP_FILL_TRIGGER_SECRET
string
Shared bearer secret for the /trigger/gap-fill endpoint that synced comment-trigger.yml workflows POST to when a user comments /ai-implement on a PR. If unset, the gap-fill trigger endpoint is disabled.
Controls the reconciliation sweep that cleans up stale Fly Machine sessions.
REAPER_DRY_RUN
string
default:"false"
When true, the reaper logs what it would destroy but takes no action. Useful for verifying rules before enabling live cleanup.
REAPER_ALERT_THRESHOLD
string
Number of destructions in a 24-hour window above which the reaper emits an alert notification (via the configured NOTIFY_TYPE). Helps catch runaway destruction bugs.
Identifiers used when deploying multiple AI-Implement instances as separate Fly apps from a single repo. Most single-client deployments leave these unset.
CLIENT_SLUG
string
The client identifier matching this app’s clients/<slug>.toml file. Used in logs and notifications to disambiguate multi-tenant deployments.
FLY_APP_NAME
string
Fly.io app name for this instance. Read for logging only; the actual Fly deployment binds this automatically.
These are read by the orchestrator and forwarded to runner sessions when RUNNER_MODE is fly or local.For GitHub Actions runner mode, the synced workflow uses its own repo secrets directly (see the Target-repo workflow secrets tab); these runtime values are unused.
ANTHROPIC_API_KEY
string
Anthropic API key, forwarded to the runner session as the Claude auth fallback. Required when RUNNER_MODE=fly or local and no OAuth token is configured.
CLAUDE_CODE_OAUTH_TOKEN
string
Claude Code OAuth token, forwarded to the runner session. Preferred over ANTHROPIC_API_KEY when both are set.

Credentials at a glance

The same credential often has a different name depending on where it’s used. The table below maps each logical credential to its name in each environment.
CredentialRuntime env var (orchestrator)GitHub Actions secret (CI)Lives on
GitHub App IDGITHUB_APP_IDAI_IMPLEMENT_APP_IDOrchestrator + each target repo
GitHub App private keyGITHUB_APP_PRIVATE_KEYAI_IMPLEMENT_PRIVATE_KEYOrchestrator + each target repo
Linear API keyLINEAR_API_KEYLINEAR_API_KEYOrchestrator + Linear target repos
Jira API tokenJIRA_TOKENJIRA_TOKENOrchestrator + Jira target repos
Jira Cloud IDJIRA_CLOUD_IDJIRA_CLOUD_IDOrchestrator + Jira target repos
Jira site URLJIRA_SITE_URLJIRA_SITE_URLOrchestrator + Jira target repos
Claude auth — preferredCLAUDE_CODE_OAUTH_TOKENCLAUDE_CODE_OAUTH_TOKENOrchestrator (Fly/local only) + each target repo
Claude auth — fallbackANTHROPIC_API_KEYANTHROPIC_API_KEYOrchestrator (Fly/local only) + each target repo
Fly token — spawn session machinesFLY_SESSIONS_TOKENOrchestrator only (Fly Machines runner mode)
Fly token — CI auto-deployFLY_API_TOKENOrchestrator repo only
Two pairs are especially easy to confuse:
  • The GitHub App credential is GITHUB_APP_ID / GITHUB_APP_PRIVATE_KEY at runtime but AI_IMPLEMENT_APP_ID / AI_IMPLEMENT_PRIVATE_KEY as CI secrets — both refer to the same app with different variable names.
  • FLY_SESSIONS_TOKEN (orchestrator runtime, authorizes spawning Fly session machines) is not the same token as FLY_API_TOKEN (orchestrator-repo CI, authorizes flyctl deploy).