Write the service once. HTTP, OpenAPI, and MCP are hosts of the same BoundOp. Server.install is that bind on the JVM, on Node, and on Scala Native. CLI is a later interpreter. Not a second product.
Endpoint + In => ZIO[R, E, Out]. Written once.
api.routes. Humans and systems.
api.openApi. Swagger at /docs.
Mcp.from(api). POST /mcp.
mcp.stdio(). Local harnesses.
Same OpArgs. Not shipped. The AST is already this shape.
GET /shows/1 HTTP/1.1
HTTP/1.1 200 OK
content-type: application/json
{"id":1,"name":"Evening bill"}Hosts are interpreters. Do not grow a second tool DSL.
12 remaining
GET /shows/1 HTTP/1.1
HTTP/1.1 200 OK
content-type: application/json
{"id":1,"name":"Evening bill"}Same bind the tests run. Replay of the AST, not a hosted server. Clone and sbt example/run for the JVM process. The same Routes also bind on Node and Native.