frostney / frostney/GocciaScript
Expose persistent GocciaSandboxRunner sessions over MCP
Nobody has claimed this yet.
- Dominant language
- Pascal
- Stars
- 20
- Forks
- 3
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 45
Description
Summary
Add a stdio MCP mode to the existing sandbox runner:
GocciaSandboxRunner --mcp
Extract the runner’s sandbox execution, seeding, diffing, audit, and lifecycle behavior into a reusable deep module. The existing CLI and new MCP server become adapters over that shared interface.
The MCP server provides persistent, in-memory sandbox sessions so coding agents can seed a virtual project, execute the real sandbox $ and runScript implementations repeatedly, inspect files and diffs, and reset or close the workspace.
Blocked by #826. After the complete lwpt migration lands, consume pascal-mcp-sdk through lwpt rather than vendoring it.
Why
GocciaScript’s primary goal is sandboxed JavaScript execution for AI agents, but agents currently have to orchestrate GocciaSandboxRunner as an external CLI process. Each invocation constructs a new VFS, so state cannot persist naturally across a coding workflow.
The runner already provides the useful primitives:
- A bounded virtual filesystem with no ambient host access.
$backed by the realTSandboxShell.runScriptwith shared and isolated child-VFS execution.- Explicit baselines and JSON/unified diffs.
- Structured execution results and capability audit events.
Exposing those primitives through MCP gives coding environments a native, inspectable sandbox without duplicating execution semantics or routing through another host application.
Current behavior
GocciaSandboxRunner is a CLI-only host. TSandboxRunnerApp currently owns seeding, engine setup, module resolution, execution, nested child sandboxes, result capture, and diff output directly.
Each invocation:
- Creates one
TGocciaSandboxContext. - Imports host or inline seed data.
- Captures a baseline.
- Executes one entry path.
- Optionally emits a diff.
- Exits and discards the VFS.
There is no protocol surface for retaining that VFS across multiple agent operations.
Expected behavior
Architecture
Move the runner’s reusable behavior behind a deep sandbox-host module, with a small interface owning:
- Sandbox contexts and session lifecycle.
- Inline seeding and baseline capture.
- Interpreter/bytecode execution.
$andrunScriptdispatch.- Shared and isolated child execution.
- File inspection and mutation.
- Diff generation.
- Capability-audit collection.
Use two adapters at that seam:
- The existing CLI adapter, preserving current behavior.
- An MCP adapter enabled by
GocciaSandboxRunner --mcp.
--mcp is mutually exclusive with a positional entry path. Stdout belongs exclusively to JSON-RPC; diagnostics and logging use stderr.
MCP tools
| Tool | Behavior |
|---|---|
sandbox_create |
Create an in-memory session and return an opaque server-generated ID. May include initial inline seed files. |
sandbox_seed |
Add UTF-8 text or base64 files to the baseline before the first execution. Reject calls after execution begins. |
sandbox_write_files |
Write text/base64 files as sandbox mutations without changing the baseline. |
sandbox_read_files |
Read one or more files as text or base64 using non-observing VFS reads. |
sandbox_exec |
Execute the real VFS-only TSandboxShell against the persistent session. |
sandbox_run_script |
Execute an entry path in the shared VFS or an optional disposable child sandbox. |
sandbox_diff |
Return JSON or unified changes against the original seeded baseline. |
sandbox_reset |
Restore the original seeded baseline without clearing security-audit history. |
sandbox_audit |
Read the bounded accumulated capability-audit log using a cursor. |
sandbox_close |
Explicitly release the session and its retained state. |
sandbox_run_script preserves the existing runScript contract:
- Shared VFS execution by default.
- Optional isolated child VFS.
- Child seeds copied only from parent-VFS paths or supplied inline.
- Optional JSON/unified child diff.
- Child mutations discarded after execution.
Calls targeting the same sandbox ID execute serially and never expose partially completed mutations.
Session limits
MCP mode uses these defaults:
- Maximum eight live sandboxes.
- 512 MiB VFS quota per sandbox.
- Four-hour idle expiry.
- Five-minute execution timeout per execution call.
The limits are configurable when starting the MCP server. MCP tool arguments cannot raise them.
Expired or closed IDs cannot be reopened. Sessions are never persisted to disk or recovered after the server exits.
Capability boundary
MCP calls cannot widen authority. The following remain fixed at server launch and are inherited by every session:
- Network allowlists.
- Unsafe runtime flags.
- Compatibility flags.
- Memory limits.
- Interpreter/bytecode mode and defaults.
- Other host-controlled runtime extensions.
MCP seeding accepts only inline text/base64 content. It never accepts a host filesystem path.
sandbox_exec runs the existing sandbox shell built-ins only. It never launches host subprocesses or resolves host executables.
Results and audit
Every tool result includes:
- Canonical machine-readable
structuredContent. - A concise text rendering for clients such as Codex CLI.
- Sandbox ID and success/failure state where applicable.
- Exit code, stdout, stderr, result, diff summary, and capability events where applicable.
Execution failures use MCP in-band isError results. Protocol and schema failures remain JSON-RPC errors.
Audit events emitted by an execution are included in that call’s result and appended to the bounded session audit log. Resetting the VFS does not erase that history.
Scope notes
- Blocked by the complete lwpt migration tracked by #826: build and dependency management #877, formatting #878, test discovery #879, and workspace-package deduplication #880.
- Add
pascal-mcp-sdkas an lwpt dependency with a locked compatible version. Version1.0.1is the currently validated baseline. - Record the new host seam and persistent MCP lifecycle in a new ADR.
- Update architecture, build-system, sandbox-module, capability-audit, and user-facing documentation.
- Preserve existing CLI behavior and interpreter/bytecode execution.
Verification should cover:
- MCP discovery, tool schemas, calls, and stdout protocol purity through the real subprocess.
- Persistence and isolation across multiple sessions.
- Seed-phase enforcement and rejection of host paths.
- Real
$andrunScriptexecution in both executor modes. - Shared mutation and isolated-child preview behavior.
- File reading, diffing, reset, close, and expiry.
- Per-session serialization.
- Capability denial and cursor-based audit retrieval.
- Text plus structured result compatibility.
- Existing sandbox CLI tests without regression.
Non-goals:
- Host subprocess execution.
- Host-path seeding through MCP.
- Durable or disk-backed sessions.
- Streamable HTTP transport.
- Automatic application of sandbox diffs to the host.
- Re-baselining an active session.
- Performing the lwpt migration itself.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with TSandboxRunnerApp and the existing GocciaSandboxRunner CLI behavior; resolve the lwpt migration blocker in #826 first. Trace the listed seeding, execution, VFS, diff, audit, and lifecycle paths before defining the shared host seam and MCP adapter. Done means persistent MCP sessions, protocol-safe results, configured limits, and the listed verification coverage work without regressing CLI behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- backend-api-design, devtools, documentation, security, testing-qa
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100