Domain is data
A hub starts as types, not as routes.
Schema is what every host will read: JSON codecs, OpenAPI components, MCP tool arguments, and (later) CLI flags. JsonCodec is how bytes move. Core never parses a user body except through JsonCodec.
Show
id: Int, title: String, remaining: Int
--id 1 (later interpreter)
{"id":1,"title":"Evening bill","remaining":12}The box office
The running example in this repo is a box office. Three bills. That is enough to host humans, systems, and agents.
The types
final case class Show(id: Int, title: String, remaining: Int) derives Schema, JsonCodec
final case class Party(showId: Int, size: Int) derives Schema, JsonCodec
final case class NotFound(message: String) derives Schema, JsonCodec
Why Schema exists
derives Schema is not documentation theater. Show becomes:
the JSON object
{"id":1,"title":"Evening bill","remaining":12}on the wirecomponents.schemas.Showin OpenAPIthe result schema of
get_showfor MCPthe shape a future CLI would print and parse
Change the type. Every host moves. That is the point of a compiler.
Operations are an AST turns these types into Endpoints.