Snippet

Thin MCP server adapters over deterministic Python tools

A complete MCP server module that exposes approved deterministic capabilities without moving business logic into the MCP layer.

pythonOct 6, 2026MIT

AI-generated, human-reviewed: the first draft was generated by an AI agent; I fact-checked, tested, and edited it. AI use policy

What it does#

Wraps existing deterministic functions as MCP tools. The adapter is intentionally thin: MCP provides discovery and invocation; normal Python still owns the business rules.

You need#

Where it goes#

Save it as mcp_tool_server.py next to deterministic_capabilities.py.

mcp_tool_server.py
# SPDX-License-Identifier: MIT
# Copyright (c) 2026 Sarang Datye
"""Thin MCP adapters over existing deterministic tools."""

from __future__ import annotations

from typing import Any

from mcp.server.mcpserver import MCPServer

from deterministic_capabilities import (
    calculate as deterministic_calculate,
    create_support_ticket as deterministic_create_support_ticket,
    validate_email as deterministic_validate_email,
)


mcp = MCPServer(
    "Deterministic Tools",
    instructions=(
        "Discover and invoke deterministic calculator, email syntax, and "
        "mock support-ticket capabilities."
    ),
)


@mcp.tool()
def calculate(operation: str, left: int | float, right: int | float) -> dict[str, Any]:
    """Perform basic arithmetic using deterministic Python code."""
    return deterministic_calculate(operation, left, right)


@mcp.tool()
def validate_email(email: str) -> dict[str, Any]:
    """Check practical email syntax without verifying mailbox existence."""
    return deterministic_validate_email(email)


@mcp.tool()
def create_support_ticket(application: str, description: str, priority: str) -> dict[str, Any]:
    """Create an in-memory mock support ticket for a named application."""
    return deterministic_create_support_ticket(application, description, priority)


if __name__ == "__main__":
    mcp.run()

Check that it works#

Run:

bash
python3 -m py_compile deterministic_capabilities.py mcp_tool_server.py
python3 -c "import asyncio, mcp_tool_server; print(sorted(tool.name for tool in asyncio.run(mcp_tool_server.mcp.list_tools())))"

You should see the three tool names. The calculator logic still lives in deterministic_capabilities.py, exactly where your tests can keep glaring at it.