Skip to content

Commit 9f7fe2e

Browse files
Dumbrisclaude
andauthored
feat(config): enable the code_execution tool by default (#1264)
* feat(config): enable the code_execution tool by default The sandboxed JavaScript/TypeScript tool ships on from v0.66.0. New installs get "enable_code_execution": true; a config file that omits the key inherits it, and an explicit false in the file still wins (default-then-merge), so existing installs keep whatever they have. Surface tests measured against the frozen flag-off capture now treat code_execution as an enumerated addition on default_server and a stub-to-live modification on the two routing-mode surfaces, pinned field by field. Docs, Settings help text and the security-posture pill (an enabled sandbox is no longer flagged "review this") follow. Adds .github/RELEASE_NOTICE.md for v0.66.0: the default flip, the scope-hardening fixes, Windows process cleanup and the stale-OAuth health fix. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(code_execution): interrupt timed-out scripts and sanitise sub-call output Two gaps the cross-model review found on the way to shipping the tool on by default. A script that overran its timeout was reported as TIMEOUT to the caller and then abandoned: nothing interrupted the goja VM, so a busy loop kept a core for the life of the process, and the pool slot it held was released the moment the handler returned. Execute now calls vm.Interrupt on the deadline, and the lone call_tool() dispatches under the execution's timeout context like call_tools() batches already did, so an upstream call in flight when the script is cut off is cancelled with it. The script bridge returned client.CallTool's result raw, so an operator's output_sanitisation redact/block policy — enforced on every call_tool_* dispatch — did not reach JavaScript, where a script can read the secret, forward it to another upstream, or return it. Sub-call results now go through the same applyOutputSanitisation seam before they are recorded, stored or handed to the script; a blocked response surfaces as a failed call. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(code_execution): recover interrupt panics during export; one correlation id per sub-call Cross-model review round 2/3 on the timeout and sanitisation seams: - An interrupt that lands while value.Export() is still running script code (a getter on the returned object) is raised by goja as a panic, not a RunString error; unrecovered in the script goroutine it took the process down. executeWithVM now recovers *goja.InterruptedError into a TIMEOUT result. - The sub-call bridge minted its correlation id twice (sanitisation and activity), and mintCorrelationIDAt bumps a sequence per call, so the policy decision could never be joined to its activity record. One id is minted at the top of CallTool and threaded through. - contentTrust for a sub-call is derived through ContentTrustForTool unconditionally, as handleCallToolVariant does: a tool with no annotations is open-world, hence untrusted, so strip mode reaches it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent 9c247df commit 9f7fe2e

26 files changed

Lines changed: 554 additions & 91 deletions

‎.github/RELEASE_NOTICE.md‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
## ⚡ `code_execution` is now on by default
2+
3+
The sandboxed JavaScript/TypeScript `code_execution` tool — one request that orchestrates several upstream tool calls, with loops, conditionals and data transformation in between — ships **enabled** starting with this release. Previously it had to be switched on by hand.
4+
5+
**What changes for you**
6+
7+
- **New installs** get `"enable_code_execution": true` in `mcp_config.json` and see the tool in `tools/list` on the default `/mcp` endpoint.
8+
- **Existing installs: an explicit value in the file wins.** mcpproxy writes every setting when it saves the config, so a `mcp_config.json` created by an earlier release carries `"enable_code_execution": false` and stays off. To get the tool, flip it to `true` in the file or in **Settings → Enable code execution tool** — the change is hot-reloaded and connected clients receive `notifications/tools/list_changed`, no restart needed.
9+
- **A hand-written config that omits the key turns the tool on** at the next start or hot reload. If you maintain the file yourself and want it off, add `"enable_code_execution": false` before upgrading.
10+
- **To keep it off**, set `"enable_code_execution": false`. As of this release a disabled tool is no longer advertised at all ([#1236](https://github.com/smart-mcp-proxy/mcpproxy-go/issues/1236)): it disappears from `tools/list` instead of being listed as a stub that refuses every call.
11+
12+
The sandbox has no filesystem, network or `require()`. `call_tool` from inside a script goes through the same gates as a direct `call_tool_*` request — quarantine, agent-token scope, per-server restrictions and, as of this release, `output_sanitisation` redact/block — and each run is bounded by `code_execution_timeout_ms` (default 2 min; a script that overruns is now interrupted, not just abandoned) and `code_execution_max_tool_calls`. Details: [docs/features/code-execution](https://docs.mcpproxy.app/features/code-execution/).
13+
14+
## 🔒 Agent-token scope hardening
15+
16+
Five fixes close the places where an agent token restricted to a subset of servers could still learn about, or act on, servers outside its grant: `call_tool_*` now requires the target tool's tier and fails closed on an unresolved one ([#1223](https://github.com/smart-mcp-proxy/mcpproxy-go/pull/1223)); `upstream_servers` `tail_log` ([#1224](https://github.com/smart-mcp-proxy/mcpproxy-go/pull/1224)), `set_profile` responses ([#1225](https://github.com/smart-mcp-proxy/mcpproxy-go/pull/1225)), `read_cache` entries ([#1226](https://github.com/smart-mcp-proxy/mcpproxy-go/pull/1226)) and aggregated prompts ([#1227](https://github.com/smart-mcp-proxy/mcpproxy-go/pull/1227)) are all scoped to the calling token. No configuration change is needed; if you hand out scoped agent tokens (`mcpproxy token create --servers …`), upgrade.
17+
18+
The registry SSRF guard now also unwraps IPv6 transition addresses (6to4, NAT64, Teredo, IPv4-compatible) and blocks the embedded IPv4 when it is private or link-local ([#1235](https://github.com/smart-mcp-proxy/mcpproxy-go/pull/1235), thanks @aroh3006).
19+
20+
## 🪟 Windows: stdio servers no longer leak child processes
21+
22+
Restarting, reconnecting or disconnecting a stdio server on Windows used to leave its `node.exe` / `python.exe` grandchildren running forever (one report counted 413 orphans after an hour). Every spawned server is now wrapped in a Job Object that is closed on every disconnect and stop path, so the whole tree goes with it ([#1234](https://github.com/smart-mcp-proxy/mcpproxy-go/pull/1234), thanks @LocoLoboZ; [#1260](https://github.com/smart-mcp-proxy/mcpproxy-go/pull/1260)). If you have orphans from earlier builds, end them once by hand — this release cannot reach processes it did not start.
23+
24+
## 🩺 "Token expired" on servers that no longer use OAuth
25+
26+
A server switched from OAuth to a static `Authorization` header stayed `unhealthy / Token expired / action: login` forever, because a stale record in the `oauth_tokens` bucket outranked the current config ([#1172](https://github.com/smart-mcp-proxy/mcpproxy-go/issues/1172)). Such servers now report from their live connection; the dead record is ignored (and `mcpproxy auth logout <server>` still removes it).

‎CLAUDE.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ Env vars: `MCPPROXY_LISTEN`, `MCPPROXY_API_KEY`, `MCPPROXY_DEBUG`, `MCPPROXY_TEL
112112

113113
## MCP Protocol
114114

115-
**Built-in tools**: `retrieve_tools` (BM25 search across upstream tools; Spec 049 opt-in `include_disabled`; Spec 085 `detail` override + compact signatures under `tool_response_mode: compact`) · `describe_tool` (Spec 085: batch ≤5 ids → full schemas; Spec 102: also on the direct surface, `server:tool` or `server__tool` ids) · `call_tool_read|write|destructive` (Spec 018 intent variants; operation type inferred from the variant; Spec 085 pre-dispatch arg validation with self-healing `invalid_params` errors) · `code_execution` (sandboxed JS, off by default) · `upstream_servers` (CRUD, Spec 049) · `quarantine_security` (Spec 032). **Tool format**: `<serverName>:<toolName>` (e.g. `github:create_issue`); the direct surface lists as `<serverName>__<toolName>` and accepts both.
115+
**Built-in tools**: `retrieve_tools` (BM25 search across upstream tools; Spec 049 opt-in `include_disabled`; Spec 085 `detail` override + compact signatures under `tool_response_mode: compact`) · `describe_tool` (Spec 085: batch ≤5 ids → full schemas; Spec 102: also on the direct surface, `server:tool` or `server__tool` ids) · `call_tool_read|write|destructive` (Spec 018 intent variants; operation type inferred from the variant; Spec 085 pre-dispatch arg validation with self-healing `invalid_params` errors) · `code_execution` (sandboxed JS, on by default since v0.66.0) · `upstream_servers` (CRUD, Spec 049) · `quarantine_security` (Spec 032). **Tool format**: `<serverName>:<toolName>` (e.g. `github:create_issue`); the direct surface lists as `<serverName>__<toolName>` and accepts both.
116116

117117
**REST API** base `/api/v1`, auth via `X-API-Key` header or `?apikey=`. MCP endpoints (`/mcp`) stay unprotected for client compatibility; the REST API always requires a key (auto-generated if absent). All responses carry `X-Request-Id` (correlate with `mcpproxy activity list --request-id <id>`). Live updates via SSE at `/events`. Full endpoint list: `oas/swagger.yaml` + [docs/api/rest-api.md](docs/api/rest-api.md).
118118

‎docs/code_execution/api-reference.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ Edit `~/.mcpproxy/mcp_config.json`:
695695

696696
```json
697697
{
698-
"enable_code_execution": false,
698+
"enable_code_execution": true,
699699
"code_execution_timeout_ms": 120000,
700700
"code_execution_max_tool_calls": 0,
701701
"code_execution_pool_size": 10,
@@ -707,7 +707,7 @@ Edit `~/.mcpproxy/mcp_config.json`:
707707

708708
| Field | Type | Default | Description |
709709
|-------|------|---------|-------------|
710-
| `enable_code_execution` | boolean | `false` | Enable/disable code execution feature (must be `true` to use) |
710+
| `enable_code_execution` | boolean | `true` | Enable/disable code execution feature (on by default since v0.66.0) |
711711
| `code_execution_timeout_ms` | number | `120000` | Default timeout in milliseconds (range: 1-600000) |
712712
| `code_execution_max_tool_calls` | number | `0` | Default max tool calls (0 = unlimited) |
713713
| `code_execution_pool_size` | number | `10` | Number of JavaScript VM instances in pool (range: 1-100) |

‎docs/code_execution/overview.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ The JavaScript execution environment is **heavily sandboxed** to prevent securit
174174

175175
```json
176176
{
177-
"enable_code_execution": false, // Must be explicitly enabled (default: false)
177+
"enable_code_execution": true, // On by default since v0.66.0; set false to switch off
178178
"code_execution_timeout_ms": 120000, // Default: 2 minutes, max: 10 minutes
179179
"code_execution_max_tool_calls": 0, // Default: unlimited
180180
"code_execution_pool_size": 10, // Default: 10 concurrent VMs

‎docs/code_execution/troubleshooting.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Common issues, error messages, and solutions for the `code_execution` tool.
3131
Error: code_execution is disabled in configuration. Set 'enable_code_execution: true' in config file.
3232
```
3333

34-
**Cause**: The `code_execution` feature is disabled by default for security. While it is disabled the tool is not listed in `tools/list`, so an MCP client will normally not see it at all; this error appears when a call reaches the handler by name anyway (the REST API or the CLI). An MCP client that calls the name from a stale tool list gets an unknown-tool error instead.
34+
**Cause**: The `code_execution` feature is switched off in this configuration (`"enable_code_execution": false` — it ships on by default since v0.66.0, but a config file written by an earlier release carries an explicit `false`). While it is disabled the tool is not listed in `tools/list`, so an MCP client will normally not see it at all; this error appears when a call reaches the handler by name anyway (the REST API or the CLI). An MCP client that calls the name from a stale tool list gets an unknown-tool error instead.
3535

3636
**Solution**:
3737
1. Edit your configuration file (`~/.mcpproxy/mcp_config.json`)

‎docs/configuration.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,7 +1254,7 @@ See [Tool Quarantine](features/tool-quarantine.md) for complete details.
12541254

12551255
```json
12561256
{
1257-
"enable_code_execution": false,
1257+
"enable_code_execution": true,
12581258
"code_execution_timeout_ms": 120000,
12591259
"code_execution_max_tool_calls": 0,
12601260
"code_execution_pool_size": 10,
@@ -1264,7 +1264,7 @@ See [Tool Quarantine](features/tool-quarantine.md) for complete details.
12641264

12651265
| Field | Type | Default | Description |
12661266
|-------|------|---------|-------------|
1267-
| `enable_code_execution` | boolean | `false` | Enable JavaScript/TypeScript code execution tool (disabled by default for security). While `false` the `code_execution` tool is not advertised in `tools/list`. Hot-reloaded: a flip adds/removes the tool and sends `notifications/tools/list_changed` |
1267+
| `enable_code_execution` | boolean | `true` | Enable JavaScript/TypeScript code execution tool (on by default since v0.66.0; set `false` to switch it off). While `false` the `code_execution` tool is not advertised in `tools/list`. Hot-reloaded: a flip adds/removes the tool and sends `notifications/tools/list_changed` |
12681268
| `code_execution_timeout_ms` | integer | `120000` | Default timeout in milliseconds (1-600000, max 10 minutes) |
12691269
| `code_execution_max_tool_calls` | integer | `0` | Maximum tool calls per execution (0 = unlimited) |
12701270
| `code_execution_pool_size` | integer | `10` | Number of JavaScript VM instances in pool (1-100) |
@@ -1562,7 +1562,7 @@ Here's a complete configuration example with all major sections:
15621562
"enhance_path": false
15631563
},
15641564

1565-
"enable_code_execution": false,
1565+
"enable_code_execution": true,
15661566
"code_execution_timeout_ms": 120000,
15671567
"code_execution_max_tool_calls": 0,
15681568
"code_execution_pool_size": 10,

‎docs/configuration/config-file.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ MCPProxy uses a JSON configuration file located at `~/.mcpproxy/mcp_config.json`
3434
"http_idle_timeout": "180s",
3535
"tools_limit": 15,
3636
"tool_response_limit": 20000,
37-
"enable_code_execution": false,
37+
"enable_code_execution": true,
3838
"code_execution_timeout_ms": 120000,
3939
"code_execution_max_tool_calls": 0,
4040
"code_execution_pool_size": 10,
@@ -136,7 +136,7 @@ Both cadences are configurable globally, and can be overridden per server (see [
136136

137137
| Option | Type | Default | Description |
138138
|--------|------|---------|-------------|
139-
| `enable_code_execution` | boolean | `false` | Enable JavaScript code execution tool |
139+
| `enable_code_execution` | boolean | `true` | Enable JavaScript code execution tool (on by default since v0.66.0) |
140140
| `code_execution_timeout_ms` | integer | `120000` | Execution timeout in milliseconds |
141141
| `code_execution_max_tool_calls` | integer | `0` | Maximum tool calls (0 = unlimited) |
142142
| `code_execution_pool_size` | integer | `10` | VM pool size for code execution |

‎docs/features/code-execution.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Enable code execution in your config:
3737

3838
| Option | Type | Default | Description |
3939
|--------|------|---------|-------------|
40-
| `enable_code_execution` | boolean | `false` | Enable the code execution tool. While `false` the tool is not listed in `tools/list`; a flip is hot-reloaded and announced with `notifications/tools/list_changed` |
40+
| `enable_code_execution` | boolean | `true` | Enable the code execution tool (on by default since v0.66.0). While `false` the tool is not listed in `tools/list`; a flip is hot-reloaded and announced with `notifications/tools/list_changed` |
4141
| `code_execution_timeout_ms` | integer | `120000` | Execution timeout (2 minutes) |
4242
| `code_execution_max_tool_calls` | integer | `0` | Max tool calls (0 = unlimited) |
4343
| `code_execution_pool_size` | integer | `10` | Number of VM instances to pool |

‎docs/features/routing-modes.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ Code execution mode is designed for multi-step orchestration workflows. Instead
165165
- Complex conditional logic that would require many round-trips in other modes
166166
- Data transformation pipelines (fetch from one tool, transform, send to another)
167167

168-
**Note:** Code execution must be enabled in config (`"enable_code_execution": true`). While it is disabled, the `code_execution` tool is not listed in `tools/list` on any endpoint, so clients that pick tools from the list never attempt it. An MCP `tools/call` for the name is refused as an unknown tool; a call that reaches the handler through the REST API or the CLI is refused with an error directing the user to enable it. The flag is hot-reloadable: flipping it adds or removes the tool on the live surfaces and sends `notifications/tools/list_changed` to connected sessions, no restart required.
168+
**Note:** Code execution is on by default since v0.66.0 (`"enable_code_execution": true`); set it to `false` to switch it off. While it is disabled, the `code_execution` tool is not listed in `tools/list` on any endpoint, so clients that pick tools from the list never attempt it. An MCP `tools/call` for the name is refused as an unknown tool; a call that reaches the handler through the REST API or the CLI is refused with an error directing the user to enable it. The flag is hot-reloadable: flipping it adds or removes the tool on the live surfaces and sends `notifications/tools/list_changed` to connected sessions, no restart required.
169169

170170
## Choosing the Right Mode
171171

‎frontend/src/views/Settings.vue‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,9 @@ const posture = computed(() => {
292292
{ label: 'MCP auth', on: !!w.require_mcp_auth, good: !!w.require_mcp_auth },
293293
{ label: 'Docker isolation', on: !!(w.docker_isolation && w.docker_isolation.enabled), good: !!(w.docker_isolation && w.docker_isolation.enabled) },
294294
{ label: 'Secret scan', on: sdd, good: sdd },
295-
{ label: 'Code exec', on: !!w.enable_code_execution, good: !w.enable_code_execution },
295+
// on by default since v0.66.0: the sandbox honours quarantine and server
296+
// restrictions, so an enabled tool is not by itself something to review.
297+
{ label: 'Code exec', on: !!w.enable_code_execution, good: true },
296298
{ label: 'Read-only', on: !!w.read_only_mode, good: true },
297299
{ label: 'Reveal headers', on: !!w.reveal_secret_headers, good: !w.reveal_secret_headers },
298300
]

0 commit comments

Comments
 (0)