npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@interopio/code-mode

v0.0.2

Published

io.Intelligence Code Mode Library

Downloads

374

Readme

io.Intelligence Code Mode

Table of Contents


Introduction

@interopio/code-mode enables Large Language Models (LLMs) to orchestrate multiple tools by generating and executing JavaScript inside an isolated QuickJS WebAssembly sandbox. Instead of exposing every tool directly to the model, Code Mode exposes a small set of meta-tools for discovering tools, reading their schemas, and running a program that coordinates them.

Key Features

  • Sandboxed execution: Runs model-generated JavaScript in an isolated QuickJS WASM runtime.
  • Reduced tool surface: Replaces a large tool list with three stable meta-tools.
  • Multi-tool orchestration: Allows one program to call, combine, and transform results from several tools.
  • Browser and Node.js support: Provides dedicated entry points for browser and Node.js hosts.
  • Tool filtering: Excludes tools from the model-visible catalog using configuration or each tool's enabled flag.
  • Policy interception: Applies approval, authorization, validation, or rate-limiting logic before each real tool call.
  • Independent sessions: Supports concurrent runs with separate tool registries and cancellation signals.
  • Resource limits: Configures sandbox timeout and memory limits.

Target Audience

Developers building AI assistants, MCP clients, or MCP servers that need to expose a large tool catalog while keeping the model-facing interface compact and allowing controlled, multi-step execution.


Installation

npm install @interopio/code-mode

The package provides separate browser and Node.js entry points:

import { IoCodeModeFactory } from "@interopio/code-mode/browser";
import { IoCodeModeFactory } from "@interopio/code-mode/node";

The root import, @interopio/code-mode, resolves to the browser build.

Requirements

  • A QuickJS WebAssembly file accessible to the host.
  • A browser-served URL for wasmLocation when using the browser entry point.
  • A filesystem-accessible path for wasmLocation when using the Node.js entry point.
  • Tool implementations that accept a single object argument and return a ToolResult.

Core Concepts

Sandboxed Tool Orchestration

Code Mode binds registered tools as asynchronous functions inside a QuickJS sandbox. The model writes plain JavaScript that calls these functions, processes their results, and returns a final value.

Tool names are converted to safe JavaScript identifiers under the tool_ namespace. For example, weather.get-current may be exposed as tool_weather_get_current. Always use the exact name returned by getTools.

Tool calls cross the sandbox boundary into the host application. The host remains responsible for the actual tool implementation and any external side effects.

Meta-Tools

getLlmTools() returns three tools for the LLM:

| Tool | Description | | ------------------- | ------------------------------------------------------------------------------- | | getTools | Lists available tools and their descriptions. | | getToolDefinition | Returns the input and output schemas for a selected tool. | | executeCode | Runs plain JavaScript with the available tools bound as asynchronous functions. |

The executeCode input includes:

{
    code: string;
    explanation: string;
}

The explanation is required by the model-facing schema to encourage a clear execution plan. It is passed through but is not interpreted by the runtime.

Sessions

The factory returns a root API that owns the shared sandbox. Call createSession() for each independent or concurrent run:

const codeMode = await IoCodeModeFactory(config);
const session = codeMode.createSession();

Each session has its own:

  • Tool registry.
  • Tool filter application.
  • Runtime state.

setTools() replaces a session's complete registry for future runs. getLlmTools() snapshots the current registry and optional signal, so later setTools() calls do not change already-prepared runs. This allows concurrent runs to share one session while keeping their tools and cancellation signals isolated.

Tool Policies

Code Mode provides two policy layers:

  1. toolFilter controls whether a tool is visible and callable.
  2. interceptors.onToolCall runs immediately before a tool is invoked.

An interceptor may allow a call, deny it with a reason, or replace its input:

interceptors: {
  onToolCall: async ({ tool, input }) => {
    if (tool.name === "payments.transfer") {
      return { allowed: false, reason: "Transfers require manual approval." };
    }

    return { allowed: true, input };
  },
}

Because the interceptor is asynchronous, it can wait for user approval before allowing or denying execution.


API Reference

IoCodeModeFactory

IoCodeModeFactory(
  config: IoCodeMode.Config
): Promise<IoCodeMode.API>

Creates the Code Mode API and configures the shared QuickJS sandbox.

Parameters:

  • config: Runtime, policy, and WASM configuration.

Returns: A promise resolving to an IoCodeMode.API instance.

Throws: A validation error when required configuration is missing or invalid.

API Methods

getSystemInstruction

getSystemInstruction(): string

Returns the instructions that teach the model how to use the meta-tools and sandbox-bound functions. Custom instructions are appended to the built-in protocol.

setTools

