Files
cleveragents-core/features/mcp_sandbox_rewrite.feature
T
freemo 81c2878ec8
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 22s
CI / quality (pull_request) Successful in 34s
CI / lint (pull_request) Successful in 3m19s
CI / typecheck (pull_request) Successful in 4m6s
CI / security (pull_request) Successful in 4m7s
CI / unit_tests (pull_request) Successful in 7m4s
CI / integration_tests (pull_request) Successful in 7m11s
CI / docker (pull_request) Successful in 1m35s
CI / coverage (pull_request) Failing after 8m51s
CI / e2e_tests (pull_request) Failing after 17m45s
CI / status-check (pull_request) Failing after 1s
CI / benchmark-regression (pull_request) Successful in 54m58s
feat(mcp): implement lazy start/auto-stop and sandbox path rewriting for MCP tools
Add lifecycle management and sandbox support for MCP tools:

- McpClient: lazy start (server starts on first call_tool()),
  configurable idle timeout with auto-stop, health monitoring
  with automatic restart on server crash
- McpRegistry: namespace-isolated tracking of multiple MCP servers
  with independent lifecycles
- SandboxPathRewriter: bi-directional file path rewriting between
  host and sandbox workspaces using PathMapper
- MCPCapabilityMetadata: structured exposure of full MCP server
  capabilities (tools, resources, prompts)
- MCPToolDescriptor: extended with annotations field
- MCPToolAdapter: capability_metadata property, enhanced source_metadata
  with server capabilities and tool annotations

BDD scenarios:
- 16 lifecycle scenarios (lazy start, auto-stop, health check, registry)
- 10 sandbox path rewriting scenarios (arguments, responses, roundtrip)
- All 42 existing MCP adapter scenarios continue to pass

ISSUES CLOSED: #938
2026-03-30 22:42:15 +00:00

67 lines
4.0 KiB
Gherkin

Feature: MCP Sandbox Path Rewriting
As an actor runtime executing in a sandboxed workspace
I want file paths in MCP tool arguments and responses rewritten
So that MCP tools operate on correct paths inside the sandbox
# -------------------------------------------------------------------
# Argument Rewriting (Host -> Sandbox)
# -------------------------------------------------------------------
Scenario: Rewrite host path to sandbox path in arguments
Given a sandbox path rewriter with host root "/home/user/project" and sandbox root "/workspace"
When I rewrite tool arguments with key "file_path" and value "/home/user/project/src/main.py"
Then the rewritten arguments should have "file_path" equal to "/workspace/src/main.py"
Scenario: Non-matching paths pass through unchanged
Given a sandbox path rewriter with host root "/home/user/project" and sandbox root "/workspace"
When I rewrite tool arguments with key "file_path" and value "/other/location/file.py"
Then the rewritten arguments should have "file_path" equal to "/other/location/file.py"
Scenario: Non-path string values are not rewritten
Given a sandbox path rewriter with host root "/home/user/project" and sandbox root "/workspace"
When I rewrite tool arguments with key "title" and value "My Document"
Then the rewritten arguments should have "title" equal to "My Document"
Scenario: Nested dict paths are rewritten
Given a sandbox path rewriter with host root "/home/user/project" and sandbox root "/workspace"
When I rewrite nested tool arguments with outer key "config" inner key "source" and value "/home/user/project/cfg.yaml"
Then the rewritten nested argument "config.source" should equal "/workspace/cfg.yaml"
Scenario: List of paths are rewritten
Given a sandbox path rewriter with host root "/home/user/project" and sandbox root "/workspace"
When I rewrite tool arguments with key "files" and path list "/home/user/project/a.py,/home/user/project/b.py"
Then the rewritten argument "files" should be a list with 2 rewritten paths
Scenario: Host root path itself maps to sandbox root
Given a sandbox path rewriter with host root "/home/user/project" and sandbox root "/workspace"
When I rewrite tool arguments with key "dir" and value "/home/user/project"
Then the rewritten arguments should have "dir" equal to "/workspace"
# -------------------------------------------------------------------
# Response Rewriting (Sandbox -> Host)
# -------------------------------------------------------------------
Scenario: Rewrite sandbox path to host path in response
Given a sandbox path rewriter with host root "/home/user/project" and sandbox root "/workspace"
When I rewrite tool response with key "output_file" and value "/workspace/build/out.txt"
Then the rewritten response should have "output_file" equal to "/home/user/project/build/out.txt"
Scenario: Non-matching sandbox response paths pass through
Given a sandbox path rewriter with host root "/home/user/project" and sandbox root "/workspace"
When I rewrite tool response with key "output_file" and value "/tmp/other.txt"
Then the rewritten response should have "output_file" equal to "/tmp/other.txt"
Scenario: Nested response paths are rewritten
Given a sandbox path rewriter with host root "/home/user/project" and sandbox root "/workspace"
When I rewrite nested tool response with outer key "result" inner key "path" and value "/workspace/dist/app.js"
Then the rewritten nested response "result.path" should equal "/home/user/project/dist/app.js"
# -------------------------------------------------------------------
# Roundtrip
# -------------------------------------------------------------------
Scenario: Roundtrip rewrite preserves original path
Given a sandbox path rewriter with host root "/home/user/project" and sandbox root "/workspace"
When I roundtrip rewrite tool arguments with key "file" and value "/home/user/project/src/main.py"
Then the roundtrip path should equal "/home/user/project/src/main.py"