Files
derek.holloway 7502bf64a4
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
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

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_ONLY set
  • MCP exposure test (test_mcp_exposure.py) verifies no EXECUTION tools leak
  • Type hints on wrapper args + return

Tests you must add

  • test_<name>_mcp_wraps_read_only_tool() — class invariant
  • test_<name>_returns_valid_mcp_content() — output shape
  • test_<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