Architecture

Contracts

Contracts is the least glamorous component and one of the most important: it’s the single source of truth for what goes on the wire. Every client’s request and response types are generated from the Authority’s own schemas, so a consumer cannot drift from what the Authority serves.

The problem it removes

In a multi-component system, the fastest way to break things is to let each client hand-guess the shape of a request. One consumer assumes a field name the Authority renamed, another misses a required parameter, and you get the class of bug that only shows up at runtime, in integration, against the real server. Contracts makes that category structurally impossible.

How it works

The Authority defines its API with typed models. Those models are introspected into a canonical openapi.json (pure schema, no database, no deployment needed), which is committed as the contract. From that, typed client definitions are generated, with friendly aliases layered on top for consumers to import. Because the types are derived from the deployed models rather than written alongside them, a generated client can’t diverge from what the Authority actually serves.

Note

Consumers import generated types; they never edit them. Regenerating from a fresh openapi.json is the only way the wire shape changes. Drift can’t creep in by hand.
Who consumes it, and why it’s a component at all

The generated contract is consumed by the TypeScript-side components (the MCP proxy, the Node runtime, and the verifier), so their view of a mint request or an error response can never fall out of step with the Authority’s.

It earns a place in the architecture because it enforces an invariant the running system depends on: one definition of the wire, owned by the server, mechanically propagated to every client. It is the same instinct as the checksum engine (shared code that guarantees two sides agree), applied to the API surface instead of the identity algorithm.