Skip to content

Code Mode

Code Mode is the default Caplets surface. Instead of showing an agent every downstream tool up front, Caplets gives the agent typed caplets.<id> handles inside one TypeScript run.

Agents should use Code Mode to discover, call, filter, join, and summarize capability data without filling the visible tool list.

Ask the agent for the outcome you need and name the Caplet when it matters:

Use Caplets Code Mode to query OSV for npm react 18.2.0. Return package,
version, vulnerability count, and advisory IDs as compact JSON.

The visible MCP tool should be caplets__code_mode. Inside that tool, the agent runs TypeScript against generated handles such as caplets.osv.

A configured OSV Caplet appears as a handle such as:

const h = caplets.osv;

The handle supports discovery and execution:

const h = caplets.osv;
const tools = await h.searchTools("package version");
const details = await h.describeTool("query_package_version");
const result = await h.callTool("query_package_version", {
ecosystem: "npm",
name: "react",
version: "18.2.0",
});
return { tools: tools.items.map((tool) => tool.name), result };

In MCP clients the visible tool is caplets__code_mode; the TypeScript inside that tool uses handles such as caplets.osv.searchTools(...) and caplets.osv.callTool(...).

For most tasks, keep bulky raw payloads inside the Code Mode script and return compact JSON with the evidence the user needs.

Code Mode also installs standard JavaScript platform globals at runtime so scripts can shape data without reaching for direct I/O:

  • Pure utilities: atob, btoa, a documented Buffer subset, and structuredClone.
  • Web data objects: URL, URLSearchParams, TextEncoder, TextDecoder, Headers, Blob, File, FormData, ReadableStream, WritableStream, TransformStream, AbortController, AbortSignal, Request, and Response.
  • Scheduling: queueMicrotask, setTimeout, clearTimeout, setInterval, and clearInterval.
  • Randomness: crypto.randomUUID() and crypto.getRandomValues(...).

These are runtime globals for JavaScript muscle memory. They are intentionally not enumerated in the generated Code Mode declaration payload or tool prompt, which stays focused on Caplet handles, debug helpers, and console to avoid token bloat.

Direct I/O is intentionally unavailable. fetch is blocked; use Caplet handles for network, tool, resource, prompt, or command I/O. Node and module APIs such as process, require, imports, filesystem access, child processes, and direct network access are not available inside Code Mode scripts.

Prefer compact decision-ready data:

{
"package": "react",
"version": "18.2.0",
"vulnerabilityCount": 0,
"advisoryIds": []
}

If a call fails, return the Caplets result envelope so the next repair step has the exact error:

{
"ok": false,
"error": {
"code": "DOWNSTREAM_TOOL_NOT_FOUND",
"message": "Tool query_package_version was not found."
}
}
  • Do search or list first when you do not know the exact downstream tool name.
  • Do call describeTool(...) before constructing non-trivial arguments.
  • Do keep joins, filters, and bulky raw payloads inside the Code Mode script.
  • Avoid returning full tool lists, full schemas, or raw API responses unless the user asks for them.
  • Avoid inventing Caplet IDs, tool names, resource URIs, prompt names, or argument shapes.
  • Avoid using Code Mode as a security boundary; it is a context-management surface.

Run inline TypeScript:

Terminal window
caplets code-mode 'return Object.keys(caplets)'

Print the generated declarations:

Terminal window
caplets code-mode types

If a run behaves unexpectedly, check config and runtime state:

Terminal window
caplets doctor

Use progressive or direct exposure only when a client cannot run Code Mode or a workflow needs a small visible tool surface. Code Mode is a context-management surface, not a security boundary.