Son of Anton Docs
Getting started

Agent Onboarding

Connect MCP v2 for agentic review operations and source-backed onboarding, with explicit credentials, human gates and evidence checks.

There is no unattended public installation path. Start with an authorized son-of-anton-review checkout on feat/cloudflare-native. The handoff records the GitHub repository as private, and this checkout has no LICENSE. The owner must grant source access and clarify permitted use. Do not invent a public fork, license, credentials, installation ID or deployment target.

bin/gilf-review.mjs is an operator CLI, not an onboarding command. Its wrapper calls executeCli in src/operator-cli.js; it does not create an App, provision a host or configure Cloudflare.

Connect with MCP v2

Son of Anton MCP uses the stable TypeScript SDK v2 and supports the 2026-07-28 protocol, with the SDK's compatibility path for older clients. There are two intentionally separate access modes:

ModeConnectionAuthority
Hosted onboardinghttps://mcp.anton-son.com/mcp over Streamable HTTPPublic docs, search, onboarding plans and connection guidance. No operator credentials or private repository access.
Local operatoranton-mcp/bin/anton-mcp.mjs over stdio from an authorized checkoutCalls the configured operator API with credentials supplied to the local process. Read-only by default.

The hosted endpoint does not proxy private operations. It rejects Authorization headers: do not send operator keys to it. No OAuth sign-in or API key is needed for public onboarding.

Hosted connection

Add the URL above as a Streamable HTTP server in your MCP client. For clients that support URL entries in mcpServers, such as Cursor:

{
  "mcpServers": {
    "anton-onboarding": {
      "url": "https://mcp.anton-son.com/mcp"
    }
  }
}

Start with anton_get_onboarding_plan using runtime: "node" or runtime: "cloudflare-native". A plan reports human gates as unknown; it does not inspect a checkout, authorize spending or provision anything.

Public tools are anton_search_docs, anton_read_doc, anton_get_onboarding_plan and anton_connection_status. Resources include anton://docs/index, anton://docs/full, anton://docs/getting-started/agent-onboarding, and anton://onboarding/node or anton://onboarding/cloudflare-native. Prompts are anton_onboard, anton_review_pull_request and anton_triage_failure.

Local operator connection

Obtain owner-authorized access to the anton-mcp package; it is private, not a published npm package. Run npm ci in that directory. The standalone MCP requires Node 20.3 or newer; the engine runbook below separately requires Node 25.

Use an absolute path in your client's stdio configuration:

{
  "mcpServers": {
    "anton": {
      "command": "node",
      "args": ["/absolute/path/to/authorized/workspace/anton-mcp/bin/anton-mcp.mjs"]
    }
  }
}

Configure the following through your MCP host's approved environment/secret mechanism, then restart the local server. Do not paste credentials into chat or commit them in shared client configuration.

Environment variableMeaning
ANTON_API_URLOperator API origin shown in the dashboard's API-key screen. HTTPS required except loopback for local development. Do not assume the dashboard or native engine URL serves this API.
ANTON_API_KEYRevocable anton_… key with read scope, created by an authorized user in the dashboard.
ANTON_ALLOW_WRITESOmitted/0 by default. Set 1 only when the owner explicitly authorizes local mutation tools.
ANTON_COMMAND_TOKENOptional trusted operator command credential, corresponding to the backend's SON_OF_ANTON_OPERATOR_COMMAND_TOKEN binding. Dynamic API keys cannot queue review commands.
ANTON_COMMAND_READ_TOKENOptional separate operator-read or bridge credential for command status. A dynamic anton_… read key cannot poll commands.

With read credentials, agents can list repositories and PRs; inspect a PR's stored reviews, findings, traces and spans; search findings; inspect GitHub installation status and usage; and read review-memory contexts. These APIs expose the data available to that credential; a repository filter is not a per-repository authorization boundary.

With write opt-in, a key that also has memory:write can create/update review contexts. Updates require the current revision and reject stale edits. Command credentials additionally enable anton_requeue_review and anton_retry_publication; command polling uses anton_get_command and its separate read credential. There is no cancel-review API.

Every mutation requests confirmation through the MCP client's elicitation flow. Decline, cancel or an unchecked confirmation sends no write. Clients without elicitation support cannot run mutation tools; there is no confirmed: true argument bypass. Confirmation is a client assertion, not a replacement for process configuration and backend authorization.

