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
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
67 lines
4.0 KiB
Gherkin
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"
|