The AST

The compiler is small on purpose.

ValueRole
Schema / SchemaDocDomain shape every host can read
Endpoint / EndpointDocOne operation, still unbound
BoundOpEndpoint + In => ZIO[R, E, Out]
ApiNamed collection of bound ops
OpArgsFlatten path, query, JSON body into one argument object

Interpreters fold that AST:

InterpreterOutput
api.routesHTTP
api.openApiOpenAPI 3.1 + Swagger UI
Mcp.from(api)MCP tools (promoted) + optional catalog
CLI (later)argv / subcommands via OpArgs
EndpointDoc · click a field
GET/shows/{id}.mcpReadOnly
read by

HTTP, OpenAPI, derived tool name

OpArgs is why MCP (and CLI) can share HTTP

OpArgs.promotable requires JSON in and JSON out. Path params and query strings flatten into the same JSON object a tool call (or a future CLI) already knows how to pass. Form, bytes, and SSE stay on HTTP. Do not smash them into tools.

OpArgs.promotable(BoxOffice.getShow.doc)
true
OpArgs.inputSchema(BoxOffice.getShow.doc).map(_.jsonSchema.toString).exists(_.contains("id"))
true

Click through EndpointDoc

Each field names its readers. Click one. That is the AST, not a metaphor.