M3c: Add thin stdio MCP adapter and parity tests #53

Merged
adrian.tkacz merged 2 commits from m3c-stdio-mcp into develop 2026-09-07 20:53:34 +00:00
Member

Summary

  • Implements the frozen M3 stdio MCP interface with exactly three tools:
    scarcity_status, scarcity_select, and scarcity_simulate.
  • Uses the official MCP Python SDK stable v2 line (mcp 2.1.1, constrained by
    mcp>=2,<3) and the low-level mcp.server.lowlevel.Server API for exact
    structured result and logical error control.
  • Uses the official stdio transport only. No REST runtime dependency, HTTP/SSE
    transport, network listener, resources, prompts, sampling, elicitation,
    subscriptions, or model execution.
  • Adds machine_api.py for shared logical request parsing and machine-interface
    v1 envelopes, and a transport-neutral ApplicationDependencies record. REST
    delegates its existing logical parsing/envelopes to the shared boundary.
  • MCP calls the typed application seam directly in-process; it does not invoke
    REST, CLI, subprocesses, temp files or duplicated selector logic.

Contract and errors

  • Success uses the exact REST logical envelopes as structured_content and a
    deterministic text block containing the same JSON.
  • Logical application-invalid input returns is_error=true with the exact
    structured invalid_request payload.
  • Unexpected application/configuration/collector failure returns is_error=true
    with the fixed safe internal_error payload.
  • Valid no-solution and degraded-provider results remain successful domain data.
  • No credentials, provider endpoints, catalog paths or model-execution input is
    accepted by MCP.

Compatibility boundary

  • The bounded SDK probe observed that MCP 2.1.1's official decoder accepts
    duplicate JSON names with last-value normalization and carries NaN,
    Infinity, and -Infinity in untyped arguments as floats.
  • Malformed JSON syntax and malformed JSON-RPC shape are rejected before the
    Scarcity Router tool handler.
  • D-031 records the narrow D-028 amendment: official SDK stdio framing and
    JSON-RPC decoding are the transport boundary; application semantics begin at
    the tool-argument object delivered by the SDK. REST strict JSON behavior is
    unchanged. No custom MCP protocol parser was added.

Verification

  • Direct == CLI == REST == MCP semantic parity is covered for deterministic
    status, select, and simulation inputs with synthetic collectors and a fixed
    clock, including the 98/2 simulation.
  • Discovery tests assert exactly three unversioned tools, machine-interface v1
    descriptions, advertised logical fields, and no resources/prompts.
  • Tests cover profile and explicit requirement selection, valid no-solution,
    degraded status, unknown profile, requirement-source errors, null
    replenishment states, unknown fields, empty/semantic/schema-invalid
    simulation overrides, malformed catalog, collector failure and safe error
    redaction.
  • Official in-memory Client tests and a real stdio subprocess Client discovery
    smoke verify framing and bounded client-owned cleanup without live collectors.
  • uv sync --only-dev: passed.
  • make check: passed, 884 tests; basedpyright 0 errors, 0 warnings, 0 notes.
  • uv run basedpyright: passed with 0 errors, 0 warnings, 0 notes.
  • git diff --check: passed; branch contains 0 merge commits.

Documentation and status

  • D-031 records the official SDK, dependency placement, low-level API, stdio
    lifecycle, exact surface, shared boundary, parity evidence and raw parser
    amendment.
  • README, architecture, machine-interface, security and roadmap docs are
    updated; a generic stdio orchestrator example is in
    examples/mcp-stdio.json.
  • M3a and M3b are complete; M3c implementation is complete; M3 closeout and
    live acceptance remain pending. M3 is not marked PASS.

Closes #52

## Summary - Implements the frozen M3 stdio MCP interface with exactly three tools: `scarcity_status`, `scarcity_select`, and `scarcity_simulate`. - Uses the official MCP Python SDK stable v2 line (`mcp` 2.1.1, constrained by `mcp>=2,<3`) and the low-level `mcp.server.lowlevel.Server` API for exact structured result and logical error control. - Uses the official stdio transport only. No REST runtime dependency, HTTP/SSE transport, network listener, resources, prompts, sampling, elicitation, subscriptions, or model execution. - Adds `machine_api.py` for shared logical request parsing and machine-interface v1 envelopes, and a transport-neutral `ApplicationDependencies` record. REST delegates its existing logical parsing/envelopes to the shared boundary. - MCP calls the typed application seam directly in-process; it does not invoke REST, CLI, subprocesses, temp files or duplicated selector logic. ## Contract and errors - Success uses the exact REST logical envelopes as `structured_content` and a deterministic text block containing the same JSON. - Logical application-invalid input returns `is_error=true` with the exact structured `invalid_request` payload. - Unexpected application/configuration/collector failure returns `is_error=true` with the fixed safe `internal_error` payload. - Valid no-solution and degraded-provider results remain successful domain data. - No credentials, provider endpoints, catalog paths or model-execution input is accepted by MCP. ## Compatibility boundary - The bounded SDK probe observed that MCP 2.1.1's official decoder accepts duplicate JSON names with last-value normalization and carries `NaN`, `Infinity`, and `-Infinity` in untyped arguments as floats. - Malformed JSON syntax and malformed JSON-RPC shape are rejected before the Scarcity Router tool handler. - D-031 records the narrow D-028 amendment: official SDK stdio framing and JSON-RPC decoding are the transport boundary; application semantics begin at the tool-argument object delivered by the SDK. REST strict JSON behavior is unchanged. No custom MCP protocol parser was added. ## Verification - Direct == CLI == REST == MCP semantic parity is covered for deterministic status, select, and simulation inputs with synthetic collectors and a fixed clock, including the 98/2 simulation. - Discovery tests assert exactly three unversioned tools, machine-interface v1 descriptions, advertised logical fields, and no resources/prompts. - Tests cover profile and explicit requirement selection, valid no-solution, degraded status, unknown profile, requirement-source errors, null replenishment states, unknown fields, empty/semantic/schema-invalid simulation overrides, malformed catalog, collector failure and safe error redaction. - Official in-memory Client tests and a real stdio subprocess Client discovery smoke verify framing and bounded client-owned cleanup without live collectors. - `uv sync --only-dev`: passed. - `make check`: passed, 884 tests; basedpyright 0 errors, 0 warnings, 0 notes. - `uv run basedpyright`: passed with 0 errors, 0 warnings, 0 notes. - `git diff --check`: passed; branch contains 0 merge commits. ## Documentation and status - D-031 records the official SDK, dependency placement, low-level API, stdio lifecycle, exact surface, shared boundary, parity evidence and raw parser amendment. - README, architecture, machine-interface, security and roadmap docs are updated; a generic stdio orchestrator example is in `examples/mcp-stdio.json`. - M3a and M3b are complete; M3c implementation is complete; M3 closeout and live acceptance remain pending. M3 is not marked PASS. Closes #52
adrian.tkacz deleted branch m3c-stdio-mcp 2026-09-07 20:53:34 +00:00
Sign in to join this conversation.
No description provided.