mocapi Constitution — Architectural Invariants¶
These are the load-bearing invariants of mocapi: the properties a change must
not violate without a superseding ADR. This file is an index of
invariants, not a restatement of the ADRs — each entry links its governing
decision. Conduct rules (formatting, warnings, imports, workflow) live in
../CLAUDE.md; product direction lives in
roadmap.md.
Changing an invariant means writing a new ADR (status Accepted) that supersedes
the cited one, updating the affected design/ doc(s) in the same
change, and updating the entry here.
Invariants¶
I1 — Stateless request model¶
Every request is self-contained: no sessions, no handshake, and no server-initiated request channel. Correlation state travels in the request envelope, not in server-held session state.
Scoped exception: the opt-in mocapi-tasks module confines all task
state (status, ledger, result) behind the TaskStore SPI. Core stays
byte-for-byte stateless when the module is absent; a client's tasks/*
requests still carry their own correlation (taskId), so no
server-initiated channel or handshake is introduced.
→ ADR-0019,
ADR-0020,
ADR-0037
I2 — Single protocol/transport coupling¶
McpServer ↔ McpTransport is the only seam between the protocol layer and
any transport. mocapi-server depends on no I/O framework (no Servlet API, no
Spring MVC); transports own their wire-format validation and map results to
their native error format. An extension module may still contribute to a
transport's own validation table (e.g. RoutedParamContributor extending the
Streamable HTTP Mcp-Name table) without the transport depending on that
extension or ceding ownership of wire validation — the contribution contract
is additive-only and the transport enforces every entry identically.
→ ADR-0002,
ADR-0038,
ADR-0039
I3 — Spec-compliance target¶
mocapi tracks the current MCP revision (2026-07-28) with a clean-break philosophy: features the same revision deprecates at introduction are not adopted. → ADR-0019, ADR-0022, ADR-0026
I4 — Module boundaries & packaging¶
The module split (api / model / server / transports / autoconfigure / observability / security / prompts) and its packaging rules are deliberate; dependencies flow one way and modules do not reach across their boundaries. → ADR-0001
I5 — Static handler discovery¶
Tools, prompts, and resources are discovered from annotated Spring components
at startup. There is no dynamic registration and no list-changed / resource
-update push; subscriptions/listen is answered as unimplemented.
→ ADR-0010
I6 — Declared not-implemented surface¶
The canonical "does mocapi do X?" list. Anything on it is a deliberate, rationale-backed omission; conformance tooling asserts against it. → ADR-0022
I7 — Model is 1:1 with the MCP schema¶
mocapi-model mirrors the MCP schema.ts shapes (params, results, shared data
types); deprecated spec types stay as @Deprecated rather than being deleted.
→ ADR-0014
I8 — Authorization model¶
Bearer-token validation with mandatory audience enforcement, RFC 9728 Protected Resource Metadata, and the composable Guard SPI. These are the resource-server obligations mocapi guarantees. → ADR-0013, ADR-0012
I9 — Error-code allocation¶
mocapi-private JSON-RPC codes live only in the implementation-defined sub-range
(-32000..-32019); spec-defined codes (-32020..-32099) are used
verbatim, never reassigned.
→ ADR-0023