frostney / frostney/GocciaScript

Expose persistent GocciaSandboxRunner sessions over MCP

Open
#993 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

internal new feature runtime
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 real TSandboxShell.
  • runScript with 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:

  1. Creates one TGocciaSandboxContext.
  2. Imports host or inline seed data.
  3. Captures a baseline.
  4. Executes one entry path.
  5. Optionally emits a diff.
  6. 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.
  • $ and runScript dispatch.
  • 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-sdk as an lwpt dependency with a locked compatible version. Version 1.0.1 is 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 $ and runScript execution 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.