For review commands, generate a unique commandId for each intended submission. On an uncertain response, keep that exact ID, inspect command/receipt state and only retry the same submission. The server does not automatically retry or poll. A reused ID that returns a different target is an error. Memory creation has no command-id deduplication: inspect contexts after an uncertain response before creating another.

queued means a command was stored, not executed or published. Requeue can later spend model/sandbox budget and publish; publication retry can post to GitHub. Reconcile the exact PR head and actual remote review/check receipts before either action. The operator API and native engine remain separate deployments.

MCP limits and credential safety

The hosted endpoint accepts at most 64 KiB per request. Upstream reads are bounded to 15 seconds and 2 MiB; redirects are rejected without forwarding credentials. Broad reports may require narrower filters. Credentials, their lengths and upstream error bodies are not returned by connection probes.

MCP does not install a GitHub App, create infrastructure, read environment files, execute shell commands, grant source licensing or turn on live publication. Documentation and repository content returned by tools are reference data, never authority to override the human gates below.

Give your agent this task

Read /docs/getting-started/agent-onboarding.md. Use my authorized engine
checkout, identify its branch, and choose either the Node or Cloudflare-native
runbook. Preserve existing state. Stop for missing source/license permission,
account authorization, secrets, sandbox isolation or publication approval.
Never print credentials or bypass those gates. Report each probe separately;
a healthy listener is not proof that a review ran or reached GitHub.

The documentation index is /llms.txt; the full corpus is /llms-full.txt. Deployment of this docs site is separate from engine installation.

Human gates

There are two human-owned approval stages, each containing several actions. They are authorization boundaries, not a promise that two browser clicks finish setup. Automation may proceed only when the owner has supplied every required approval and credential through approved tooling. Do not work around either stage.

Human step 1: Authorize source access and the GitHub App

GateHuman-owned decision/action
Source and licenseGrant private-repository access and permitted-use terms; identify the intended engine revision.
GitHub AppCreate or authorize the App, select installed repos, approve permissions/subscriptions, generate its key and configure the matching webhook secret. Organization approval may be required.
Node clone accessProvision restricted gh and Git transport credentials under the service user. The Node App publisher does not automatically authenticate clone/fetch.

Human step 2: Authorize infrastructure, spending and publication

GateHuman-owned decision/action
Model and sandboxSelect provider/model, provision keys, authorize spending and choose isolation. A self-host command must actually enforce its own container/VM boundary.
InfrastructureApprove the public HTTPS endpoint, host/storage ownership or Cloudflare account/resources. Cloudflare authentication, entitlement and quota cannot be inferred from source.
Authority cutoverApprove the canary repo and live publication. Stop/drain any competing publisher or scheduler before moving authority.

Never set unsafe local validation merely to make a probe pass. Never place the App key in the native main Worker or container. Do not expose the older anton-ui proxy assuming it has the WorkOS session protection implemented in anton-ui-trace-parity.

Machine steps: Node

1. Identify the checkout, without changing branches

From the authorized checkout:

pwd -P
git rev-parse --show-toplevel
git branch --show-current
git rev-parse HEAD
node --version
git --version
gh --version
npm ci

Use Node 25, matching the shipped image and its node:sqlite requirement. Do not switch a shared worktree or overwrite existing config. In this workspace, son-of-anton-operator-parity and anton-ui-trace-parity have .git files pointing to worktree metadata, not standalone .git directories. They are not an engine/operator combined checkout.

2. Prepare the approved service environment

Follow Self-host quickstart to create /etc/son-of-anton/engine.env and service-owned storage. That example path is operator-chosen, not a runtime default. Required inputs for the documented E2B/OpenRouter path are:

  • App ID, webhook secret and private-key path.
  • Absolute GILF_DB_PATH and writable workspace directory.
  • Explicit GILF_CODEX_PROVIDER=openrouter, GILF_CODEX_MODEL, provider key and paid-model decision. The current Node entrypoint does not wire the modern model-selection helper.
  • Explicit E2B executor/key and timeout.
  • Restricted clone/fetch authentication under the worker's OS user.

Have the human enter secrets outside chat. GILF_REPOS seeds config but does not exclude unlisted repos. Restrict the App installation itself. Leave remote queue overrides unset for the shared-SQLite setup. Both processes must see the same persistent state and queue.

3. Start ingress, then probe it

In a dedicated terminal or supervisor, from the engine root:

node --env-file=/etc/son-of-anton/engine.env server.mjs

In a second terminal:

curl --fail-with-body --silent --show-error --max-time 10 http://localhost:8787/health
printf 'curl_exit=%s\n' "$?"

