Skip to content

Commit cb2db54

Browse files
authored
feat(docs): add public docs site (#11)
1 parent 1a11ede commit cb2db54

22 files changed

Lines changed: 6170 additions & 2503 deletions

File tree

.github/workflows/ci.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,21 @@ jobs:
7272

7373
- name: Run isolated-vm security lane
7474
run: npm run test:isolated-vm
75+
76+
docs:
77+
runs-on: ubuntu-latest
78+
79+
steps:
80+
- uses: actions/checkout@v4
81+
82+
- name: Use Node.js 24
83+
uses: actions/setup-node@v4
84+
with:
85+
node-version: 24
86+
cache: npm
87+
88+
- name: Install dependencies
89+
run: npm ci
90+
91+
- name: Build docs
92+
run: npm run docs:build

.github/workflows/deploy-docs.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Deploy Docs
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: docs-pages
15+
cancel-in-progress: true
16+
17+
jobs:
18+
build-and-deploy:
19+
runs-on: ubuntu-latest
20+
environment:
21+
name: github-pages
22+
url: ${{ steps.deployment.outputs.page_url }}
23+
24+
steps:
25+
- uses: actions/checkout@v4
26+
27+
- name: Use Node.js 24
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: 24
31+
cache: npm
32+
33+
- name: Install dependencies
34+
run: npm ci
35+
36+
- name: Build docs
37+
run: npm run docs:build
38+
39+
- uses: actions/configure-pages@v4
40+
41+
- uses: actions/upload-pages-artifact@v3
42+
with:
43+
path: docs/.vitepress/dist
44+
45+
- id: deployment
46+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
.worktrees/
22
node_modules/
33
dist/
4+
docs/.vitepress/cache/
5+
docs/.vitepress/dist/
46
packages/*/dist/
57
coverage/
68
*.tsbuildinfo

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
Secure code execution for [Model Context Protocol](https://modelcontextprotocol.io/) tools and wrapped MCP servers.
66

77
[![License](https://img.shields.io/github/license/aallam/execbox?style=flat-square)](https://github.com/aallam/execbox/blob/main/LICENSE)
8+
[![Docs](https://img.shields.io/badge/docs-execbox.aallam.com-0ea5e9?style=flat-square)](https://execbox.aallam.com)
89
[![Packages](https://img.shields.io/badge/packages-7-111827?style=flat-square)](#package-map)
910

1011
</div>
@@ -29,5 +30,6 @@ Runnable examples live in [`examples/`](./examples/) and are indexed in [`exampl
2930

3031
## Docs
3132

33+
- [Public Docs](https://execbox.aallam.com)
3234
- [Execbox Architecture Overview](./docs/architecture/README.md)
3335
- [QuickJS Pooling Baseline](./docs/performance/quickjs-pooling-baseline.md)

docs/.vitepress/config.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { defineConfig } from "vitepress";
2+
import { withMermaid } from "vitepress-plugin-mermaid";
3+
4+
export default withMermaid(
5+
defineConfig({
6+
title: "execbox",
7+
description:
8+
"Portable code execution for MCP tools and wrapped MCP servers.",
9+
base: "/",
10+
cleanUrls: true,
11+
lastUpdated: true,
12+
mermaid: {
13+
securityLevel: "loose",
14+
},
15+
themeConfig: {
16+
footer: {
17+
copyright: "Copyright © 2026 Mouaad Aallam",
18+
message: "Released under the MIT License.",
19+
},
20+
nav: [
21+
{ link: "/getting-started", text: "Getting Started" },
22+
{ link: "/examples", text: "Examples" },
23+
{ link: "/architecture/", text: "Architecture" },
24+
{ link: "/security", text: "Security" },
25+
],
26+
search: {
27+
provider: "local",
28+
},
29+
sidebar: {
30+
"/architecture/": [
31+
{
32+
items: [
33+
{ link: "/architecture/", text: "Overview" },
34+
{ link: "/architecture/execbox-core", text: "Core" },
35+
{ link: "/architecture/execbox-executors", text: "Executors" },
36+
{
37+
link: "/architecture/execbox-mcp-and-protocol",
38+
text: "MCP And Protocol",
39+
},
40+
{
41+
link: "/architecture/execbox-remote-workflow",
42+
text: "Remote Workflow",
43+
},
44+
{
45+
link: "/architecture/execbox-protocol-reference",
46+
text: "Protocol Reference",
47+
},
48+
{
49+
link: "/architecture/execbox-runner-specification",
50+
text: "Runner Specification",
51+
},
52+
],
53+
text: "Architecture",
54+
},
55+
],
56+
},
57+
socialLinks: [
58+
{ icon: "github", link: "https://github.com/aallam/execbox" },
59+
],
60+
siteTitle: "execbox",
61+
},
62+
}),
63+
);

docs/.vitepress/theme/custom.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
:root {
2+
--vp-c-brand-1: #0f766e;
3+
--vp-c-brand-2: #0d9488;
4+
--vp-c-brand-3: #14b8a6;
5+
--vp-c-brand-soft: rgba(20, 184, 166, 0.14);
6+
}
7+
8+
.VPHomeHero .name {
9+
max-width: 12ch;
10+
}

docs/.vitepress/theme/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import DefaultTheme from "vitepress/theme";
2+
3+
import "./custom.css";
4+
5+
export default DefaultTheme;

docs/architecture/index.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Execbox Architecture Overview
2+
3+
Execbox is the code-execution part of the `execbox` workspace. It turns host tool catalogs into callable guest namespaces, lets those namespaces wrap MCP tools, and pairs with executor packages that decide where and how guest JavaScript runs.
4+
5+
This doc set is for two audiences:
6+
7+
- integrators choosing packages and deployment shapes
8+
- contributors reasoning about package boundaries, control flow, and trade-offs
9+
10+
## Reading guide
11+
12+
- Start here for the package map, trust model, and overall flow.
13+
- Read [Core](/architecture/execbox-core) for provider resolution, execution contracts, and error handling.
14+
- Read [Executors](/architecture/execbox-executors) for QuickJS, process, worker-thread, and `isolated-vm` trade-offs.
15+
- Read [MCP And Protocol](/architecture/execbox-mcp-and-protocol) for MCP wrapping and where `execbox-protocol` fits.
16+
- Read [Remote Workflow](/architecture/execbox-remote-workflow) for the end-to-end remote execution control flow.
17+
- Read [Protocol Reference](/architecture/execbox-protocol-reference) for the protocol message catalog and session rules.
18+
- Read [Runner Specification](/architecture/execbox-runner-specification) for the normative runner specification for non-TypeScript runners.
19+
20+
## Package map
21+
22+
```mermaid
23+
flowchart LR
24+
APP["Host application"]
25+
CORE["@execbox/core<br/>provider resolution + runner semantics + MCP adapters"]
26+
QJS["@execbox/quickjs<br/>in-process QuickJS executor + reusable runner"]
27+
REM["@execbox/remote<br/>transport-backed remote executor"]
28+
PROC["@execbox/process<br/>child-process QuickJS executor"]
29+
IVM["@execbox/isolated-vm<br/>in-process isolated-vm executor + reusable runner"]
30+
PROTO["@execbox/protocol<br/>transport messages + shared host session"]
31+
WORKER["@execbox/worker<br/>worker-thread QuickJS executor"]
32+
MCP["MCP sources and wrapped servers"]
33+
34+
APP --> CORE
35+
APP --> QJS
36+
APP --> REM
37+
APP --> PROC
38+
APP --> IVM
39+
APP --> WORKER
40+
CORE --> MCP
41+
REM --> PROTO
42+
PROC --> PROTO
43+
WORKER --> PROTO
44+
PROC --> QJS
45+
WORKER --> QJS
46+
```
47+
48+
## End-to-end execution model
49+
50+
At a high level, execbox always follows the same model:
51+
52+
1. Host code defines or discovers tools.
53+
2. `@execbox/core` resolves those tools into a deterministic guest namespace.
54+
3. An executor runs guest JavaScript against that resolved namespace.
55+
4. Guest tool calls cross a host-controlled boundary and return structured JSON-compatible results.
56+
57+
## Trust model and security posture
58+
59+
Execbox reduces accidental exposure, but it does not claim a hard security boundary for hostile code in its default deployment model.
60+
61+
Key implications:
62+
63+
- The real capability boundary is the provider/tool surface, not the JavaScript syntax itself.
64+
- Fresh runtimes, schema validation, JSON-only boundaries, timeouts, memory limits, and bounded logs are defense-in-depth features.
65+
- In-process execution still shares the host process. Use a separate process, container, VM, or similar boundary when the code source is hostile or multi-tenant.
66+
- Wrapping third-party MCP servers is a separate dependency-trust decision from letting end users author guest code.

docs/examples.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Examples
2+
3+
Use the examples when you want a runnable starting point rather than package-by-package reference material.
4+
5+
## Run everything
6+
7+
```bash
8+
npm install
9+
npm run build
10+
npm run examples
11+
```
12+
13+
## Example index
14+
15+
| Example | What it shows | When to start here |
16+
| --- | --- | --- |
17+
| [`execbox-basic.ts`](https://github.com/aallam/execbox/blob/main/examples/execbox-basic.ts) | Resolve a provider and execute guest code with QuickJS. | You want the smallest end-to-end example. |
18+
| [`execbox-process.ts`](https://github.com/aallam/execbox/blob/main/examples/execbox-process.ts) | Run the same provider flow inside a child-process executor. | You want a stronger lifecycle boundary than in-process execution. |
19+
| [`execbox-worker.ts`](https://github.com/aallam/execbox/blob/main/examples/execbox-worker.ts) | Run the same provider flow inside a worker-thread executor. | You want QuickJS off the main thread. |
20+
| [`execbox-remote.ts`](https://github.com/aallam/execbox/blob/main/examples/execbox-remote.ts) | Run the same provider flow through a transport-backed executor. | You already own the remote boundary and want execbox to plug into it. |
21+
| [`execbox-mcp-provider.ts`](https://github.com/aallam/execbox/blob/main/examples/execbox-mcp-provider.ts) | Wrap MCP tools into a provider and execute against them. | You want guest code to call upstream MCP tools as code. |
22+
| [`execbox-mcp-server.ts`](https://github.com/aallam/execbox/blob/main/examples/execbox-mcp-server.ts) | Expose `mcp_search_tools`, `mcp_execute_code`, and `mcp_code`. | You want downstream MCP clients to execute code against a wrapped tool namespace. |
23+
| [`execbox-isolated-vm-basic.ts`](https://github.com/aallam/execbox/blob/main/examples/execbox-isolated-vm-basic.ts) | Run the same provider flow on the `isolated-vm` backend. | You explicitly want the `isolated-vm` runtime. |
24+
25+
## What to read next
26+
27+
- [Getting Started](/getting-started) for the minimal QuickJS install path
28+
- [Architecture](/architecture/) for how providers, executors, and protocol layers fit together
29+
- [Security](/security) before choosing a production boundary

docs/getting-started.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Getting Started
2+
3+
Execbox works best when you start small: define one provider, run one snippet, then choose a stronger boundary only when your deployment needs it.
4+
5+
## Requirements
6+
7+
- Node.js 22+
8+
- npm
9+
10+
## Install
11+
12+
```bash
13+
npm install @execbox/core @execbox/quickjs
14+
```
15+
16+
## Smallest working example
17+
18+
```ts
19+
import { resolveProvider } from "@execbox/core";
20+
import { QuickJsExecutor } from "@execbox/quickjs";
21+
22+
const provider = resolveProvider({
23+
name: "tools",
24+
tools: {
25+
greet: {
26+
inputSchema: {
27+
type: "object",
28+
required: ["name"],
29+
properties: {
30+
name: { type: "string" },
31+
},
32+
},
33+
execute: async (input) => `Hello, ${(input as { name: string }).name}!`,
34+
},
35+
},
36+
});
37+
38+
const executor = new QuickJsExecutor();
39+
const result = await executor.execute(
40+
`await tools.greet({ name: "World" })`,
41+
[provider],
42+
);
43+
44+
console.log(result);
45+
```
46+
47+
## Which package should I use?
48+
49+
- Use `@execbox/quickjs` first unless you already know you need a stronger boundary.
50+
- Use `@execbox/process` when you want QuickJS semantics in a separate child process.
51+
- Use `@execbox/worker` when you want QuickJS off the main thread with pooled workers.
52+
- Use `@execbox/remote` when your runtime already lives behind an application-owned transport.
53+
- Use `@execbox/isolated-vm` only when you explicitly want that runtime and can support `--no-node-snapshot`.
54+
55+
## Run the examples
56+
57+
The repo includes runnable examples for each main deployment shape:
58+
59+
```bash
60+
npm install
61+
npm run build
62+
npm run examples
63+
```
64+
65+
For the isolated-vm lane:
66+
67+
```bash
68+
npm run example:execbox-isolated-vm
69+
npm run verify:isolated-vm
70+
```
71+
72+
Next:
73+
74+
- [Examples](/examples) for runnable flows
75+
- [Architecture](/architecture/) for the deeper technical model
76+
- [Security](/security) before choosing a production boundary

0 commit comments

Comments
 (0)