Architecture

August 2, 2026 · View on GitHub

Math MCP Server is a modular FastMCP 3.0 application composed of five mounted sub-servers (calculate, matrix, persistence, visualization, resources) with a three-layer middleware stack (StructuredLogging, ErrorHandling, RateLimiting). State is managed across two layers: in-memory lifespan context for session data and persistent workspace files for cross-session recovery.

Component Map

graph TD
    Client["MCP Client"]
    Client -->|Request| SL["StructuredLogging"]
    SL -->|Pass| EH["ErrorHandling"]
    EH -->|Pass| RL["RateLimiting"]
    RL -->|Route| Root["FastMCP Server<br/>math-mcp"]

    Root -->|mount| Calc["Calculate<br/>Sub-Server"]
    Root -->|mount| Matrix["Matrix<br/>Sub-Server"]
    Root -->|mount| Persist["Persistence<br/>Sub-Server"]
    Root -->|mount| Viz["Visualization<br/>Sub-Server"]
    Root -->|mount| Res["Resources<br/>Sub-Server"]

Tool Taxonomy

graph TD
    subgraph Calc["Calculate"]
        C1["calc_expression"]
        C2["calc_statistics"]
        C3["calc_interest"]
        C4["calc_units"]
    end

    subgraph Matrix["Matrix"]
        M1["matrix_multiply"]
        M2["matrix_transpose"]
        M3["matrix_determinant"]
        M4["matrix_inverse"]
        M5["matrix_eigenvalues"]
    end

    subgraph Persist["Persistence"]
        P1["workspace_save"]
        P2["workspace_load"]
    end

    subgraph Viz["Visualization"]
        V1["plot_function"]
        V2["plot_histogram"]
        V3["plot_line_chart"]
        V4["plot_scatter"]
        V5["plot_box_plot"]
        V6["plot_financial_line"]
    end

Request Lifecycle

graph TD
    A["MCP Client"]
    A --> B["StructuredLogging"]
    B --> C["ErrorHandling"]
    C --> D["RateLimiting"]
    D --> E["Tool Execution"]
    E --> A

State Layers

graph TD
    subgraph Lifespan["In-Memory"]
        L0["Lifespan Context"]
        L1["AppContext"]
        L2["calculation_history"]
        L3["Lost on restart"]
    end
    subgraph Workspace["Disk-Based"]
        W0["workspace.json"]
        W1["Survives restarts"]
    end
    Tool["Tool Execution"]
    Tool -->|Read/Write| Lifespan
    Tool -->|Read/Write| Workspace

Design Principles

  • KISS (Keep It Simple, Stupid): Single-file tools, minimal dependencies, no over-engineering. Each tool does one thing well.
  • Educational Clarity: Code is a teaching artifact. Comments explain "why", not "what". Docstrings include examples and difficulty annotations.
  • Security First: Restricted eval() scope (math module + abs only), Pydantic validation on all inputs, no arbitrary code execution.
  • Modular Composition: FastMCP's mount pattern enables independent sub-servers with shared middleware; easy to test, extend, or disable.

FastMCP 3.0 Patterns

  • Composition via Mount: Each tool category (calculate, matrix, persistence, visualization) is a separate FastMCP instance mounted into the root server. Enables independent development and testing.
  • Middleware Stack: Three layers (StructuredLogging → ErrorHandling → RateLimiting) applied once at the root level; all mounted sub-servers inherit them automatically.
  • Lifespan Context: @asynccontextmanager in server.py manages AppContext (in-memory state) across the server lifetime. Lost on restart; use workspace persistence for recovery.
  • Optional Context: All tools accept ctx: SkipValidation[Context | None] = None (never required). Guarded with if ctx: before use; enables tools to work with or without MCP runtime context.

Prompts

FastMCP's @mcp.prompt() decorator registers reusable prompt templates that Claude can invoke. Math MCP Server provides two prompts via the resources sub-server: math_tutor (structured tutoring prompts with configurable difficulty and examples) and formula_explainer (detailed formula breakdowns with variable definitions, context, and real-world applications). See FastMCP Prompts Documentation for details.

Architecture Decision Records

ADRTitleStatus
ADR-001Restricted eval() SandboxAccepted
ADR-002Monolith-then-Modules DecompositionAccepted
ADR-003FastMCP 3.0 Early AdoptionAccepted
ADR-004asyncio.to_thread() over ProcessPoolExecutorAccepted
ADR-005Pydantic + @validated_tool for Input ValidationAccepted
ADR-006Matplotlib + Agg Backend for VisualizationAccepted
ADR-007JSON Files for Workspace PersistenceAccepted
ADR-008Annotation Quality Enforcement via Introspection TestsAccepted

Development Workflow

See CONTRIBUTING.md for feature branch process, commit standards, testing requirements, and PR review guidelines.