feat(mcp): add host_path and mount_path parameters with unit tests#1131
feat(mcp): add host_path and mount_path parameters with unit tests#1131candlelightner wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the Python MCP sandbox server’s sandbox_create tool to expose host volume mounting by adding optional host_path and mount_path parameters, mapping them into native OpenSandbox Volume specs, and introducing an initial unit test for the MCP module.
Changes:
- Added
host_pathandmount_pathkeyword-only parameters tosandbox_createand forwarded them asvolumestoSandbox.create. - Constructed a native
opensandbox.models.sandboxes.Volume(Host bind mount) when both mount parameters are provided. - Added a new unit test to validate that
sandbox_createpasses the expectedVolumeconfiguration into the SDK call.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| sdks/mcp/sandbox/python/src/opensandbox_mcp/server.py | Adds volume-mount parameters and translates them into an SDK volumes argument during sandbox creation. |
| sdks/mcp/sandbox/python/tests/test_server.py | Adds a unit test ensuring volume parameters are wired into Sandbox.create as a native Volume spec. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Dynamically compile the volumes configuration using native SDK models | ||
| volumes = None | ||
| if host_path and mount_path: | ||
| from opensandbox.models.sandboxes import Host, Volume | ||
|
|
||
| volumes = [ | ||
| Volume( | ||
| name="mcp-persistent-storage", | ||
| host=Host(path=host_path), | ||
| mountPath=mount_path, | ||
| ) | ||
| ] |
| @@ -0,0 +1,47 @@ | |||
| import pytest | |||
| from unittest.mock import AsyncMock, MagicMock, patch | |||
| from opensandbox_mcp.server import create_server | |||
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b9d7b6f9dd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
|
||
| # Dynamically compile the volumes configuration using native SDK models | ||
| volumes = None | ||
| if host_path and mount_path: |
There was a problem hiding this comment.
Reject incomplete volume mount inputs
When an MCP caller provides only one of the new mount fields, such as host_path without mount_path, this condition leaves volumes as None and still creates the sandbox successfully. That silently drops the requested host mount, so subsequent writes happen in the container filesystem instead of the intended persisted host path. Since these two fields are a required pair for a valid volume, partial or blank input should be rejected rather than ignored.
Useful? React with 👍 / 👎.
I don't have repository write permissions to apply labels via the UI. Could a maintainer please tag this with the |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cbea46cad0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (host_path is not None) != (mount_path is not None): | ||
| raise ValueError("Both 'host_path' and 'mount_path' must be provided together to enable persistence.") | ||
|
|
||
| if host_path and mount_path: |
There was a problem hiding this comment.
Reject empty mount parameters instead of ignoring them
The current None-pair check only fixes missing/null values; fresh evidence in this revision is that this truthiness guard still treats an explicitly supplied "" for either mount field as disabled and leaves volumes=None. In MCP clients that serialize blank optional strings instead of omitting them, sandbox_create succeeds without mounting the requested host path, so data is written to ephemeral container storage instead of the intended persistent host directory. Validate non-blank strings, or construct the Volume whenever both values are not None and let the SDK validators fail.
Useful? React with 👍 / 👎.
| host_path: str | None = None, | ||
| mount_path: str | None = None, |
There was a problem hiding this comment.
Document the new mount parameters in MCP docs
This adds user-visible MCP inputs, but I checked docs/sdks/mcp.md and sdks/mcp/sandbox/python/README.md and neither mentions host_path/mount_path or the server allowed_host_paths prerequisite. The repo docs rules require updating docs/ for user-visible behavior, and without that users installing the MCP package only see sandbox_create listed generically, so the new persistence workflow is effectively undocumented outside the generated tool schema.
Useful? React with 👍 / 👎.
Summary
This PR exposes the core platform's native volume-mounting layer through the Python MCP server configuration schema. Currently, the
sandbox_createMCP tool omits the underlying Python SDK's volume mapping options. This locks downstream MCP-capable AI clients (such as LibreChat, Claude Code, and Cursor) out of host-bound filesystem persistence workflows.This change appends keyword-only optional attributes (
host_path: str | None = Noneandmount_path: str | None = None) onto thesandbox_createtool signature, cleanly maps them to native OpenSandboxVolumemodels, and forwards them to the orchestration layer.Testing
Details:
tests/test_server.py). The test initializes the FastMCP application via thecreate_serverfactory, extracts the target function from the tool manager, and asserts that input parameters are successfully structured into nativeVolumespecs with accurate snake_case attributes. Passed cleanly locally usinguv run pytest tests/.socat). Confirmed the new schema updates are broadcasted accurately, allowing an LLM agent to provision a container, mount an ext4 host path (/var/lib/sandboxes/workspaces), write an integrity file, completely destroy the sandbox instance, and verify data persistence upon mounting the same path to an independent subsequent sandbox.Breaking Changes
Details:
The added parameters are fully optional keyword arguments defaulting to
None. All existing orchestration blocks, environment mappings, metadata payloads, and progress streams remain 100% backward compatible and unaffected.Checklist