Cloudflare Worker
For a site whose DNS is on Cloudflare, the Inception Agents relay (a small Worker, version 1.0.0) puts your agent surface on your own domain:
- Agent paths go to Inception Agents, signed with this install’s relay key:
/mcp,/.well-known/mcp.json,/agent,/agent/*,/llms.txt,/llms-full.txt,/.well-known/agent.jsonand/.well-known/agent-capabilities.json. The signature tells us the visitor’s address, Origin and User-Agent, so each visitor is counted and rate-limited as themselves rather than as your Worker. The commerce protocol paths (/.well-known/acp/*,/.well-known/ucp) and/.well-known/oauth-authorization-serverare not relayed; they go to your site. /.well-known/inception-verifyis answered by the Worker itself. That answer is how Inception Agents confirms the install is yours.- Everything else goes to your site untouched. HTML pages get the Inception Agents page script once, just before
</body>, which registers your Agent Actions for an agent on the page in browsers that support them. It is skipped when the page already has it.
If Inception Agents does not answer within 8 seconds, agent paths get a 502 and your pages are unaffected: they never depend on us. Responses on agent paths are never cached. The Worker sends us no cookies, no page content and no Authorization header.
This is not Cloudflare’s own switch (AI → Agent Readiness → WebMCP). Leave that off: it re-serves your site’s /mcp with the tool annotations stripped, and it makes our page script stand down, so the confirmation card never appears (see Agent Actions).
What you need
- Your domain’s zone in a Cloudflare account you control. A host or site builder that runs its own Cloudflare in front of your site does not count.
- An account-owned API token (Manage Account → Account API Tokens) with Workers Admin at the Workers product scope, and Workers Routes Write and Zone Read for this zone only. Creating the relay Worker needs Workers Admin: Workers Editor can deploy a Worker but not create one. Workers Admin covers this account’s Workers and nothing in Pages, R2, KV or D1. Never use the account’s global API key.
- Your account ID (not a secret: your zone’s Overview page shows it).
- Node.js for
npx wrangler, andjqfor the connect command. - The relay template zip. The install plan (below) gives the download link and the SHA-256 to check it against; the zip holds
README.md,src/index.tsandwrangler.toml.example.
Going live, step by step
Going live is a checklist, and each step counts as done only when a check proves it, never because a setting was saved. It runs from Claude or your coding agent through the Inception Agents connector: ask it to take your site live and it follows the /inception-go-live playbook, reading the go-live state (get_go_live_state) before and after every step. The same steps work for your developer or your agency. Credentials stay out of sight throughout: the token goes into your environment, the install code into curl on standard input, and the relay secret straight into the Worker’s secrets. Nothing prints them.
1. Your website and the install plan
Add the host your visitors use, exactly (add_domain): www.example.com and example.com are different hosts, and a relay serves exactly one. get_install_plan looks at your homepage from outside and recommends the Cloudflare Worker (or the WordPress plugin), with the reasons, any warnings, the download and the exact steps. Download the template, check its SHA-256 against the plan, and unzip it.
2. Set up the Worker, with one route
Copy wrangler.toml.example to wrangler.toml and fill it in:
| Setting | Kind | Value |
|---|---|---|
IA_HOST | var | Your host, exactly as your visitors use it |
IA_EDGE_BASE | var | https://inception-agents-edge.inception-agents.workers.dev |
IA_API_BASE | var | https://inception-agents-api.inception-agents.workers.dev |
IA_TENANT_ID | var | Your Inception Agents tenant ID (the connect answer in step 3 shows it too) |
IA_RELAY_KEY_ID | secret | Set in step 3, straight from the connect answer |
IA_RELAY_SECRET | secret | Set in step 3, straight from the connect answer |
Route only the install proof for now: example.com/.well-known/inception-verify. Until the install is proven, Inception Agents does not serve your host through the Worker, so its agent paths would answer 404. You add the other routes in step 6.
read -rs CLOUDFLARE_API_TOKEN && export CLOUDFLARE_API_TOKEN # paste the scoped token, then Enter
export CLOUDFLARE_ACCOUNT_ID=… # your account ID (not a secret)
npx wrangler deploy # the Worker, with only the inception-verify route
3. Connect, once: the key goes straight into the Worker
create_install_code makes a code for your host and the Cloudflare Worker path. It starts with iac_, works once and expires after 60 minutes, so exchange it right away, from the Worker’s folder. The code goes to curl on standard input, never on its command line; the answer stays in a shell variable, and its key and secret go straight into the Worker’s secrets:
ANSWER=$(curl -sS -H 'content-type: application/json' --data-binary @- \
https://inception-agents-api.inception-agents.workers.dev/api/v1/relay/connect <<'EOF'
{"code":"iac_…","host":"example.com","artifact":{"kind":"cloudflare_worker","version":"1.0.0"}}
EOF
)
if printf '%s' "$ANSWER" | jq -e '(.keyId | type) == "string" and (.secret | type) == "string"' > /dev/null; then
printf '%s' "$ANSWER" | jq '{IA_RELAY_KEY_ID: .keyId, IA_RELAY_SECRET: .secret}' | npx wrangler secret bulk
printf '%s' "$ANSWER" | jq '{host, tenantId}'
else
printf '%s' "$ANSWER" | jq -r '"Not connected: \(.code // "no answer") \(.error // "")"'
fi
unset ANSWER
Any mistake (a wrong host, a used or expired code) gets the same 400 install_code_invalid: ask for a new code.
4. Let agents through
Cloudflare’s bot protection runs before Workers. If it challenges AI agents, they never reach /mcp, and a challenged install proof fails, so do this before step 5.
-
Pro and above: add a WAF custom rule with the Skip action (skip Super Bot Fight Mode and the managed rules) for exactly the relayed paths, so nothing else on your site loses its protection:
http.host eq "example.com" and ( http.request.uri.path in {"/mcp" "/agent" "/llms.txt" "/llms-full.txt" "/.well-known/mcp.json" "/.well-known/agent.json" "/.well-known/agent-capabilities.json" "/.well-known/inception-verify"} or starts_with(http.request.uri.path, "/agent/") ) -
Free: Bot Fight Mode cannot be skipped by a rule. If it is on, agents may be challenged: turn it off, or accept that some agents are blocked.
-
Block AI bots also acts before the Worker: if it is on, check that it does not block the assistants you want to reach you.
5. Prove the install
verify_install fetches https://example.com/.well-known/inception-verify?c=<challenge> with a fresh challenge every time, and the Worker answers v1.<keyId>.<HMAC>. A pass proves the site is yours and turns on /mcp for it. You can check the Worker yourself first:
curl -s "https://example.com/.well-known/inception-verify?c=$(head -c 32 /dev/urandom | base64 | tr '+/' '-_' | tr -d '=')"
It answers only for IA_HOST (another host gets a 404) and only for a 43-character challenge (anything else gets a 400).
6. Add the routes
Once the proof has passed, route the agent paths and your pages to the Worker, then npx wrangler deploy again. Cover only your one host, and leave static assets off: they never need the Worker, and Workers Free counts every request it runs on (100,000 a day).
- Agent paths:
example.com/mcp,example.com/agent*,example.com/llms*,example.com/.well-known/mcp.jsonandexample.com/.well-known/agent*(the inception-verify route stays). - Pages:
example.com/plus one pattern per section you want the page script on (example.com/services*, …). Avoidexample.com/*unless the site is small.
A request the Worker does not serve (another host, a path it does not relay) goes to your origin unchanged.
7. Tools, leads, and a test lead
The rest is the same as on WordPress:
- Approve the tools.
preview_agent_toolsshows exactly which tools a visiting agent will be offered, each marked as a lookup or an action; approve them withapprove_agent_tools. Answers you publish later need no new approval; any other change to the tools does. - Choose who gets leads.
set_lead_recipientswith the people at your business, thensend_test_notificationso you know the email arrives. - Reachable from outside.
check_reachabilitychecks your site the way an agent sees it: the page script,/.well-known/mcp.json,/mcpand its tool list with a standard MCP client, the briefing, and the relay’s headers. It passes when/mcpserves exactly the tools you approved. - A test lead reaches a person.
run_live_testacts as a buyer’s agent on your live site: it asks a few questions, then requests a callback. Everyone on your lead list gets an email marked TEST that shows what the agent asked first, with a link to replay the conversation. One of them opens it and clicks I received this test lead. It is never billed. - Live.
complete_go_livechecks everything again and marks the site live. From then on the site is checked every hour, and the people who receive leads get an email if agents stop being able to reach it (for example, if the Worker’s routes change).
Check it yourself
# Agents are pointed at /mcp
curl -s https://example.com/.well-known/mcp.json
# The tools an agent calling from its own servers is offered
curl -s -X POST https://example.com/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# The page script is on your pages, once
curl -sL https://example.com/ | grep -c 'beacon.js'
What the Worker sends to Inception Agents
To the edge, on agent paths only: the method, path and body byte for byte, with ?store={IA_HOST} (a visitor’s own store parameter is dropped); the visitor’s User-Agent (so an agent is classed as an agent), Accept, Content-Type, Mcp-Session-Id, MCP-Protocol-Version, Last-Event-ID, x-ia-probe, x-ia-exchange-id and openai-conversation-id; the x-ia-relay-* signature headers; and x-ia-relay-artifact: cloudflare_worker/1.0.0. Nothing else from the visitor: no cookies, no Authorization, and never a visitor’s own x-ia-relay-*, x-inception-*, X-Forwarded-Host or x-ia-internal-probe.
Back to the visitor: the status and headers as Inception Agents sent them (a 405 keeps its Allow), without Set-Cookie, with Cache-Control: no-store. Redirects are passed back, never followed. Origin requests carry X-IA-Origin-Fetch: 1, so an Inception Agents plugin on the origin does not add its own markup a second time.
What agents ask and what your site answers are recorded in your workspace as agent conversations, with contact details masked.
Updating
Replace src/index.ts with the new release and deploy again. Nothing needs reconnecting: the relay key stays the same. Every relayed request names the release in x-ia-relay-artifact.
Removing the relay
-
Revoke the key. The relay key revokes itself: sign
IA-DISCONNECT-V1, the key id, a Unix timestamp, a random nonce and your host, one per line, with the secret, and send the four headers. No body. The secret never goes on a command line:read -stakes it without echo, and Node reads it from the environment.KEY_ID=rk_… HOST=example.com read -rs IA_RELAY_SECRET && export IA_RELAY_SECRET # paste rks_…, then Enter TS=$(date +%s); NONCE=$(openssl rand -hex 16) SIG=$(printf 'IA-DISCONNECT-V1\n%s\n%s\n%s\n%s' "$KEY_ID" "$TS" "$NONCE" "$HOST" \ | node -e 'process.stdout.write(require("crypto").createHmac("sha256", process.env.IA_RELAY_SECRET).update(require("fs").readFileSync(0)).digest("hex"))') unset IA_RELAY_SECRET curl -sS -X POST https://inception-agents-api.inception-agents.workers.dev/api/v1/relay/disconnect \ -H "x-ia-relay-key: $KEY_ID" -H "x-ia-relay-ts: $TS" -H "x-ia-relay-nonce: $NONCE" -H "x-ia-relay-sig: $SIG"The answer is
{"revoked": true}. A wrong signature, another host (www is not the apex), or a timestamp more than 5 minutes off gets401 {"code": "relay_auth_invalid"}. From then on Inception Agents ignores anything signed with that key. -
Remove the Worker: delete its routes and the script (
npx wrangler delete). Your site is served exactly as before the install. -
Remove access you granted for the install, such as the scoped API token.