setTools(update: RuntimeTool[] | ((current: RuntimeTool[]) => RuntimeTool[])): void

Replaces or updates the current session's tool registry. Filtering and safe-name generation are applied when the registry is updated.

getLlmTools

getLlmTools(options?: { signal?: AbortSignal }): LlmTool[]

Returns the getTools, getToolDefinition, and executeCode meta-tools to expose to the LLM. The optional signal is scoped to executions through the returned tool wrappers.

createSession

createSession(): IoCodeMode.API

Creates an independent session that shares the configured sandbox but has its own registry and cancellation state.

Runtime Tools

Tools passed to setTools() use this shape:

interface RuntimeTool {
    name: string;
    description?: string;
    inputSchema?: Record<string, unknown>;
    outputSchema?: Record<string, unknown>;
    source?: { mcpName?: string };
    _meta?: Record<string, unknown>;
    enabled?: boolean;
    execute(
        args: Record<string, unknown>,
        options?: { signal?: AbortSignal }
    ): Promise<{
        content: Array<{ type: "text"; text: string }>;
        structuredContent?: Record<string, unknown>;
        isError?: boolean;
    }>;
}
  • enabled: false excludes the tool from the catalog.
  • source and _meta are passed to filters and interceptors when supplied by the host.
  • When outputSchema is present, Code Mode attempts to parse successful JSON output before returning it to sandbox code.
  • A result marked isError: true (or a rejected execute) makes the sandbox-side call throw with the tool's error message, so failures are distinguishable from data and an unhandled one fails the whole script.

Configuration

interface Config {
    wasmLocation: string;
    overwriteSystemInstruction?: (current: string) => string;
    interceptors?: {
        onToolCall?: (context: ToolCallContext) => Promise<InterceptorDecision>;
    };
    timeout?: number;
    memoryLimit?: number;
    toolFilter?: (tool: ToolDefinition) => boolean;
}

| Property | Type | Required | Default | Description | | ---------------------------- | ---------- | -------- | ----------- | --------------------------------------------------------------------------- | | wasmLocation | string | Yes | - | QuickJS WASM URL in a browser or filesystem path in Node.js. | | overwriteSystemInstruction | function | No | Identity | Receives the default system instruction and returns the instruction to use. | | interceptors.onToolCall | function | No | Allow | Asynchronous policy hook invoked before every sandbox-originated tool call. | | timeout | number | No | 30000 | Maximum sandbox execution time in milliseconds. | | memoryLimit | number | No | 128 | Sandbox memory limit in megabytes. | | toolFilter | function | No | Include all | Returns true to include a tool or false to hide it. |


Usage

Browser

Place the QuickJS WASM file in a publicly served location, such as public/quickjs/emscripten-module.wasm in a Vite or Angular application:

import { IoCodeModeFactory, type IoCodeMode } from "@interopio/code-mode/browser";

const hostTools = [
    {
        name: "search",
        description: "Searches the host application's data.",
        inputSchema: {
            type: "object",
            properties: { query: { type: "string" } },
            required: ["query"],
        },
        execute: async ({ query }) => ({
            content: [{ type: "text", text: JSON.stringify({ query, matches: [] }) }],
            structuredContent: { query, matches: [] },
        }),
    },
] satisfies IoCodeMode.RuntimeTool[];

const codeMode = await IoCodeModeFactory({
    wasmLocation: "/quickjs/emscripten-module.wasm",
    timeout: 30_000,
    memoryLimit: 128,
    toolFilter: (tool) => !tool.name.startsWith("admin."),
});

const session = codeMode.createSession();

session.setTools([
    {
        name: "weather.get",
        description: "Returns the current weather for a city.",
        inputSchema: {
            type: "object",
            properties: { city: { type: "string" } },
            required: ["city"],
        },
        outputSchema: {
            type: "object",
            properties: { temperatureC: { type: "number" } },
            required: ["temperatureC"],
        },
        execute: async ({ city }) => ({
            content: [{ type: "text", text: JSON.stringify({ city, temperatureC: 21 }) }],
            structuredContent: { city, temperatureC: 21 },
        }),
    },
]);

const systemInstruction = codeMode.getSystemInstruction();
const toolsForModel = session.getLlmTools();

Pass systemInstruction and toolsForModel to the model integration used by the host application.

Node.js

Use the Node.js entry point and provide a filesystem-accessible WASM path:

import path from "node:path";
import { fileURLToPath } from "node:url";

import { IoCodeModeFactory } from "@interopio/code-mode/node";

const currentDirectory = path.dirname(fileURLToPath(import.meta.url));

const codeMode = await IoCodeModeFactory({
    wasmLocation: path.join(currentDirectory, "quickjs/emscripten-module.wasm"),
});

The host build or deployment must copy the WASM file to the configured location.

