MCP server wrapping; custom sandbox modules; zero-dependency entry
v0.2.1
The latest releases of @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 singlecodetool where each upstream tool becomes a typedcodemode.*method.openApiMcpServer({ spec, executor, request })— createssearchandexecuteMCP tools from an OpenAPI spec with host-side request proxying and automatic$refresolution.
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { codeMcpServer } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@cloudflare/codemode/mcp"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { DynamicWorkerExecutor } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@cloudflare/codemode"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> executor</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1itgoe"> new</span><span class="nb-shiki-1t8gfj"> DynamicWorkerExecutor</span><span class="nb-shiki-140thh">({ loader: env.</span><span class="nb-shiki-dzsirb">LOADER</span><span class="nb-shiki-140thh"> });</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-21nrsd">// Wrap an existing MCP server — all its tools become</span></span>
<span class="line"><span class="nb-shiki-21nrsd">// typed methods the LLM can call from generated code</span></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> server</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1itgoe"> await</span><span class="nb-shiki-1t8gfj"> codeMcpServer</span><span class="nb-shiki-140thh">({ server: upstreamMcp, executor });</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { codeMcpServer } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@cloudflare/codemode/mcp"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { DynamicWorkerExecutor } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@cloudflare/codemode"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> executor</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1itgoe"> new</span><span class="nb-shiki-1t8gfj"> DynamicWorkerExecutor</span><span class="nb-shiki-140thh">({ loader: env.</span><span class="nb-shiki-dzsirb">LOADER</span><span class="nb-shiki-140thh"> });</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-21nrsd">// Wrap an existing MCP server — all its tools become</span></span>
<span class="line"><span class="nb-shiki-21nrsd">// typed methods the LLM can call from generated code</span></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> server</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1itgoe"> await</span><span class="nb-shiki-1t8gfj"> codeMcpServer</span><span class="nb-shiki-140thh">({ server: upstreamMcp, executor });</span></span>
Zero-dependency main entry point
Breaking change in v0.2.0: generateTypes and the ToolDescriptor / ToolDescriptors types have moved to @cloudflare/codemode/ai:
<span class="line"><span class="nb-shiki-21nrsd">// Before</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { generateTypes } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@cloudflare/codemode"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-21nrsd">// After</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { generateTypes } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@cloudflare/codemode/ai"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"><span class="nb-shiki-21nrsd">// Before</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { generateTypes } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@cloudflare/codemode"</span><span class="nb-shiki-140thh">;</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-21nrsd">// After</span></span>
<span class="line"><span class="nb-shiki-1itgoe">import</span><span class="nb-shiki-140thh"> { generateTypes } </span><span class="nb-shiki-1itgoe">from</span><span class="nb-shiki-mdbnqw"> "@cloudflare/codemode/ai"</span><span class="nb-shiki-140thh">;</span></span>
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:
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> executor</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1itgoe"> new</span><span class="nb-shiki-1t8gfj"> DynamicWorkerExecutor</span><span class="nb-shiki-140thh">({</span></span>
<span class="line"><span class="nb-shiki-140thh"> loader: env.</span><span class="nb-shiki-dzsirb">LOADER</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh"> modules: {</span></span>
<span class="line"><span class="nb-shiki-mdbnqw"> "utils.js"</span><span class="nb-shiki-140thh">: </span><span class="nb-shiki-mdbnqw">`export function add(a, b) { return a + b; }`</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh"> },</span></span>
<span class="line"><span class="nb-shiki-140thh">});</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-21nrsd">// Sandbox code can then: import { add } from "utils.js"</span></span>
<span class="line"><span class="nb-shiki-1itgoe">const</span><span class="nb-shiki-dzsirb"> executor</span><span class="nb-shiki-1itgoe"> =</span><span class="nb-shiki-1itgoe"> new</span><span class="nb-shiki-1t8gfj"> DynamicWorkerExecutor</span><span class="nb-shiki-140thh">({</span></span>
<span class="line"><span class="nb-shiki-140thh"> loader: env.</span><span class="nb-shiki-dzsirb">LOADER</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh"> modules: {</span></span>
<span class="line"><span class="nb-shiki-mdbnqw"> "utils.js"</span><span class="nb-shiki-140thh">: </span><span class="nb-shiki-mdbnqw">`export function add(a, b) { return a + b; }`</span><span class="nb-shiki-140thh">,</span></span>
<span class="line"><span class="nb-shiki-140thh"> },</span></span>
<span class="line"><span class="nb-shiki-140thh">});</span></span>
<span class="line"></span>
<span class="line"><span class="nb-shiki-21nrsd">// Sandbox code can then: import { add } from "utils.js"</span></span>
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
<span class="line"><span class="nb-shiki-1t8gfj">npm</span><span class="nb-shiki-mdbnqw"> i</span><span class="nb-shiki-mdbnqw"> @cloudflare/codemode@latest</span></span>
See the Code Mode documentation for the full API reference.
Fetched July 22, 2026


