Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions apps/cloud/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DurableObject } from "cloudflare:workers";
import { SpanKind, SpanStatusCode, context, trace } from "@opentelemetry/api";
import {
ATTR_HTTP_REQUEST_METHOD,
Expand Down Expand Up @@ -46,6 +47,14 @@ export const McpSessionDOSqlite = Sentry.instrumentDurableObjectWithSentry(
McpSessionDOBase,
);

// Orphaned placeholder for the original key-value `McpSessionDO` class (migration
// v1). The live MCP session DO is now `McpSessionDOSqlite` (SQLite); the
// `MCP_SESSION` binding moved to it. Cloudflare won't delete `McpSessionDO` in the
// same deploy that moves its binding, so the class is left unbound and is kept
// exported here only to satisfy the migration. It can be removed in a later deploy
// (with a `deleted_classes: ["McpSessionDO"]` migration) now that nothing binds it.
export class McpSessionDO extends DurableObject {}

// ---------------------------------------------------------------------------
// Worker fetch handler
//
Expand Down
2 changes: 1 addition & 1 deletion apps/cloud/worker-configuration.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ declare namespace Cloudflare {
WORKOS_COOKIE_PASSWORD: string;
APP_URL: string;
WORKOS_CLAIM_TOKEN: string;
MCP_SESSION: DurableObjectNamespace<import("./src/server").McpSessionDO>;
MCP_SESSION: DurableObjectNamespace<import("./src/server").McpSessionDOSqlite>;
MARKETING: Fetcher /* executor-marketing */;
}
}
Expand Down
15 changes: 8 additions & 7 deletions apps/cloud/wrangler.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,21 @@
],
},
// The MCP session DO moved to the Cloudflare Agents (`McpAgent`) base, which
// stores state in SQLite. The original `McpSessionDO` was created with the
// key-value backend (`new_classes`), and Cloudflare cannot convert a live class
// to SQLite in place, nor delete a class while a binding still references it.
// Session state is ephemeral, so v2 repoints the `MCP_SESSION` binding to a new
// SQLite-backed class (`McpSessionDOSqlite`) and deletes the old KV `McpSessionDO`
// (now unreferenced). The worker exports `McpSessionDOSqlite`, not `McpSessionDO`.
// 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",
"deleted_classes": ["McpSessionDO"],
"new_sqlite_classes": ["McpSessionDOSqlite"],
},
],
Expand Down
Loading