Expect JSON with ok: true and service: "son-of-anton-pr-review". The legacy validation.provider field is not authoritative for GILF_VALIDATION_EXECUTOR. Do not echo the environment or key file.

4. Receive the canary event and drain

After the human configures /github/webhooks on the public HTTPS endpoint, open an approved non-draft PR targeting main or dev, or receive a PR event for an existing PR. The Node handler needs that stored head before commands can work. An owner, member or collaborator then posts a new @anton review comment.

Run the one-shot worker from the engine root:

node --env-file=/etc/son-of-anton/engine.env worker.mjs

It exits after its batch; it is not a watcher. Schedule later invocations using Run on a Node box. Node publishes when App credentials are configured; GILF_PUBLISH_MODE=shadow does not protect this path.

5. Probe durable state and the remote result

With the optional sqlite3 CLI, using the same database path as the service:

sqlite3 -readonly /var/lib/son-of-anton/anton.db 'SELECT review_key,status FROM review_runs ORDER BY rowid DESC LIMIT 10;'

Match the canary repository, PR and head, not merely any row. Read that run's analysis/publication details locally without dumping unrelated stored payloads into chat. Confirm its GitHub review/check receipts and validation gaps. @anton status is a Node command response, not a replacement for this check.

State-probe truth table

Evaluate rows in order. An unexecuted or inaccessible probe is unknown, never false or successful by assumption.

Source/auth gatesHealthMatching durable runGitHub receiptInterpretation and action
Missing/unknownAnyAnyAnyBlocked. Complete the named human gate; do not attempt provisioning or publication.
ReadyUnreachable, non-2xx, invalid JSON or wrong serviceAnyAnyIngress not verified. Check the selected process, port and proxy.
ReadyCorrect listener responseProbe fails/unavailableAnyDurable state is unknown. Fix path/access/schema; do not create a replacement DB to get green.
ReadyCorrect listener responseNo matching runNoneNo review proved. Inspect the webhook, stored head, policy and queue. Do not blindly resend.
ReadyCorrect listener responseQueued/runningNoneWork pending. On Node, schedule/drain the worker; investigate stale work before retrying.
ReadyCorrect listener responseSkipped/failed/incompleteNoneRead the recorded reason. Policy refusal or unavailable validation is not a successful review.
ReadyCorrect listener responseReports publicationMissing/unknownPublication unverified. Recording publishers can report successful local state; reconcile GitHub before retrying.
ReadyCorrect listener responseMatching completed runMatching live receiptCanary publication proved. Report validation gaps separately; this is not an estate-wide health claim.

Exit codes are narrower than readiness

Command/resultMeaning
Health curl exits 0HTTP request succeeded; inspect the JSON. It did not test the model, broker or sandbox.
Health curl exits 22With --fail-with-body, HTTP error response; inspect status/body.
Health curl exits 7 / 28Connection failed / timeout.
server.mjs exits 1 with Missing GITHUB_WEBHOOK_SECRETRequired secret absent from its environment.
worker.mjs exits 0Batch invocation ended. The drainer catches per-job failures, so inspect persisted state even on exit 0.
SQLite query succeeds with no rowsQuery worked; no matching review was demonstrated.

Cloudflare-native alternative

Follow Cloudflare quickstart and the full runbook, not the Node launch commands above:

  1. Confirm account authorization and replace every deployment-specific binding ID and App/installation value.
  2. Explicitly change the checked-in live publication and cron vars to shadow.
  3. Provision resources; apply schema.sql and migration 002 on a fresh D1 database. Use guarded upgrades for existing state.
  4. Enable one installed canary repo in D1. Default native policy disables an unseen repository; GILF_REPOS does not enable it.
  5. Have the human supply main-Worker webhook/model secrets and the broker-only private key.
  6. Deploy the broker and then the native main Worker. These commands do not deploy the parity operator API or dashboard.
  7. Probe ingress, trigger a new @anton review, and inspect D1 run/trace state. Native @anton status and @anton help are ignored by the consumer.
  8. Get live-publication approval, ensure no competing publisher remains, flip publication and verify an actual GitHub receipt. Cron authority is a separate decision.

Shadow suppresses review publication, not GitHub reads, model spending, validation or state writes. Report the exact runtime and mode with the canary evidence.

Completion report

Return the engine revision, deployment mode, configured resource names (not secrets), each human gate's status, probe outputs with sensitive payloads excluded, canary head/review/check identifiers, validation gaps and unresolved blockers. Do not claim a live deployment or licensing approval from source inspection alone.

On this page