Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/docs/content/1.getting-started/2.installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ This will give you access to prompts like `setup-mcp-server`, `create-tool`, `cr
- Node.js 18.x or higher
- A package manager (npm, pnpm, yarn, or bun)

If you enable Code Mode, that feature specifically requires Node.js `>=18.16.0`.

## Installation

::steps
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/content/2.core-concepts/5.handlers.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ export default defineMcpHandler({
})
```

Code Mode requires `secure-exec` and Node.js `>=18.16.0`.

::callout{icon="i-lucide-book-open" color="primary"}
See the [Code Mode guide](/advanced/code-mode) for full documentation, security details, and configuration options.
::
Expand Down
40 changes: 40 additions & 0 deletions apps/docs/content/3.advanced/8.code-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ bun add secure-exec

::

::callout{icon="i-lucide-info" color="info"}
Code Mode requires `secure-exec` and Node.js `>=18.16.0`. The rest of the module still supports Node.js 18.x, but code mode depends on `AsyncLocalStorage.snapshot()` to preserve request context.
::

### 2. Enable on a handler

Add `experimental_codeMode` to any handler:
Expand Down Expand Up @@ -194,6 +198,10 @@ export default defineMcpHandler({
memoryLimit: 64,
cpuTimeLimitMs: 10_000,
maxResultSize: 102_400,
maxRequestBodyBytes: 1_048_576,
maxToolResponseSize: 1_048_576,
wallTimeLimitMs: 60_000,
maxToolCalls: 200,
progressive: false,
description: undefined,
},
Expand All @@ -219,6 +227,30 @@ export default defineMcpHandler({
Maximum result size in bytes before truncation. Large results are intelligently truncated — arrays by number of items, objects by number of keys.
::

::field{name="maxRequestBodyBytes" type="number"}
Default: `1048576` (1 MB)

Maximum bytes accepted in a single RPC request body from the sandbox. Returns HTTP 413 if exceeded. Prevents memory exhaustion from oversized payloads. Like `memoryLimit`, this applies when the RPC server **first** starts; call `disposeCodeMode()` before changing it.
::

::field{name="maxToolResponseSize" type="number"}
Default: `1048576` (1 MB)

Maximum bytes for individual tool RPC responses. Large results are truncated using the same strategy as `maxResultSize`.
::

::field{name="wallTimeLimitMs" type="number"}
Default: `60000` (60 seconds)

Per-execution deadline checked at the **start of each** sandbox→host RPC call (tool invocation or return value). After the deadline, the next RPC receives HTTP 408. This bounds host-side work (e.g. slow tools); pure CPU loops in the isolate are primarily limited by `cpuTimeLimitMs`.
::

::field{name="maxToolCalls" type="number"}
Default: `200`

Maximum number of tool RPC calls per execution. Prevents runaway loops that repeatedly invoke expensive tools. Returns HTTP 429 when exceeded.
::

::field{name="progressive" type="boolean"}
Default: `false`

Expand Down Expand Up @@ -328,8 +360,12 @@ This prevents other local processes from calling your MCP tools through the RPC
| Resource | Default | Configurable | Protection |
|----------|---------|-------------|------------|
| **CPU time** | 10 seconds | `cpuTimeLimitMs` | Sandbox is killed on timeout — prevents infinite loops |
| **Wall-clock deadline** | 60 seconds | `wallTimeLimitMs` | Enforced on each RPC from the sandbox — stops further tool/return RPCs after the deadline |
| **Memory** | 64 MB | `memoryLimit` | V8 isolate hard limit — prevents OOM crashes |
| **Result size** | 100 KB | `maxResultSize` | Intelligent truncation (arrays by items, objects by keys) |
| **Tool response size** | 1 MB | `maxToolResponseSize` | Per-call truncation before response delivery |
| **Request body size** | 1 MB | `maxRequestBodyBytes` | HTTP 413 early rejection — prevents memory exhaustion |
| **Tool calls per execution** | 200 | `maxToolCalls` | HTTP 429 rate limit — prevents runaway loops |
| **Log entries** | 200 | No | Console output capped — prevents `console.log` flooding |

### Input Validation
Expand All @@ -340,6 +376,10 @@ Tool names are interpolated into the sandbox code template. To prevent code inje
- **Sanitization** — Names are sanitized upstream (`get-user` → `get_user`), but a second validation layer at the template level ensures defense in depth.
- **Rejection** — If a name fails validation, the execution throws immediately — no partial injection.

### Error Sanitization

Infrastructure errors (file paths, stack traces) are sanitized before being returned to the sandbox or the MCP client. Full error details are logged server-side with the `[nuxt-mcp-toolkit]` prefix for debugging.

### Summary

::callout{icon="i-lucide-shield" color="info"}
Expand Down
Loading
Loading