Cancellation

Associate an AbortSignal with one run's LLM tools:

const abortController = new AbortController();
const session = codeMode.createSession();
session.setTools(tools);
const toolsForModel = session.getLlmTools({ signal: abortController.signal });

abortController.abort();

After cancellation, Code Mode prevents additional tool calls and settles an in-flight execution with an error result. Cancellation is cooperative: a CPU-bound script inside QuickJS may continue until the configured timeout, but its result is discarded and it cannot dispatch additional host tool calls.


Integration Options

Standalone Integration

Use Code Mode directly when the host application owns the LLM connection and tool-call loop. In this setup, Code Mode acts as a plug-in layer: the host registers its tools with a session, adds the Code Mode system instruction to the model request, and exposes only the returned meta-tools to the model.

import { IoCodeModeFactory } from "@interopio/code-mode/browser";

const codeMode = await IoCodeModeFactory({
    wasmLocation: "/quickjs/emscripten-module.wasm",
    timeout: 30_000,
    memoryLimit: 128,
    overwriteSystemInstruction: (current) => `${current}\nFollow the host application's authorization rules.`,
    toolFilter: (tool) => !tool.name.startsWith("internal."),
    interceptors: {
        onToolCall: async ({ input }) => ({ allowed: true, input }),
    },
});

const session = codeMode.createSession();
const abortController = new AbortController();

session.setTools(hostTools);

const systemInstruction = codeMode.getSystemInstruction();
const metaTools = session.getLlmTools({ signal: abortController.signal });

The host then adapts each returned meta-tool to its model SDK:

  • Use name, description, inputSchema, and outputSchema as the model-visible tool definition.
  • Route model tool calls to the matching meta-tool's execute(args) function.
  • Return the resulting content, structuredContent, and isError through the host's normal tool-result channel.
  • Keep the session alive for the duration of the model run so all three meta-tools use the same tool registry and cancellation signal.

For Node.js hosts, import IoCodeModeFactory from @interopio/code-mode/node and provide a filesystem path in wasmLocation. Standalone integration does not require @interopio/ai-web, @interopio/mcp-core, or an io.Connect environment.

With @interopio/ai-web

Configure Code Mode at the AI Web client layer to virtualize the combined tools received from connected MCP servers:

import { IoAiWebFactory } from "@interopio/ai-web";
import { IoCodeModeFactory } from "@interopio/code-mode/browser";

const aiWeb = await IoAiWebFactory(io, {
    agentServer: {
        baseUrl: "https://agent.example.com",
    },
    codeMode: {
        factory: IoCodeModeFactory,
        config: {
            wasmLocation: "/quickjs/emscripten-module.wasm",
        },
    },
});

AI Web creates a session for each agent stream and declares the experimental codeMode capability to connected MCP servers.

With @interopio/mcp-core

Configure Code Mode on the MCP server to virtualize non-UI tools for clients that do not provide their own Code Mode implementation:

import { IoCodeModeFactory } from "@interopio/code-mode/node";
import { IoIntelMCPCoreFactory } from "@interopio/mcp-core";

const mcpCore = await IoIntelMCPCoreFactory(io, {
    licenseKey,
    transport: { type: "http" },
    server: {
        name: "io-intelligence-mcp",
        codeMode: {
            factory: IoCodeModeFactory,
            config: {
                wasmLocation: quickJsWasmPath,
            },
        },
    },
});

MCP Apps tools with UI resources remain directly registered because a sandboxed script cannot render their UI. If an MCP client declares capabilities.experimental.codeMode, MCP Core serves the plain tool list for that client so the layer closest to the LLM performs virtualization.

Transport packages such as @interopio/mcp-http and @interopio/mcp-web expose this configuration through their mcpCoreServer setting.


Security and Runtime Behavior

  • Model-generated code executes in QuickJS rather than the host JavaScript context.
  • Sandbox code can access only the functions explicitly registered by the host.
  • All tool arguments and results cross the boundary as JSON-compatible values.
  • Tool interceptors are the central place for authorization, approval, argument rewriting, and rate limits.
  • toolFilter and enabled: false remove tools from discovery and execution.
  • Timeout and memory limits constrain each sandbox execution.
  • Code Mode does not make external tools safe automatically; the host must still validate inputs and protect side-effecting operations.
  • A session should not be reused across concurrent requests.

Development

# Build browser and Node.js bundles
npm run build

# Run browser smoke tests
npm run smoke:browser

# Run Node.js smoke tests
npm run smoke

# Run the repeated Node.js stress scenario
npm run stress

# Check lint rules
npm run lint

# Apply automatic lint fixes
npm run lint:fix

The package's public TypeScript contract is defined in code-mode.d.ts.