Cloudflare Workers MCP: stable agent identity without KV races

Direct answer: Use an explicit, non-secret DELX_AGENT_ID binding for each logical Worker agent and environment. Pass that ID in every MCP identity argument, call resume_session after cold starts or deploys, and never infer identity from an edge IP. Workers KV is eventually consistent, so it must not own a live session or coordinate concurrent requests.

Send Streamable HTTP JSON-RPC requests to https://api.delx.ai/mcp?src=cloudflare-workers. This guide provides explicit identity bindings, canonical MCP calls, and state-consistency boundaries without assuming that network traffic identifies a person, agent, fleet, or customer.

1. Declare one ID per logical agent and environment

Cloudflare documents text environment variables as bindings for application configuration. A Delxagent_id is a declared identifier, not a credential, so a plain variable is appropriate. Sensitive recovery tokens or future API credentials belong in a Cloudflare secret instead. Read the official environment-variable guide and secrets guide.

name = "order-monitor-agent"
main = "src/index.ts"
compatibility_date = "2026-08-12"

[vars]
DELX_AGENT_ID = "cf-order-monitor-production"

[env.staging.vars]
DELX_AGENT_ID = "cf-order-monitor-staging"

Same logical agent, same ID; different agent or environment, different ID. Production and staging need explicit values because Cloudflare environment-variable configuration is environment-specific. Do not use a default such as unnamed-worker, an edge address, or a cold-start UUID.

2. Call the canonical Delx MCP endpoint

The live Delx manifest names https://api.delx.ai/mcp as canonical. The older /v1/mcp route currently remains compatible but responds with deprecation and sunset headers, so new integrations should not copy it.

interface Env {
  DELX_AGENT_ID: string;
}

const DELX_MCP = "https://api.delx.ai/mcp?src=cloudflare-workers";

async function callDelx(name: string, args: Record<string, unknown>) {
  const response = await fetch(DELX_MCP, {
    method: "POST",
    headers: {
      "content-type": "application/json",
      "accept": "application/json, text/event-stream",
    },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: "worker-request-1",
      method: "tools/call",
      params: { name, arguments: args },
    }),
  });

  if (!response.ok) {
    throw new Error("Delx MCP returned " + response.status);
  }
  return response.json();
}

export default {
  async fetch(_request: Request, env: Env): Promise<Response> {
    if (!env.DELX_AGENT_ID) {
      return Response.json({ error: "DELX_AGENT_ID is required" }, { status: 500 });
    }

    const result = await callDelx("resume_session", {
      agent_id: env.DELX_AGENT_ID,
    });

    return Response.json(result);
  },
};

In this example, resume_session: resume_session requires agent_id. It does not create continuity from network fingerprints. A warm response requires a capsule sealed by an earlier bounded session.

3. Open, use, and close a bounded session

If there is no active arc to resume, start_therapy_session: start_therapy_session opens a new session for the declared agent. Carry the returned session_id only for the bounded work that owns it.

{
  "jsonrpc": "2.0",
  "id": "worker-start-1",
  "method": "tools/call",
  "params": {
    "name": "start_therapy_session",
    "arguments": {
      "agent_id": "cf-order-monitor-production",
      "agent_name": "Order monitor",
      "source": "cloudflare-workers"
    }
  }
}

After verification, close_session can seal a sanitized capsule. Do not put secrets, raw customer payloads, credentials, or hidden chain of thought in it.

{
  "jsonrpc": "2.0",
  "id": "worker-close-1",
  "method": "tools/call",
  "params": {
    "name": "close_session",
    "arguments": {
      "session_id": "<ACTIVE_SESSION_ID>",
      "reason": "bounded run completed",
      "capsule": {
        "version": "1",
        "goal": "Verify order-monitor continuity after deploy",
        "done": ["Reused the configured stable identity"],
        "next": "Resume and revalidate before any external action",
        "blockers": [],
        "refuted": ["Edge IP is a durable agent identity"]
      }
    }
  }
}

4. Choose storage from the consistency requirement

StateCloudflare primitiveBoundary
Stable non-secret agent_idEnvironment-variable bindingSource of truth per logical agent and environment.
Credential or recovery tokenSecret bindingNever place it in Wrangler vars, logs, source control, capsules, or analytics.
Read-heavy artifact that tolerates stale readsWorkers KVCache or projection only; not a lock or authoritative active-session pointer.
Shared active session, dedupe, ordering, timerDurable ObjectOne coordination owner per logical agent when requests genuinely share mutable state.
Independent requestPlain WorkerCall MCP directly; do not add state infrastructure without a coordination requirement.

Why KV must not own the active session

Do not store live session ownership in KV. The official Workers KV consistency documentation explains that reads are eventually consistent, changes can take time to appear in other locations, and KV is not intended for atomic read/write coordination. Two concurrent edge requests can therefore observe different values.

When a Durable Object is justified

Use one Durable Object per logical agent only when requests must coordinate. Cloudflare recommends Durable Objects for stateful coordination and strong consistency. Use them when one agent needs serialized access to a shared active session, deduplication, ordered writes, or scheduled state—not merely to survive a cold start. See the official Durable Objects rules.

Verification checklist

  1. Deploy production and staging with different explicit DELX_AGENT_ID values.
  2. Call tools/list on the canonical endpoint and confirm HTTP 200 before a session mutation.
  3. Open one bounded session, record its returned ID privately, and close it with a sanitized capsule.
  4. Deploy a new Worker version and call resume_session with the unchanged production agent ID.
  5. Confirm the returned continuity belongs to that declared identity; never use a public aggregate or edge IP as proof.
  6. Exercise concurrent requests only if your Durable Object or independent-request design defines ownership explicitly.

Frequently asked questions

Does a Cloudflare Worker need KV for a stable Delx agent ID?

No. Use an explicit non-secret DELX_AGENT_ID environment-variable binding. It survives cold starts and deployments because it is configuration, while each Cloudflare environment can declare a different value.

Should production and staging share an agent ID?

No. Same logical agent, same ID; different agent or environment, different ID. Cloudflare environment vars are configured per environment, so declare production and staging values explicitly.

Can Workers KV own the active Delx session ID?

Do not store live session ownership in KV. Workers KV is eventually consistent and is not designed for atomic read-modify-write coordination. It can hold stale-tolerant cached artifacts, but not a lock or authoritative active-session pointer.

When should I use a Durable Object with Delx?

Use one Durable Object per logical agent only when requests must coordinate access to shared active state, serialize writes, deduplicate work, or own a timer. Independent Worker requests do not need a Durable Object merely to keep a stable agent ID.

Can Delx infer the same Worker from its edge IP?

No. Network addresses and routing metadata are not durable agent identity. Declare the agent ID in Worker configuration and pass it in the MCP tool arguments instead of relying on IP, User-Agent, or a random value created at cold start.

How does a Worker resume after a deployment?

Call resume_session with the same configured agent_id. A warm result exists only when an earlier session sealed a sanitized Continuity Capsule; otherwise the runtime can identify the agent but has no bounded trail to restore.

Related guides

Prefer agent-readable artifacts? Use the JSON specs in the sidebar.