{ "$schema": "node_modules/wrangler/config-schema.json", "name": "executor-cloud", "compatibility_date": "2025-04-01", "compatibility_flags": ["nodejs_compat"], "main": "src/server.ts", // The vite plugin fills in assets.directory (dist/client); the binding must // be declared here or env.ASSETS does not exist at runtime. "assets": { "binding": "ASSETS", }, "routes": [ { "pattern": "executor.sh", "custom_domain": true, }, ], "limits": { "cpu_ms": 30000, }, "observability": { "enabled": true, }, // Script-level logpush feeds the account's workers_trace_events Logpush job // (invocation logs, outcomes like exceededMemory, console output) into // Axiom. Pinned here because the setting lives on the script: a deploy that // omits it can reset it to false, which is how the export silently died in // the July deploy-tooling migration. "logpush": true, "durable_objects": { "bindings": [ { "name": "MCP_SESSION", "class_name": "McpSessionDOSqlite", }, { "name": "MCP_EXECUTION_OWNER", "class_name": "McpExecutionOwnerDirectoryDO", }, // Per-org execution rate-limit counter (abuse backstop). One instance // per organization via idFromName(orgId); a single { windowId, count } // record per instance, purged by alarm after inactivity. { "name": "EXECUTION_RATE_LIMITER", "class_name": "ExecutionRateLimiterDO", }, ], }, // The MCP session DO moved to the Cloudflare Agents (`McpAgent`) base, which // stores state in SQLite. The original `McpSessionDO` was created on the // key-value backend (`new_classes`) and cannot be converted in place. Cloudflare // also refuses to delete a class in the same deploy that moves its binding (it // validates the delete against the live binding), so v2 only CREATES the new // SQLite class `McpSessionDOSqlite` and the `MCP_SESSION` binding moves to it. // The old KV `McpSessionDO` is left orphaned (unbound, kept as a stub export in // server.ts so the migration stays valid); it can be deleted in a later deploy // now that nothing binds it. Session state is ephemeral, so nothing is lost. "migrations": [ { "tag": "v1", "new_classes": ["McpSessionDO"], }, { "tag": "v2", "new_sqlite_classes": ["McpSessionDOSqlite"], }, { "tag": "v3", "new_sqlite_classes": ["ExecutionRateLimiterDO"], }, { "tag": "v4", "new_sqlite_classes": ["McpExecutionOwnerDirectoryDO"], }, ], "services": [ { "binding": "MARKETING", "service": "executor-marketing", }, ], "hyperdrive": [ { "binding": "HYPERDRIVE", "id": "ca5f68119e4e4277b2ad6298a9048875", "localConnectionString": "postgresql://postgres:postgres@127.0.0.1:5433/postgres", }, ], // Plugin blob seam backend (multi-MB resolved specs). Bucket must exist // before deploy: `wrangler r2 bucket create executor-cloud-blobs`. "r2_buckets": [ { "binding": "BLOBS", "bucket_name": "executor-cloud-blobs", }, ], // Pins the Worker to the Hyperdrive/Postgres region. Added in #420 to fix // MCP Hyperdrive connection pressure; dropped in #1693 as a placement // experiment, which took `user_store.*` from ~12ms to ~300ms because every // query started crossing regions. Restored to measure that against the // JWKS verify time the experiment also moved. "placement": { "region": "aws:us-east-1", }, "worker_loaders": [ { "binding": "LOADER", }, ], // Stamps spans (`service.version`) and mem-metrics snapshots with the // running Worker version id, so an Axiom step-change maps to the exact // deploy without Cloudflare API archaeology. memory-metrics.ts already // reads this binding; it was never declared before, so it always fell back. "version_metadata": { "binding": "CF_VERSION_METADATA", }, "vars": { "VITE_PUBLIC_SITE_URL": "https://executor.sh", // Keeps the /__sentry-otel-verify probe live in production: Sentry // delivery failed silently for weeks (zero events after ~Jul 30 with an // active DSN), and without this there is no way to test the pipeline // end-to-end short of waiting for a real error. The endpoint only fires // when its exact path is requested and the events are explicitly tagged // synthetic. "SENTRY_OTEL_VERIFY": "true", "VITE_PUBLIC_POSTHOG_KEY": "phc_nNLrNMALpRsfrEkZovUkfMxYbcJvHnsJHeoSPavprgLL", // Browser OTLP spans → same-origin, forwarded to Axiom by the worker // (src/observability/browser-traces.ts). Relative on purpose: the // client resolves it against the page origin, so previews work too. "VITE_PUBLIC_OTLP_TRACES_URL": "/v1/traces", // Per-session sampling: 1 = every signed-in session exports. Dial down // (e.g. "0.1") if Axiom volume becomes a cost concern. "VITE_PUBLIC_OTLP_SAMPLE_RATIO": "1", }, }