feat(mcp-tool-proxy): private MCP integration via per-tool SLXs#43
Open
theyashl wants to merge 19 commits into
Open
feat(mcp-tool-proxy): private MCP integration via per-tool SLXs#43theyashl wants to merge 19 commits into
theyashl wants to merge 19 commits into
Conversation
…P integration Spec covers four approaches (A multi-task SLX, B in-VPC gateway, C SLX-per-server, D SLX-per-tool) and recommends D. Plan scopes to the codecollection mcp-tool-proxy codebundle + the mcp_tools indexer in runwhen-local; papi DB/API/UI work is a separate plan. Defaults locked for §10 open decisions in the plan header. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…p path, split error policy
- Discovery: D1 → D2 (no papi work needed for v1; reads MCP_CONFIG setting from
Helm-provided mcpConfig values, mirroring CLOUD_CONFIG_SETTING pattern).
- SLX template: additionalContext gets path/hierarchy = "mcp/{server}"; access
tag flipped to read-only as safe default until we can classify tools.
- Error policy split: tools/call errors and result.isError surface as task
output (rc=0) so agentfarm can read and react; transport + initialize errors
fail the task (rc=1). Reflected in invoke_tool (returns string vs raises) and
main() exit codes.
- Tests rewritten accordingly; Phase 4 papi HTTP fetch replaced with
Helm-config parsing + validation; Phase 5 E2E drops papi mock.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…list SLX YAMLs generated by workspace-builder don't carry configProvided (that lives on the Runbook for the runner to read at exec time). additionalContext.hierarchy is a list of tag keys the UI walks to build the tree view, not a slash-path string. Use [source, mcp_server] so MCP SLXs group by source → server → tool, and surface tool_name as its own tag so the rendered alias isn't the only place it shows up.
RuntimeVarEntry in corestate-operator api/v1/common_types.go only declares name/default/description/validation. The Runbook CRD validation will reject envelopes with extra fields, so 'required' and 'type' (carried over from MCP's JSON Schema) had to come out. The Robot wrapper still receives the full input_schema via MCP_INPUT_SCHEMA so per-tool required-arg enforcement happens at MCP call time, not at Runbook level.
Maps MCP JSON Schema property metadata onto RuntimeVarValidation:
- properties[x].enum -> validation.type=enum, values=[...]
- properties[x].pattern -> validation.type=regex, pattern=...
- neither -> validation.type=regex, pattern='.*'
CRD constrains validation.type to {enum, regex} (corestate-operator
common_types.go:53-63), so the catch-all fallback is a permissive regex
rather than 'optional / nothing'. Every emitted runtime var now carries
a validation block, which matches the CRD's expectation in practice.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
codebundles/mcp-tool-proxy/that proxies a single MCP tool call: Python script doesinitialize+tools/call, Robot wrapper dynamically imports per-tool parameters fromMCP_INPUT_SCHEMA.mcp_toolresource (mcp__{server}__{tool},access: read-only,path: mcp/{server}).initializefailures exit 1;tools/callerrors andresult.isError=trueare surfaced as task output (rc=0) so agentfarm can react to them.Pairs with
runwhen-contrib/runwhen-local#TBD(mcp_tools indexer that drives this codebundle from Helm-providedmcpConfigvalues).Design spec:
docs/superpowers/specs/2026-05-20-private-mcp-integration-design.md.Test Plan
cd codebundles/mcp-tool-proxy && PYTHONPATH=. .venv/bin/pytest tests/ -v→ 18 pass + 1 skipfrom robot.api import get_model; get_model('runbook.robot')cleangeneration-rule-schema.json./.test/dry-run.sh) — stub MCP server + script round-trip; bypasses Robot sinceRW.Coreships only in the runner image (documented in.test/README.md)🤖 Generated with Claude Code