From 9473330049d3896196dd688bab78cd82f59c16b9 Mon Sep 17 00:00:00 2001 From: Matt Carey Date: Wed, 18 Mar 2026 11:50:36 +0000 Subject: [PATCH 1/4] =?UTF-8?q?Add=20changelog=20for=20@cloudflare/codemod?= =?UTF-8?q?e=20v0.2.0=E2=80=93v0.2.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agents/2026-03-17-codemode-sdk-v0.2.1.mdx | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx diff --git a/src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx b/src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx new file mode 100644 index 00000000000..fad65475af5 --- /dev/null +++ b/src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx @@ -0,0 +1,92 @@ +--- +title: "@cloudflare/codemode v0.2.1: MCP barrel export, zero-dependency main entry point, and custom sandbox modules" +description: "Codemode v0.2.0–v0.2.1 adds a new @cloudflare/codemode/mcp export with codeMcpServer and openApiMcpServer, makes the main entry point dependency-free, and lets you inject custom modules into the sandbox." +products: + - agents + - workers +date: 2026-03-17 +--- + +import { TypeScriptExample } from "~/components"; + +The latest releases of [`@cloudflare/codemode`](https://www.npmjs.com/package/@cloudflare/codemode) add a new MCP barrel export, remove `ai` and `zod` as required peer dependencies from the main entry point, and give you more control over the sandbox. + +## New `@cloudflare/codemode/mcp` export + +A new `@cloudflare/codemode/mcp` entry point provides two functions that wrap MCP servers with Code Mode: + +- **`codeMcpServer({ server, executor })`** — wraps an existing MCP server with a single `code` tool where each upstream tool becomes a typed `codemode.*` method. +- **`openApiMcpServer({ spec, executor, request })`** — creates `search` and `execute` MCP tools from an OpenAPI spec with host-side request proxying and automatic `$ref` resolution. + + + +```ts +import { codeMcpServer } from "@cloudflare/codemode/mcp"; +import { DynamicWorkerExecutor } from "@cloudflare/codemode"; + +const executor = new DynamicWorkerExecutor({ loader: env.LOADER }); + +// Wrap an existing MCP server — all its tools become +// typed methods the LLM can call from generated code +const server = codeMcpServer({ server: upstreamMcp, executor }); +``` + + + +## Zero-dependency main entry point + +**Breaking change in v0.2.0:** `generateTypes` and the `ToolDescriptor` / `ToolDescriptors` types have moved to `@cloudflare/codemode/ai`: + + + +```ts +// Before +import { generateTypes } from "@cloudflare/codemode"; + +// After +import { generateTypes } from "@cloudflare/codemode/ai"; +``` + + + +The main entry point (`@cloudflare/codemode`) no longer requires the `ai` or `zod` peer dependencies. It now exports: + +| Export | Description | +| ----------------------------- | ---------------------------------------------------------------- | +| `sanitizeToolName` | Sanitize tool names into valid JS identifiers | +| `normalizeCode` | Normalize LLM-generated code into async arrow functions | +| `generateTypesFromJsonSchema` | Generate TypeScript type definitions from plain JSON Schema | +| `jsonSchemaToType` | Convert a single JSON Schema to a TypeScript type string | +| `DynamicWorkerExecutor` | Sandboxed code execution via Dynamic Worker Loader | +| `ToolDispatcher` | RPC target for dispatching tool calls from sandbox to host | + +The `ai` and `zod` peer dependencies are now optional — only required when importing from `@cloudflare/codemode/ai`. + +## Custom sandbox modules + +`DynamicWorkerExecutor` now accepts an optional `modules` option to inject custom ES modules into the sandbox: + + + +```ts +const executor = new DynamicWorkerExecutor({ + loader: env.LOADER, + modules: { + "my-utils": { add: (a: number, b: number) => a + b }, + }, +}); +``` + + + +## Internal normalization and sanitization + +`DynamicWorkerExecutor` now normalizes code and sanitizes tool names internally. You no longer need to call `normalizeCode()` or `sanitizeToolName()` before passing code and functions to `execute()`. + +## Upgrade + +```sh +npm i @cloudflare/codemode@latest +``` + +See the [Code Mode documentation](/agents/api-reference/codemode/) for the full API reference. From eb8b4c1160a1c9254ffccde2786233b953b060d4 Mon Sep 17 00:00:00 2001 From: Matt Carey Date: Wed, 18 Mar 2026 18:21:33 +0000 Subject: [PATCH 2/4] =?UTF-8?q?Update=20codemode=20docs=20for=20v0.2.0?= =?UTF-8?q?=E2=80=93v0.2.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix generateTypes import path (now @cloudflare/codemode/ai) - Remove stale zod-to-ts Vite config and limitation - Update installation to reflect optional ai/zod peer deps - Add modules option to DynamicWorkerExecutor table - Add internal normalization/sanitization note - Add MCP server wrappers section (codeMcpServer, openApiMcpServer) - Add generateTypesFromJsonSchema example - Fix changelog modules example (values are source strings) --- .../agents/2026-03-17-codemode-sdk-v0.2.1.mdx | 4 +- .../docs/agents/api-reference/codemode.mdx | 99 ++++++++++++++----- 2 files changed, 78 insertions(+), 25 deletions(-) diff --git a/src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx b/src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx index fad65475af5..0ad847239b1 100644 --- a/src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx +++ b/src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx @@ -72,9 +72,11 @@ The `ai` and `zod` peer dependencies are now optional — only required when imp const executor = new DynamicWorkerExecutor({ loader: env.LOADER, modules: { - "my-utils": { add: (a: number, b: number) => a + b }, + "utils.js": `export function add(a, b) { return a + b; }`, }, }); + +// Sandbox code can then: import { add } from "utils.js" ``` diff --git a/src/content/docs/agents/api-reference/codemode.mdx b/src/content/docs/agents/api-reference/codemode.mdx index d56e33c96d5..f0d9e56dd93 100644 --- a/src/content/docs/agents/api-reference/codemode.mdx +++ b/src/content/docs/agents/api-reference/codemode.mdx @@ -37,6 +37,12 @@ For simple, single tool calls, standard AI SDK tool calling is simpler and suffi ## Installation +```sh +npm install @cloudflare/codemode +``` + +The `ai` and `zod` packages are optional peer dependencies — only required when importing from `@cloudflare/codemode/ai`: + ```sh npm install @cloudflare/codemode ai zod ``` @@ -144,23 +150,6 @@ compatibility_flags = ["nodejs_compat"] -### Vite configuration - -If you use `zod-to-ts` (which codemode depends on), add a `__filename` define to your Vite config: - - - -```ts -export default defineConfig({ - plugins: [react(), cloudflare(), tailwindcss()], - define: { - __filename: "'index.ts'", - }, -}); -``` - - - ## How it works 1. `createCodeTool` generates TypeScript type definitions from your tools and builds a description the LLM can read. @@ -246,6 +235,54 @@ const codemode = createCodeTool({ Tool names with hyphens or dots (common in MCP) are automatically sanitized to valid JavaScript identifiers (for example, `my-server.list-items` becomes `my_server_list_items`). +## MCP server wrappers + +The `@cloudflare/codemode/mcp` export provides two functions that wrap MCP servers with Code Mode. + +### `codeMcpServer` + +Wraps an existing MCP server with a single `code` tool. Each upstream tool becomes a typed `codemode.*` method inside the sandbox: + + + +```ts +import { codeMcpServer } from "@cloudflare/codemode/mcp"; +import { DynamicWorkerExecutor } from "@cloudflare/codemode"; + +const executor = new DynamicWorkerExecutor({ loader: env.LOADER }); +const server = await codeMcpServer({ server: upstreamMcp, executor }); +``` + + + +### `openApiMcpServer` + +Creates an MCP server with `search` and `execute` tools from an OpenAPI spec. All `$ref` pointers are resolved before being passed to the sandbox, and the host-side `request` handler keeps authentication out of the sandbox: + + + +```ts +import { openApiMcpServer } from "@cloudflare/codemode/mcp"; +import { DynamicWorkerExecutor } from "@cloudflare/codemode"; + +const executor = new DynamicWorkerExecutor({ loader: env.LOADER }); +const server = openApiMcpServer({ + spec: openApiSpec, + executor, + request: async ({ method, path, query, body }) => { + // Runs on the host — add auth headers here + const res = await fetch(`https://api.example.com${path}`, { + method, + headers: { Authorization: `Bearer ${token}` }, + body: body ? JSON.stringify(body) : undefined, + }); + return res.json(); + }, +}); +``` + + + ## The Executor interface The `Executor` interface is deliberately minimal — implement it to run code in any sandbox: @@ -283,11 +320,14 @@ Returns an AI SDK compatible `Tool`. Executes code in an isolated Cloudflare Worker via `WorkerLoader`. -| Option | Type | Default | Description | -| ---------------- | ----------------- | -------- | ------------------------------------------------------------ | -| `loader` | `WorkerLoader` | required | Worker Loader binding from `env.LOADER` | -| `timeout` | `number` | `30000` | Execution timeout in ms | -| `globalOutbound` | `Fetcher \| null` | `null` | Network access control. `null` = blocked, `Fetcher` = routed | +| Option | Type | Default | Description | +| ---------------- | -------------------------- | -------- | ---------------------------------------------------------------------------------- | +| `loader` | `WorkerLoader` | required | Worker Loader binding from `env.LOADER` | +| `timeout` | `number` | `30000` | Execution timeout in ms | +| `globalOutbound` | `Fetcher \| null` | `null` | Network access control. `null` = blocked, `Fetcher` = routed | +| `modules` | `Record` | — | Custom ES modules available in the sandbox. Keys are specifiers, values are source. | + +Code and tool names are normalized and sanitized internally — you do not need to call `normalizeCode()` or `sanitizeToolName()` before passing them to `execute()`. ### `generateTypes(tools)` @@ -296,7 +336,7 @@ Generates TypeScript type definitions from your tools. Used internally by `creat ```ts -import { generateTypes } from "@cloudflare/codemode"; +import { generateTypes } from "@cloudflare/codemode/ai"; const types = generateTypes(myTools); // Returns: @@ -308,6 +348,18 @@ const types = generateTypes(myTools); +For JSON Schema inputs that don't depend on the AI SDK, use the main entry point: + + + +```ts +import { generateTypesFromJsonSchema } from "@cloudflare/codemode"; + +const types = generateTypesFromJsonSchema(jsonSchemaToolDescriptors); +``` + + + ### `sanitizeToolName(name)` Converts tool names into valid JavaScript identifiers. @@ -337,7 +389,6 @@ sanitizeToolName("delete"); // "delete_" - **Tool approval (`needsApproval`) is not supported yet.** Tools with `needsApproval: true` execute immediately inside the sandbox without pausing for approval. Support for approval flows within codemode is planned. For now, do not pass approval-required tools to `createCodeTool` — use them through standard AI SDK tool calling instead. - Requires Cloudflare Workers environment for `DynamicWorkerExecutor`. - Limited to JavaScript execution. -- The `zod-to-ts` dependency bundles the TypeScript compiler, which increases Worker size. - LLM code quality depends on prompt engineering and model capability. ## Related resources From 1b586e2f028d4b1aaddb83c5480337a8e454c7ce Mon Sep 17 00:00:00 2001 From: Matt <77928207+mattzcarey@users.noreply.github.com> Date: Wed, 18 Mar 2026 18:56:39 +0000 Subject: [PATCH 3/4] Update src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx Co-authored-by: ask-bonk[bot] <249159057+ask-bonk[bot]@users.noreply.github.com> --- src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx b/src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx index 0ad847239b1..40c4300b4f4 100644 --- a/src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx +++ b/src/content/changelog/agents/2026-03-17-codemode-sdk-v0.2.1.mdx @@ -28,7 +28,7 @@ const executor = new DynamicWorkerExecutor({ loader: env.LOADER }); // Wrap an existing MCP server — all its tools become // typed methods the LLM can call from generated code -const server = codeMcpServer({ server: upstreamMcp, executor }); +const server = await codeMcpServer({ server: upstreamMcp, executor }); ``` From acbbb62d6b5fe918b81e5f71615eb43e50ef64b6 Mon Sep 17 00:00:00 2001 From: Matt Carey Date: Wed, 18 Mar 2026 18:57:44 +0000 Subject: [PATCH 4/4] Address bonk review comments - Add missing await to codeMcpServer call in changelog - Replace contraction "don't" with "do not" per style guide - Restructure install commands for clarity (separate base + optional deps) --- src/content/docs/agents/api-reference/codemode.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/docs/agents/api-reference/codemode.mdx b/src/content/docs/agents/api-reference/codemode.mdx index f0d9e56dd93..28177685bcd 100644 --- a/src/content/docs/agents/api-reference/codemode.mdx +++ b/src/content/docs/agents/api-reference/codemode.mdx @@ -41,10 +41,10 @@ For simple, single tool calls, standard AI SDK tool calling is simpler and suffi npm install @cloudflare/codemode ``` -The `ai` and `zod` packages are optional peer dependencies — only required when importing from `@cloudflare/codemode/ai`: +If you use `@cloudflare/codemode/ai`, also install the `ai` and `zod` peer dependencies: ```sh -npm install @cloudflare/codemode ai zod +npm install ai zod ``` ## Quick start @@ -348,7 +348,7 @@ const types = generateTypes(myTools); -For JSON Schema inputs that don't depend on the AI SDK, use the main entry point: +For JSON Schema inputs that do not depend on the AI SDK, use the main entry point: