{ "$schema": "node_modules/wrangler/config-schema.json", "name": "executor-cloudflare", "compatibility_date": "2025-04-01", "compatibility_flags": ["nodejs_compat"], "main": "src/worker.ts", // Access configuration is set per installation after the first deploy. // Preserve those live bindings when this source config does not declare them. "keep_vars": true, "observability": { "enabled": true }, // The web UI (Workers Static Assets) — the shared multiplayer SPA built by // `vite build` into ./dist. `single-page-application` serves index.html for // client routes (e.g. /policies); `run_worker_first` forces the API, MCP, and // app-level routes (e.g. /v1/app/npm/dist-tags, the update check) to the // Worker instead of the SPA fallback. "assets": { "directory": "./dist", // The MCP session DO reads the built MCP-Apps shell document through this // binding (`ui://executor/shell.html` has no filesystem to come from on a // deployed Worker). "binding": "ASSETS", "not_found_handling": "single-page-application", "run_worker_first": ["/api/*", "/mcp", "/mcp/*", "/.well-known/*", "/v1", "/v1/*"], }, // D1 is the app's SQLite store (the DbProvider seam). `wrangler deploy` // auto-provisions it on first deploy; replace database_id after that, or run // `wrangler d1 create executor` and paste the id here. "d1_databases": [ { "binding": "DB", "database_name": "executor", "database_id": "ae748ca1-032c-4427-a1a0-fe39db77d1a9", }, ], // Plugin blob seam backend: multi-MB values (resolved OpenAPI specs, // introspection snapshots) live here, not in D1 (which caps a value at // ~1-2MB). `wrangler r2 bucket create executor-blobs` provisions it. "r2_buckets": [ { "binding": "BLOBS", "bucket_name": "executor-blobs", }, ], // Dynamic Worker Loader binding: when present, sandboxed code runs in real // workerd isolates with `globalOutbound: null` (platform-enforced zero egress) // via @executor-js/runtime-dynamic-worker; without it the host falls back to // the QuickJS-wasm substrate. Remove this block to stay on QuickJS. "worker_loaders": [ { "binding": "LOADER", }, ], // The MCP session Durable Object: one addressable isolate per MCP session (the // DO id IS the session id) so a session survives across the Worker's stateless // isolates — without it, `tools/list` after `initialize` can land on a fresh // isolate that never saw the session ("Not connected"). `new_sqlite_classes` // is the free-tier-eligible SQLite-backed DO storage. "durable_objects": { "bindings": [ { "name": "MCP_SESSION", "class_name": "McpSessionDO" }, { "name": "MCP_EXECUTION_OWNER", "class_name": "McpExecutionOwnerDirectoryDO" }, ], }, "migrations": [ { "tag": "v1", "new_sqlite_classes": ["McpSessionDO"] }, { "tag": "v2", "new_sqlite_classes": ["McpExecutionOwnerDirectoryDO"] }, ], // Cloudflare Access is the entire auth layer. ACCESS_TEAM_DOMAIN, ACCESS_AUD, // and ADMIN_EMAILS are installation-specific live vars, set after the first // deploy and preserved by keep_vars. EXECUTOR_SECRET_KEY (the at-rest // secret-encryption key) is a SECRET, set it with // `wrangler secret put EXECUTOR_SECRET_KEY`, never in vars. "vars": { "ACCESS_NAME_CLAIM": "name", "ACCESS_GROUPS_CLAIM": "groups", // Never preserve a production dev-auth override through keep_vars. "ENABLE_DEV_AUTH": "false", "SELF_HOSTED_ORG_ID": "default", "SELF_HOSTED_ORG_NAME": "Default", // VITE_PUBLIC_SITE_URL is intentionally unset: with no static URL the worker // derives the web base URL from each request's origin (RequestWebOrigin), so // secret/OAuth handoff links match whatever host the user actually reached. // Set it only to force a canonical URL (e.g. behind a proxy that rewrites Host). },}
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "executor-cloudflare",
"compatibility_date": "2025-04-01",
"compatibility_flags": ["nodejs_compat"],
"main": "src/worker.ts",
// Access configuration is set per installation after the first deploy.
// Preserve those live bindings when this source config does not declare them.
"keep_vars": true,
"observability": { "enabled": true },
// The web UI (Workers Static Assets) — the shared multiplayer SPA built by
// `vite build` into ./dist. `single-page-application` serves index.html for
// client routes (e.g. /policies); `run_worker_first` forces the API, MCP, and
// app-level routes (e.g. /v1/app/npm/dist-tags, the update check) to the
// Worker instead of the SPA fallback.
"assets": {
"directory": "./dist",
// The MCP session DO reads the built MCP-Apps shell document through this
// binding (`ui://executor/shell.html` has no filesystem to come from on a
// deployed Worker).
"binding": "ASSETS",
"not_found_handling": "single-page-application",
"run_worker_first": ["/api/*", "/mcp", "/mcp/*", "/.well-known/*", "/v1", "/v1/*"],
},
// D1 is the app's SQLite store (the DbProvider seam). `wrangler deploy`
// auto-provisions it on first deploy; replace database_id after that, or run
// `wrangler d1 create executor` and paste the id here.
"d1_databases": [
{
"binding": "DB",
"database_name": "executor",
"database_id": "ae748ca1-032c-4427-a1a0-fe39db77d1a9",
},
],
// Plugin blob seam backend: multi-MB values (resolved OpenAPI specs,
// introspection snapshots) live here, not in D1 (which caps a value at
// ~1-2MB). `wrangler r2 bucket create executor-blobs` provisions it.
"r2_buckets": [
{
"binding": "BLOBS",
"bucket_name": "executor-blobs",
},
],
// Dynamic Worker Loader binding: when present, sandboxed code runs in real
// workerd isolates with `globalOutbound: null` (platform-enforced zero egress)
// via @executor-js/runtime-dynamic-worker; without it the host falls back to
// the QuickJS-wasm substrate. Remove this block to stay on QuickJS.
"worker_loaders": [
{
"binding": "LOADER",
},
],
// The MCP session Durable Object: one addressable isolate per MCP session (the
// DO id IS the session id) so a session survives across the Worker's stateless
// isolates — without it, `tools/list` after `initialize` can land on a fresh
// isolate that never saw the session ("Not connected"). `new_sqlite_classes`
// is the free-tier-eligible SQLite-backed DO storage.
"durable_objects": {
"bindings": [
{ "name": "MCP_SESSION", "class_name": "McpSessionDO" },
{ "name": "MCP_EXECUTION_OWNER", "class_name": "McpExecutionOwnerDirectoryDO" },
],
},
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["McpSessionDO"] },
{ "tag": "v2", "new_sqlite_classes": ["McpExecutionOwnerDirectoryDO"] },
],
// Cloudflare Access is the entire auth layer. ACCESS_TEAM_DOMAIN, ACCESS_AUD,
// and ADMIN_EMAILS are installation-specific live vars, set after the first
// deploy and preserved by keep_vars. EXECUTOR_SECRET_KEY (the at-rest
// secret-encryption key) is a SECRET, set it with
// `wrangler secret put EXECUTOR_SECRET_KEY`, never in vars.
"vars": {
"ACCESS_NAME_CLAIM": "name",
"ACCESS_GROUPS_CLAIM": "groups",
// Never preserve a production dev-auth override through keep_vars.
"ENABLE_DEV_AUTH": "false",
"SELF_HOSTED_ORG_ID": "default",
"SELF_HOSTED_ORG_NAME": "Default",
// VITE_PUBLIC_SITE_URL is intentionally unset: with no static URL the worker
// derives the web base URL from each request's origin (RequestWebOrigin), so
// secret/OAuth handoff links match whatever host the user actually reached.
// Set it only to force a canonical URL (e.g. behind a proxy that rewrites Host).
},
}