# Code Mode

Code Mode is an optional tool surface on the [Ordering MCP](./mcp-server) that lets an LLM execute a single JavaScript function which composes multiple backend operations in one round-trip. Inspired by [Cloudflare's Code Mode](https://blog.cloudflare.com/code-mode/) pattern.

## Why

Classic tool calling forces the model to burn a full turn — including the entire tool registry in context — for every operation. For multi-step flows ("find sushi near me, grab the first store's menu, build a cart") this means 3–5 round-trips, 3–5× the tokens, and 3–5× the latency.

Code Mode collapses that: **one tool call, one round-trip, one typed JS function that runs to completion server-side.**

## How

The MCP exposes a single tool:

```
code(code: string)
```

Where `code` is an async arrow function that runs in a **V8 isolate sandbox** on our servers (128 MB memory cap, 10-second timeout). Inside the sandbox, a `codemode` object exposes all the same operations available as classic tools — typed and ready to chain:

```javascript
async () => {
  await codemode.setFulfillmentContext({
    mode: "DELIVERY_BY_MERCHANT",
    addressId: "550e8400-e29b-41d4-a716-446655440000"
  });

  const discovery = await codemode.discoverStores({
    location: { latitude: 37.77, longitude: -122.42 },
    query: "sushi",
    limit: 3,
  });

  const store = discovery.stores[0];
  const menu = await codemode.getCatalogSet({ catalogSetId: store.catalogSetId });
  const firstItem = Object.values(menu.items)[0];

  const cart = await codemode.addToCart({
    storeId: store.storeId,
    catalogSetId: store.catalogSetId,
    item: { itemId: firstItem.itemId, quantity: 1, modifierGroups: null },
  });

  return { store: store.name, cart };
}
```

The model submits this as the `code` argument. We run it in the sandbox, return the function's resolved value as the tool output.

## Security model

The sandbox is a fresh V8 isolate created per call and disposed after — no shared state between calls or users.

- **No network**: `fetch`, `XMLHttpRequest`, `WebSocket`, and all outbound I/O are absent from the isolate's global. The only way the code can reach anything is through the `codemode.*` bindings we inject.
- **No filesystem**: no `require`, no `import`, no `fs`.
- **No secrets**: `process.env` is not available. Your Marketfront JWT never enters the sandbox — it's held by the host-side runtime that services the `codemode.*` binding calls.
- **Bounded CPU**: 10-second timeout.
- **Bounded memory**: 128 MB heap.

Auth is never in the sandbox. The host-side runtime makes every upstream call with the session-bound Marketfront JWT. If the model-written code tries to escape (e.g., dynamically constructs a string to pass elsewhere), there is nowhere to escape *to*.

## What's exposed

The sandboxed `codemode` namespace contains the same operations as the classic tools, shaped for direct chaining:

```ts
type FulfillmentType = "DELIVERY_BY_MERCHANT" | "PICKUP";

declare const codemode: {
  getSession(): Promise<{
    user: { userId: string; email: string | null; firstName?: string | null; lastName?: string | null };
    partnerId: string | null;
    savedAddressId: string | null;
    expiresAt: string;
    fulfillmentContext: { mode: FulfillmentType; addressId?: string; storeId?: string } | null;
    cart: object | null;
  }>;

  setFulfillmentContext(fc: {
    mode: FulfillmentType;
    addressId?: string;
    storeId?: string;
  }): Promise<{ ok: true; fulfillmentContext: object }>;

  discoverStores(req: {
    location: { latitude: number; longitude: number };
    query?: string | null;
    fulfillmentType?: FulfillmentType;
    limit?: number;
    offset?: number;
  }): Promise<{ stores: Array<object>; totalCount: number; hasMore: boolean }>;

  getCatalogSet(req: { catalogSetId: string }): Promise<object>;

  addToCart(req: {
    cart?: object;
    storeId?: string;
    catalogSetId?: string;
    item: { itemId: string; quantity: number; modifierGroups: Array<unknown> | null };
  }): Promise<object>;

  removeFromCart(req: { cart: object; lineItemId: string }): Promise<object>;
  updateCartQuantity(req: { cart: object; lineItemId: string; quantity: number }): Promise<object>;
  getCart(): Promise<object | null>;

  validateOrder(req: {
    cart: object;
    fulfillmentType: FulfillmentType;
    deliveryInfo?: object;
    amounts?: { tip?: number };
  }): Promise<object>;

  placeOrder(req: {
    cart: object;
    fulfillmentType: FulfillmentType;
    deliveryInfo?: object;
    amounts: object; // echoed from the prior validateOrder response
    paymentId: string | null;
  }): Promise<object>;
};
```

This TypeScript declaration is baked into the `code` tool's description, so capable models (Claude, GPT-4-class) write correctly-typed code without extra prompting.

## When to use it

| Scenario | Classic tools | Code Mode |
|---|---|---|
| Single operation ("what's in my cart?") | ✅ simpler | overkill |
| Multi-step flow (discovery → menu → cart → review) | works but expensive | ✅ **3–5× cheaper** |
| Dynamic branching ("if the closest place is closed, try the second") | multiple turns | ✅ one turn |
| User confirmation in the middle (place order) | ✅ host can gate | ✗ whole function runs atomically — prefer classic for destructive steps |
| Debugging | easier — one tool per operation | harder — the whole script is opaque until it returns |

**Recommended pattern**: use Code Mode for **discovery + cart construction**, then fall back to classic tools (`validateOrder`, `placeOrder`) for user-in-the-loop checkout so clients can enforce confirmation prompts.

## Tool annotations

The `code` tool carries:

- `destructiveHint: true` — it *can* perform destructive operations (via `placeOrder` inside the sandbox).
- `openWorldHint: true` — it reaches external systems (Marketfront).

Hosts like Claude Desktop will typically prompt the user before each `code` call. If you want tighter checkout gating, instruct the model to use `validateOrder` / `placeOrder` as classic tools rather than inside a Code Mode script.

## Errors

The `code` tool returns:

```json
{
  "content": [{ "type": "text", "text": "<JSON-stringified result>" }],
  "structuredContent": {
    "result": <the function's return value, or null>,
    "logs": ["[log] ...", "[warn] ..."]
  }
}
```

On failure (timeout, OOM, thrown exception, syntax error):

```json
{
  "isError": true,
  "content": [{ "type": "text", "text": "Code Mode error: <message>" }],
  "structuredContent": {
    "errorCode": "code_mode_error",
    "message": "<message>",
    "logs": ["..."]
  }
}
```

`console.log`/`console.warn`/`console.error` inside the sandbox are captured into `logs`.
