This guide keeps lower-level implementation and API reference material out of the README. Start with the README if you only want to run AgentRail locally.
- Node.js 24 or newer.
npm,git, andcurl.- Docker Desktop if you want to run the compose smoke path.
- Provider credentials only when testing live provider adapters.
Install dependencies:
npm install
npm linkRun checks:
npm run typecheck
npm test
npm run lint:openapiStart the local API from a configured checkout:
agentrail server startYou can also run the raw server entrypoint for development:
npm startThe package exposes the agentrail binary. In a source checkout, use
npm link or npm install -g . once if the binary is not already on your
PATH.
Product telemetry is best effort. Published AgentRail builds use AgentRail's
bundled public PostHog capture key by default, so customers do not configure a
PostHog key. AGENTRAIL_TELEMETRY_POSTHOG_KEY is a development/test override.
AGENTRAIL_TELEMETRY_DISABLED=1 forces telemetry off.
Tests should use injected telemetry sinks for assertions or the default no-op path. Do not send test events to PostHog.
Telemetry must stay limited to safe metadata such as event names, providers, lifecycle outcomes, counts, and coarse status or duration buckets. Do not send raw user content/errors, source code, issue text, PR diffs, prompts, terminal logs, environment variables, secrets, tokens, or raw provider payloads.
The repository is intentionally API-first:
src/app.tsexposes HTTP routes.src/server-runtime.tswires stores, adapters, routing, providers, and background delivery.src/task-store.tsstores task lifecycle state.src/task-event-store.tsstores and replays compact task events.src/event-subscription-store.tsandsrc/event-delivery-worker.tsmodel event subscriptions and delivery retry state.src/github-issue-intake-adapter.tsandsrc/linear-issue-source-adapter.tsingest provider issues.src/intake-routing-control-plane.tsowns routing profiles, rule sets, decisions, and audit entries.sdk/typescriptandsdk/pythonare the typed SDK surfaces agents should use instead of hand-rolled HTTP calls.
The runtime does not silently fall back to fixture tasks. Provider imports are expected to route through configured routing state or fail closed.
Provider adapters are opt-in:
GITHUB_TOKENenables GitHub-backed submit, CI, review, and issue intake paths where configured.CIRCLECI_TOKENenables CircleCI status lookup for tasks withciProvider: "circleci".CIRCLECI_WEBHOOK_SECRETverifies CircleCI webhook deliveries.LINEAR_API_KEYenables Linear issue import and outbound GraphQL mutations.LINEAR_WEBHOOK_SECRETverifies Linear webhook deliveries.
Prefer the CLI for local setup:
agentrail provider connect github
agentrail provider connect circleci
# Paste the full CircleCI project slug when prompted:
# circleci/<org-id>/<project-id>
agentrail provider connect linearThe CLI writes local provider env files and masks secret prompts.
Provider connect is the setup path. It validates the provider, runs readiness,
applies safe local fixes, and exits non-zero with classified next steps when a
repo or remote setting still needs user action. agentrail provider test <provider> uses the same readiness engine as agentrail provider doctor <provider>, so it should not disagree with doctor output.
agentrail provider connect circleci also verifies the stored project slug,
checks for .circleci/config.yml, creates a starter config for straightforward
Node repos when it is missing, discovers CircleCI pipeline definitions, and
stores the trigger strategy AgentRail will use. If automatic CircleCI branch
builds are unavailable, AgentRail can trigger the configured pipeline definition
through CircleCI's pipeline-run API instead of requiring a manual CircleCI
button click.
Readiness commands:
agentrail provider status
agentrail provider doctor github
agentrail provider doctor circleciAgentRail routing has two setup modes:
rules_only: deterministic rules route or triage work. No model is called.ai_assist: AgentRail can use AI to route tasks to the right agents. If AI routing cannot find a suitable agent, setup can require a suitable agent and retry when agents change, or assign the closest match as a best-effort decision.
AI routing uses the same local runner family as managed agents. It does not require provider API keys for LLM calls in this repo. Configure it during init:
agentrail init \
--routing-mode ai-assist \
--routing-classifier-runner codex \
--routing-classifier-model gpt-5.4-miniSupported local AI routing runner executables:
| Runner | Executable checked by doctor | Notes |
|---|---|---|
codex |
codex |
Runs the AI routing prompt through the local Codex CLI. |
claude-code |
claude |
Uses Claude Code's local CLI. |
cursor |
cursor-agent |
Requires the Cursor agent CLI, not only the GUI app. |
agentrail doctor verifies the configured executable is on PATH, but it does
not make a model call. Runtime AI routing receives bounded issue text only:
title, labels, repo, project, issue type, priority, and a truncated body
preview. Local runner classification defaults to a 180 second timeout; slow
local runners can raise routing.classifier.timeoutMs in config.json up to
600 seconds. Timeout failures leave the task for triage instead of forcing an
unsafe assignment.
- Task lifecycle OpenAPI
- Intake routing admin OpenAPI
- Intake routing architecture
- Local setup CLI contract
The CLI should be the normal onboarding path. These calls are useful when testing the API directly or debugging setup state.
Create an operator-capable key:
curl -s -X POST http://127.0.0.1:3000/agent-api-keys \
-H "content-type: application/json" \
-H "idempotency-key: bootstrap-local-admin" \
-d '{
"agent": {
"id": "agt_local_operator",
"displayName": "Local Operator",
"role": "operator"
},
"scopes": [
"auth:admin",
"routing:admin",
"routing:read",
"tasks:read",
"tasks:write",
"usage:read"
]
}'The returned data.apiKey is the secret bearer token. The akey_... value is
the key id, not the secret.
List assigned work for an agent key:
curl -s "http://127.0.0.1:3000/tasks/mine?status=in_progress&limit=1" \
-H "authorization: Bearer $AGENTRAIL_API_KEY"Submit work for review:
curl -s -X POST "http://127.0.0.1:3000/tasks/tsk_example/submit" \
-H "authorization: Bearer $AGENTRAIL_API_KEY" \
-H "content-type: application/json" \
-H "idempotency-key: submit-example-1" \
-d '{
"summary": "Implemented the assigned change.",
"mode": "adapter_managed",
"pullRequest": {
"title": "Implement assigned AgentRail task",
"draft": false
}
}'Read CI and review feedback:
curl -s "http://127.0.0.1:3000/tasks/tsk_example/ci-status" \
-H "authorization: Bearer $AGENTRAIL_API_KEY"
curl -s "http://127.0.0.1:3000/tasks/tsk_example/review-feedback" \
-H "authorization: Bearer $AGENTRAIL_API_KEY"For complete TypeScript and Python client setup, lifecycle examples, webhooks, SSE, scopes, idempotency, and troubleshooting, see the SDK guide.
TypeScript:
import { AgentRailClient } from "@agentrail-core/sdk";
const client = new AgentRailClient({
baseUrl: "http://127.0.0.1:3000",
apiKey: process.env.AGENTRAIL_API_KEY!,
});
const tasks = await client.listMyTasks({ status: "in_progress" });Python:
import os
from agentrail import AgentRailClient, TaskStatus
async with AgentRailClient(
base_url="http://127.0.0.1:3000",
api_key=os.environ["AGENTRAIL_API_KEY"],
) as client:
tasks = await client.list_my_tasks(status=TaskStatus.IN_PROGRESS)Build and run the local server image:
docker build -t agentrail .
docker run --rm -p 3000:3000 agentrailOr use compose:
docker compose up --buildDocker starts the server. Use the CLI setup path when you need local agent, routing, and provider state.
This public repo is the source-available runtime: local server, CLI, SDKs, provider adapters, OpenAPI contracts, and self-managed setup docs.
AgentRail Cloud is planned as the managed team/fleet layer, not merely a hosted copy of this Node process. Cloud should own managed connectors, shared run history, routing and wakes, SSO/RBAC/SCIM, audit, dashboards, support, backups, and hosted reliability. See Cloud boundary.