feat(config): enable the code_execution tool by default - #1264
Merged
Conversation
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>
…l 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>
…elation 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>
Deploying mcpproxy-docs with
|
| Latest commit: |
ce521a6
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://e5428686.mcpproxy-docs.pages.dev |
| Branch Preview URL: | https://chore-enable-code-execution.mcpproxy-docs.pages.dev |
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Contributor
📦 Build ArtifactsWorkflow Run: View Run Available Artifacts
How to DownloadOption 1: GitHub Web UI (easiest)
Option 2: GitHub CLI gh run download 34687375997 --repo smart-mcp-proxy/mcpproxy-go
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
code_executionships on from v0.66.0. Alongside the flip, the cross-model review (opencode astra, 3 rounds → CLEAN) surfaced two gaps that had to close before the tool is on for everyone, plus the release notice.Default flip
DefaultConfig().EnableCodeExecution = true(internal/config/config.go). Load is default-then-merge, so an explicitfalsein the file still wins; a file that omits the key inheritstrue. Config files written by earlier releases carry the key explicitly, so existing installs keep their setting — documented in the release notice.pre099/) is untouched. The merge-base goldens are regenerated with the live tool present, and the two enumerated-delta gates now allowcode_executionas an addition ondefault_serverand a stub → live modification on the two routing-mode surfaces, pinned field by field byassertCodeExecutionLive(stubcodeparam survives,scriptpresent,codenot schema-required, title/annotations/description are the live tool's).configuration.md,config-file.md,features/code-execution.md,routing-modes.md,code_execution/*),CLAUDE.md, Settings help text (Web UI + macOS tray catalog), and the Settings security-posture pill no longer flags an enabled sandbox as "review this"..github/RELEASE_NOTICE.mdfor v0.66.0: the default flip (explicit vs omitted key), the Spec-105 scope-hardening fixes, Windows child-process cleanup, the stale-OAuth health fix.Hardening found by the review
ExecutereturnedTIMEOUTand abandoned the goroutine — afor(;;){}kept a core for the life of the process, and the pool slot was released the moment the handler returned.Executenow callsvm.Interrupton the deadline; an interrupt that lands duringvalue.Export()(a getter on the returned object) surfaces as a goja panic rather than aRunStringerror, soexecuteWithVMrecovers it into aTIMEOUTresult — without that the process died. The lonecall_tool()now dispatches under the execution's timeout context likecall_tools()batches already did.output_sanitisationdid not reach scripts. The bridge returnedclient.CallTool's result raw, so an operator's redact/block policy — enforced on everycall_tool_*dispatch — was bypassed insidecode_execution, where a script can read the secret, forward it to another upstream, or return it. Sub-call results now go throughapplyOutputSanitisationbefore they are recorded, stored in history, or handed to JavaScript; a block surfaces as a failed call.contentTrustis derived exactly as on the direct path (unannotated ⇒ open-world ⇒ untrusted, so strip applies), and the sub-call mints one correlation id shared by the policy decision and the activity record (previously two ids, which could never be joined).Testing
TDD throughout — each new test observed failing first (
TestDefaultConfig_CodeExecutionEnabled,TestExecuteTimeoutInterruptsTheVM(2s goroutine still running without the interrupt),TestExecuteTimeoutDuringExportDoesNotPanic(process panic without the recover),TestSubCallSanitisation_*,TestSingletonCallToolDispatchesUnderTheExecutionContext).go test -raceoninternal/config internal/runtime internal/httpapi internal/telemetry internal/jsruntime cmd/...andinternal/server(CI skip regex) — greenvitest1264/1264,vue-tsccleangolangci-lintv2 with.github/.golangci.yml— 0 issues./scripts/test-api-e2e.sh(CI runs it)Not addressed here (pre-existing, filed separately): sub-call activity records truncate the detection text to 8 KiB, and the parent
code_executionrecord never invokes sensitive-data detection on script input/output.🤖 Generated with Claude Code