CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
2.3 KiB
2.3 KiB
Contributing: new MCP tool
What you're adding
A wrapper that exposes a perfxpert tool to external clients (Claude Desktop,
Cursor, etc.) via the Model Context Protocol. MCP tools must preserve the
READ_ONLY class invariant — no EXECUTION tools are exposed.
File locations
- MCP server:
mcp_server/ - Tool wrapper:
mcp_server/tools/<name>.py - Tests:
tests/test_mcp/test_<name>.py
Key constraint
Only READ_ONLY tools are exposed via MCP. EXECUTION tools must remain
in-process only. CI enforces this via tests/test_integration/test_mcp_exposure.py.
Template
# SKIP-SAMPLE — template: <name> is a placeholder
"""<name> MCP tool wrapper."""
from typing import Any, Dict
import mcp.types as types
from mcp.server import RequestContext
from perfxpert.tools import my_read_only_tool
async def handle_name(
context: RequestContext,
**kwargs: Any
) -> list[types.TextContent | types.ImageContent]:
"""MCP handler for <name>."""
try:
result = my_read_only_tool(**kwargs)
return [types.TextContent(type="text", text=str(result))]
except Exception as e:
return [types.TextContent(type="text", text=f"Error: {e}")]
Registration
Add to MCP server tool list:
# SKIP-SAMPLE — template: `server` and `handle_tool_call` are placeholders
server.set_request_handler(
types.messages.CallToolRequest,
lambda ctx, req: handle_tool_call(ctx, req)
)
Schema constraints (CI-enforced)
- Wrapping tool must have
ToolClass.READ_ONLYset - MCP exposure test (
test_mcp_exposure.py) verifies noEXECUTIONtools leak - Type hints on wrapper args + return
Tests you must add
test_<name>_mcp_wraps_read_only_tool()— class invarianttest_<name>_returns_valid_mcp_content()— output shapetest_<name>_handles_error()— error path
Review requirements
- 1 security-focused reviewer
- Exposure test green (no EXECUTION tools)
- CI green (unit + MCP policy)
Common pitfalls
- Don't wrap EXECUTION tools — they must stay in-process
- MCP responses are text + images only — complex types must serialize to JSON
- Error messages should not leak internal details
Related docs
- Design spec: Appendix A (tool-class split)
- MCP spec: https://modelcontextprotocol.io/
- Exposure test:
tests/test_integration/test_mcp_exposure.py