Skip to content

Allow run_script to run on a remote runner#182

Merged
titouanmathis merged 1 commit into
mainfrom
feat/mcp-run-remote-runner
Jun 10, 2026
Merged

Allow run_script to run on a remote runner#182
titouanmathis merged 1 commit into
mainfrom
feat/mcp-run-remote-runner

Conversation

@titouanmathis

Copy link
Copy Markdown
Contributor

Summary

Lets the MCP server delegate run_script execution to a separate runner so a script's memory/CPU (and any OOM) is isolated from the main server — important on small VMs (the hosted HTTP MCP runs on 256 MB, where a heavy in-process run could OOM-kill the whole server). Infrastructure-agnostic and load-balancer-ready.

How it works

  • Front (PRODUCTIVE_MCP_RUN_RUNNER_URL set): handleRunScript forwards a stateless { code, args, flags, dry_run, credentials } POST to the runner and relays its ToolResult. The runner URL also enables run_script without the local PRODUCTIVE_MCP_ENABLE_RUN flag (the front can stay tiny + gated).
  • Runner (HTTP transport, PRODUCTIVE_MCP_RUN_RUNNER_TOKEN set, PRODUCTIVE_MCP_ENABLE_RUN=true): a token-gated POST /run runs the script through the normal pipeline (its own limits + sandbox) and returns the ToolResult.
  • No runner configured: runs locally exactly as before (graceful fallback). Agents see no difference either way.

Infra-agnostic / LB-ready

The /run contract is a single stateless HTTP POST, so any backend works (Fly machine pool, k8s, serverless, …) and you can put a load balancer in front of a runner pool. It is:

  • stateless — everything is in the body, no session/affinity;
  • token-authenticatedPRODUCTIVE_MCP_RUN_RUNNER_TOKEN (constant-time compare), so the hop is safe even on a shared private network;
  • not to be proxy-retried — a non-dry_run script can mutate, so retries must be disabled at the LB/proxy.

Config

Front: PRODUCTIVE_MCP_RUN_RUNNER_URL, PRODUCTIVE_MCP_RUN_RUNNER_TOKEN, optional PRODUCTIVE_MCP_RUN_RUNNER_TIMEOUT_MS (30000).
Runner: PRODUCTIVE_MCP_RUN_RUNNER_TOKEN (activates /run), PRODUCTIVE_MCP_ENABLE_RUN=true, plus the existing PRODUCTIVE_MCP_RUN_* limits.

Testing

  • Unit tests: remote.ts (config parsing, token compare, forwarding success/non-2xx/timeout/transport-error, header/body), /run core (run-endpoint.ts — token gating 404/401, body/credential validation, happy path), and the handleRunScript remote branch (forwards, doesn't run locally, still validates code).
  • 926 MCP unit tests pass; npm run check clean; build OK. The thin H3 wiring in http.ts is covered by the executeRunRequest core tests.

Depends on a release before the runner deployment can pin it.

🤖 Generated with Claude Code

Isolate script execution (memory/CPU/OOM) from the main MCP server by letting it
forward run_script to a separate runner over one stateless HTTP POST:
- When PRODUCTIVE_MCP_RUN_RUNNER_URL is set, handleRunScript forwards
  { code, args, flags, dry_run, credentials } and relays the runner's ToolResult;
  the runner URL also enables run_script without the local ENABLE_RUN flag.
  Otherwise it runs locally as before (graceful fallback).
- Add a token-gated /run endpoint on the HTTP transport (active only when
  PRODUCTIVE_MCP_RUN_RUNNER_TOKEN is set), which runs the script through the
  normal pipeline and returns the ToolResult.
- Contract is infrastructure-agnostic and load-balancer-ready: stateless,
  token-authenticated, must not be proxy-retried (non-dry-run scripts mutate).
- Unit tests for remote forwarding, the /run core, and the handler branch;
  SKILL.md + CHANGELOG updated.

Co-authored-by: Claude <claude@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.27%. Comparing base (e00aa34) to head (e334000).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #182      +/-   ##
==========================================
+ Coverage   97.25%   97.27%   +0.02%     
==========================================
  Files         264      266       +2     
  Lines        8802     8867      +65     
  Branches     2783     2806      +23     
==========================================
+ Hits         8560     8625      +65     
  Misses        236      236              
  Partials        6        6              
Flag Coverage Δ
unittests 97.27% <100.00%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@titouanmathis titouanmathis merged commit 45cbe91 into main Jun 10, 2026
11 checks passed
@titouanmathis titouanmathis deleted the feat/mcp-run-remote-runner branch June 10, 2026 05:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant