Architecture
Mcph is a Python async CLI built on six modular components:
Component Overview
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ .mcph file │ → │ Parser │ → │ AST │
└──────────────┘ └──────────────┘ └──────────────┘
│
▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Reporter │ ← │ Runtime │ ← │ Session │
│ JUnit, JSON │ │ (runner) │ │ (executor) │
└──────────────┘ └──────────────┘ └──────────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Protocol │ │ Assertion│ │ Capture │
│ Engine │ │ Engine │ │ Registry │
└──────────┘ └──────────┘ └──────────┘
│
▼
┌──────────┐
│Transport │
│ stdio/HTTP│
└──────────┘ Modules
Parser (src/mcph/parser.py)
Hand-written recursive descent parser. Line-oriented, Hurl-inspired syntax.
Produces an AST of 15 node types from .mcph source text.
Transport (src/mcph/transport/)
- StdioTransport — spawns MCP server as async subprocess, newline-delimited JSON-RPC framing, stderr isolation
- HttpTransport — httpx-based, Mcp-Session-Id header tracking, POST to single MCP endpoint
Protocol Engine (src/mcph/protocol.py)
Transport-agnostic JSON-RPC 2.0 layer. Sequential request IDs, response validation, initialize → initialized handshake, method mapping.
Assertion Engine (src/mcph/assertion.py)
Evaluates assertions against protocol responses. JSONPath via jsonpath-ng, regex matching, fuzzy type matchers
(#string, #number, ##object),
structural dict subset equality.
Capture Registry (src/mcph/capture.py)
JSONPath + regex extraction from responses. Recursive {{var}} template resolution through dicts and lists.
Nested variable path support.
Runtime (src/mcph/session.py, src/mcph/runner.py)
Orchestrates the full execution pipeline: parse → connect → initialize →
execute steps → report. REQUIRE_CAPABILITY gating, soft/hard failure
modes, transport cleanup.
Design Decisions
| Decision | Rationale |
|---|---|
| Python + uv | Strong JSON Schema ecosystem, async I/O, single-binary via PyInstaller |
| Custom runner | Stdio lifecycle + JSON-RPC multiplexing fundamentally different from HTTP |
| Hand-written parser | Clear error messages, no parser generator dependency |
| Hurl-inspired syntax | Proven readability, familiar to developers |
| Transport-agnostic | Same code tests local and remote servers |
| AST-first | Enables future validation passes and compilation |