Skip to content

Add safe-execution wrapper for hosted MCP deployments#91

Merged
kgdunn merged 2 commits into
mainfrom
claude/review-mcp-server-security-Ux0hZ
Apr 19, 2026
Merged

Add safe-execution wrapper for hosted MCP deployments#91
kgdunn merged 2 commits into
mainfrom
claude/review-mcp-server-security-Ux0hZ

Conversation

@kgdunn
Copy link
Copy Markdown
Owner

@kgdunn kgdunn commented Apr 18, 2026

Summary

Adds a safety layer around the tool registry so the MCP server can be exposed over untrusted transports (public HTTP, hosted services like factori.al) without letting a single fit_pca(n_components=10000) call OOM the server or block the event loop.

Companion PR in kgdunn/agentic-doe wires the hosted backend through this safe wrapper.

What changed

  • New module process_improve/tool_safety.py:
    • validate_input() — rejects oversized arrays (cells, string length, depth) and over-large scalar params (n_components, max_outliers_to_detect, n_iter, ...) before any subprocess work.
    • safe_execute_tool_call() — runs the tool in a ProcessPoolExecutor with:
      • wall-clock timeout (default 10 s, env PROCESS_IMPROVE_TOOL_TIMEOUT)
      • per-subprocess RLIMIT_AS cap (default 1024 MB, env PROCESS_IMPROVE_MAX_MEMORY_MB) applied after heavy imports so pyDOE3's orthogonal-array tables don't eat the per-call budget.
    • Structured errors: ToolInputInvalidError, ToolInputTooLargeError, ToolTimeoutError, ToolMemoryExceededError — all carry a JSON-serialisable .to_dict().
    • Prefers fork multiprocessing context where available so the worker inherits the parent's tool registry and imported numpy.
  • process_improve/mcp_server.py — opt-in safe mode via PROCESS_IMPROVE_MCP_SAFE_MODE=1. Local stdio users keep the fast in-process path.
  • process_improve/tool_spec.py — re-exports the safety API for discoverability.
  • Version bump 1.3.3 → 1.4.0 (new feature per CLAUDE.md versioning rules).

Test plan

  • New tests/test_tool_safety.py (14 tests) — validator unit tests + subprocess integration (happy path, timeout, memory cap, unknown tool). All pass.
  • pytest tests/test_tool_spec.py tests/test_tool_safety.py — 66 passed.
  • ruff check . — clean.
  • python -c "from process_improve.mcp_server import _register_all_tools; _register_all_tools()" — 31 tools register.

https://claude.ai/code/session_01EokDs8NGnpFhCshdaxEnA2

claude added 2 commits April 18, 2026 21:45
Adds process_improve.tool_safety with input-size validation, wall-clock
timeouts via a ProcessPoolExecutor, per-subprocess memory caps
(RLIMIT_AS), and structured error types (ToolInputTooLargeError,
ToolTimeoutError, ToolMemoryExceededError). The stdio MCP server keeps
the fast in-process path by default; hosted callers can opt in via
PROCESS_IMPROVE_MCP_SAFE_MODE=1 or by calling safe_execute_tool_call
directly.

Prepares the registry to be exposed over an untrusted HTTP transport
(e.g. from the agentic-doe backend) without letting a single large
fit_pca request OOM the server or block the event loop.

Bumps version to 1.4.0 (new feature).
CI on macos-latest/3.13 failed because Apple's Accelerate framework
(used by numpy) is not fork-safe, and Python 3.13 emits a
DeprecationWarning for fork() in multi-threaded parents. Restrict the
fork preference to Linux and fall back to the platform default (spawn)
elsewhere.

The in-file @tool_spec registrations the subprocess tests rely on only
survive fork, so the subprocess test class is skipped on non-Linux.
The input-validation tests (which don't touch the pool) still run on
every platform.
@kgdunn kgdunn merged commit c9e882b into main Apr 19, 2026
7 checks passed
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.

2 participants