|
1 | 1 | # @execbox/core |
2 | 2 |
|
3 | | -Executor-agnostic core for guest JavaScript that can call host tools directly or wrap MCP servers and clients into callable namespaces. |
| 3 | +Core execution contract for execbox. Use it to resolve host tools into callable guest namespaces, validate tool boundaries, and bridge MCP servers or clients into the same execution model. |
4 | 4 |
|
5 | 5 | [](https://www.npmjs.com/package/@execbox/core) |
6 | 6 | [](https://github.com/aallam/execbox/blob/main/LICENSE) |
| 7 | +[](https://execbox.aallam.com) |
7 | 8 |
|
8 | | -Docs: https://execbox.aallam.com |
| 9 | +## Use `@execbox/core` When |
9 | 10 |
|
10 | | -## What You Get |
11 | | - |
12 | | -- Resolve host tools into deterministic guest namespaces with name sanitization. |
13 | | -- Validate tool inputs and outputs with JSON Schema, full Zod schemas, or MCP SDK-style raw Zod shapes. |
14 | | -- Normalize user code before execution and generate namespace typings from resolved schemas. |
15 | | -- Wrap MCP servers or clients into execbox providers, or expose code-execution tools from an MCP server. |
| 11 | +- you want to expose host capabilities to guest code through explicit tool providers |
| 12 | +- you want one execution contract across QuickJS, remote, or `isolated-vm` runtimes |
| 13 | +- you want to wrap MCP servers or clients into callable namespaces instead of exposing raw tool loops |
16 | 14 |
|
17 | 15 | ## Pair It With an Executor |
18 | 16 |
|
19 | | -`@execbox/core` does not execute code on its own. Pair it with an executor backend: |
20 | | - |
21 | | -| Package | Best for | |
22 | | -| ---------------------------------------------------------------------------- | --------------------------------------------------------------------------- | |
23 | | -| [`@execbox/quickjs`](https://www.npmjs.com/package/@execbox/quickjs) | Easiest setup, no native addon, with inline, worker, and process host modes | |
24 | | -| [`@execbox/remote`](https://www.npmjs.com/package/@execbox/remote) | Same executor API, but with a caller-supplied remote boundary | |
25 | | -| [`@execbox/isolated-vm`](https://www.npmjs.com/package/@execbox/isolated-vm) | Native `isolated-vm` backend when you specifically want that runtime | |
26 | | - |
27 | | -## Examples |
| 17 | +`@execbox/core` defines the provider and tool boundary, but it does not execute guest code on its own. |
28 | 18 |
|
29 | | -- [Basic provider execution](https://github.com/aallam/execbox/blob/main/examples/execbox-basic.ts) |
30 | | -- [Process-backed provider execution](https://github.com/aallam/execbox/blob/main/examples/execbox-process.ts) |
31 | | -- [Remote provider execution](https://github.com/aallam/execbox/blob/main/examples/execbox-remote.ts) |
32 | | -- [Worker-backed provider execution](https://github.com/aallam/execbox/blob/main/examples/execbox-worker.ts) |
33 | | -- [Wrap MCP tools into a provider](https://github.com/aallam/execbox/blob/main/examples/execbox-mcp-provider.ts) |
34 | | -- [Expose MCP code-execution tools from a server](https://github.com/aallam/execbox/blob/main/examples/execbox-mcp-server.ts) |
35 | | -- [Run the same flow on `isolated-vm`](https://github.com/aallam/execbox/blob/main/examples/execbox-isolated-vm-basic.ts) |
36 | | -- [Full examples index](https://github.com/aallam/execbox/tree/main/examples) |
| 19 | +| Package | Start here when | |
| 20 | +| ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | |
| 21 | +| [`@execbox/quickjs`](https://www.npmjs.com/package/@execbox/quickjs) | You want the default path with inline, worker, or process-hosted QuickJS. | |
| 22 | +| [`@execbox/remote`](https://www.npmjs.com/package/@execbox/remote) | Your runtime already lives behind an application-owned transport boundary. | |
| 23 | +| [`@execbox/isolated-vm`](https://www.npmjs.com/package/@execbox/isolated-vm) | You explicitly want the `isolated-vm` runtime and can support its constraints. | |
37 | 24 |
|
38 | 25 | ## Install |
39 | 26 |
|
| 27 | +Most users start with QuickJS: |
| 28 | + |
40 | 29 | ```bash |
41 | 30 | npm install @execbox/core @execbox/quickjs |
42 | 31 | ``` |
43 | 32 |
|
44 | | -Swap in `@execbox/isolated-vm` when you want the native executor instead. |
45 | | -Set `host: "process"` on `QuickJsExecutor` when you want the QuickJS runtime to live in a fresh child process. |
46 | | -Set `host: "worker"` on `QuickJsExecutor` when you want QuickJS off the main thread with pooled worker shells. |
47 | | -Swap in `@execbox/remote` when you want the same API but a caller-managed remote transport boundary. |
48 | | - |
49 | | -## Security Posture |
50 | | - |
51 | | -- Execbox gives you fresh execution state, JSON-only tool boundaries, schema validation, timeout handling, memory limits, and bounded logs. |
52 | | -- Hard isolation depends on the executor and deployment boundary you pair with `@execbox/core`. |
53 | | -- Providers are explicit capability grants. Every tool you expose is authority you are handing to guest code. |
54 | | -- In the default deployment model, provider and MCP tool definitions are controlled by the application, not by the end user. |
55 | | -- Third-party MCP integrations should be reviewed as dependency-trust decisions, not folded into the primary end-user attacker model. |
56 | | -- If the code source is hostile, prefer stronger isolation such as `QuickJsExecutor` with `host: "process"`, `@execbox/remote`, a container, or a VM. |
57 | | - |
58 | | -## Architecture Docs |
59 | | - |
60 | | -- [Execbox architecture overview](https://github.com/aallam/execbox/blob/main/docs/architecture/README.md) |
61 | | -- [Execbox core architecture](https://github.com/aallam/execbox/blob/main/docs/architecture/execbox-core.md) |
62 | | -- [Execbox executors](https://github.com/aallam/execbox/blob/main/docs/architecture/execbox-executors.md) |
63 | | -- [Execbox MCP adapters and protocol](https://github.com/aallam/execbox/blob/main/docs/architecture/execbox-mcp-and-protocol.md) |
64 | | - |
65 | | -## Exports |
66 | | - |
67 | | -- `@execbox/core` |
68 | | - - `ExecutionOptions` |
69 | | - - `resolveProvider` |
70 | | - - `normalizeCode` |
71 | | - - `sanitizeToolName` |
72 | | - - `extractProviderManifests` |
73 | | - - `createToolCallDispatcher` |
74 | | - - JSON Schema type generation and executor/result types |
75 | | -- `@execbox/core/mcp` |
76 | | - - `createMcpToolProvider` |
77 | | - - `openMcpToolProvider` |
78 | | - - `getMcpToolSourceServerInfo` |
79 | | - - `McpToolClientSource` |
80 | | - - `McpToolServerSource` |
81 | | - - `codeMcpServer` |
82 | | - |
83 | | -## Basic Usage |
| 33 | +Swap in `@execbox/remote` or `@execbox/isolated-vm` when you need a different runtime boundary. |
| 34 | + |
| 35 | +## Smallest Working Usage |
84 | 36 |
|
85 | 37 | ```ts |
86 | 38 | import { resolveProvider } from "@execbox/core"; |
87 | 39 | import { QuickJsExecutor } from "@execbox/quickjs"; |
88 | | -import * as z from "zod"; |
89 | 40 |
|
90 | 41 | const provider = resolveProvider({ |
91 | 42 | name: "tools", |
92 | 43 | tools: { |
93 | | - add: { |
94 | | - inputSchema: z.object({ |
95 | | - x: z.number(), |
96 | | - y: z.number(), |
97 | | - }), |
98 | | - execute: async (input) => { |
99 | | - const { x, y } = input as { x: number; y: number }; |
100 | | - return { sum: x + y }; |
| 44 | + greet: { |
| 45 | + inputSchema: { |
| 46 | + type: "object", |
| 47 | + required: ["name"], |
| 48 | + properties: { |
| 49 | + name: { type: "string" }, |
| 50 | + }, |
101 | 51 | }, |
| 52 | + execute: async (input) => ({ |
| 53 | + message: `Hello, ${(input as { name: string }).name}!`, |
| 54 | + }), |
102 | 55 | }, |
103 | 56 | }, |
104 | 57 | }); |
105 | 58 |
|
106 | 59 | const executor = new QuickJsExecutor(); |
107 | | -const result = await executor.execute( |
108 | | - "await tools.add({ x: 2, y: 5 })", |
109 | | - [provider], |
110 | | - { timeoutMs: 250 }, |
111 | | -); |
| 60 | +const result = await executor.execute(`await tools.greet({ name: "World" })`, [ |
| 61 | + provider, |
| 62 | +]); |
| 63 | + |
| 64 | +console.log(result); |
112 | 65 | ``` |
113 | 66 |
|
114 | | -## MCP Adapters |
| 67 | +## MCP Support |
| 68 | + |
| 69 | +Use `@execbox/core/mcp` when you want MCP on either side of the boundary: |
| 70 | + |
| 71 | +- wrap an upstream MCP server or client into a provider with `createMcpToolProvider()` or `openMcpToolProvider()` |
| 72 | +- expose execbox code execution back out through an MCP server with `codeMcpServer()` |
| 73 | +- preserve raw MCP `CallToolResult` envelopes so guest code can inspect `structuredContent` first and fall back to `content` |
| 74 | + |
| 75 | +## Operational Notes |
| 76 | + |
| 77 | +- Providers are the capability boundary. If guest code can call a tool, it can exercise that authority. |
| 78 | +- Execbox gives you JSON-only tool/result boundaries, schema validation, bounded logs, and timeout-aware execution controls. |
| 79 | +- Hard isolation depends on the executor and deployment boundary you choose, not on `@execbox/core` by itself. |
115 | 80 |
|
116 | | -Use `@execbox/core/mcp` when you want to wrap an MCP server or client into a tool provider, or expose code-execution tools from an MCP server. Wrapped tools preserve raw MCP `CallToolResult` envelopes so guest code can inspect `structuredContent` first and fall back to `content`. |
| 81 | +## Read Next |
117 | 82 |
|
118 | | -- `createMcpToolProvider({ client })` is the convenience API when the caller already owns the upstream MCP client lifecycle. |
119 | | -- `openMcpToolProvider({ server | client })` returns an `McpToolProviderHandle` and is the required API when execbox owns a local `{ server }` connection. |
120 | | -- `codeMcpServer()` owns any local wrapper connection it opens and releases it when the wrapper server closes. |
| 83 | +- [Getting Started](https://execbox.aallam.com/getting-started) |
| 84 | +- [Examples](https://execbox.aallam.com/examples) |
| 85 | +- [Security & Boundaries](https://execbox.aallam.com/security) |
| 86 | +- [Architecture Overview](https://execbox.aallam.com/architecture/) |
| 87 | +- [Core Architecture](https://execbox.aallam.com/architecture/execbox-core) |
| 88 | +- [MCP And Protocol](https://execbox.aallam.com/architecture/execbox-mcp-and-protocol) |
0 commit comments