One Schema, many surfaces

One Effect Schema definition can feed a CLI, REST API, MCP server, and code mode21. This study records the proposal and implementation on 2026-09-18 against Effect rc.115. Read One capability, every surface18 for today’s defineContract → implement pattern, including browser RPC, and current pins. The API names, proposed RPC timing, test counts, and sandbox permissions below are historical. Use current guidance for sandbox permissions.

Joel (2026-09-18): rat-stack is meant to build agent-first tools. The interesting question is whether one Effect Schema definition can project into a CLI, a REST API with OpenAPI, an MCP27 server, and a code-mode surface23, and what Executor and Kody teach about the last two.

What Effect rc.115 already ships

Every target below is in effect/unstable/* today and takes Schema directly. None of them talk to each other.

SurfaceModuleEntrySchema goes in as
CLIunstable/cliCommand.make(name, config, handler)Flag.withSchema, Flag.FileSchema, Argument.*
REST + OpenAPIunstable/httpapiHttpApi / HttpApiGroup / HttpApiEndpoint.{get,post,...}payload, success, error schemas
OpenAPI docunstable/httpapi/OpenApiOpenApi.fromApi(api)derived from the HttpApi
Typed clientunstable/httpapi/HttpApiClientHttpApiClient.make(api)derived from the HttpApi
MCPunstable/aiTool.make(name, { parameters, success, failure, dependencies, needsApproval }), Toolkit.make(...), McpServer.toolkit(toolkit), McpServer.layerStdio / layerHttpparameters, success, failure
JSON Schemaunstable/ai/ToolTool.getJsonSchema(tool), Tool.getJsonSchemaFromSchema(schema)any Schema
RPCunstable/rpcRpc.make, RpcGrouppayload, success, error

Tool annotations already exist as Context references: Tool.Readonly, Tool.Destructive, Tool.Idempotent, Tool.OpenWorld. needsApproval is a first-class option on Tool.make.

Effect has no Toolkit.fromHttpApi or Command.fromToolkit to feed all four surfaces from one definition. rat-stack can supply that connection.

What the two reference repos do

Executor (UsefulSoftwareCo, Effect 4)

Kody (Kent C. Dodds, Cloudflare Workers, Zod)

Cloudflare Code Mode (the origin)

One tool, codemode({ code }). The MCP or OpenAPI schema becomes a typed TypeScript API with doc comments; the model writes TS against it; it runs in an isolated Worker with no network, only bindings23. Inside the sandbox: search(query), describe(target), step(name, fn) (run once, replay), and run(snippet). Durable log, approval pause, rollback. The OpenAPI MCP server variant exposes exactly two tools, search and execute.

Proposed rat-stack shape

Keep Effect Schema as the single source and add one domain object plus projections. Nothing here needs a new schema language.

                 Capability (Effect Schema in / out / error, Effect handler,
                             dependencies, annotations, approval)
                                          │
        ┌──────────────┬──────────────────┼──────────────────┬──────────────┐
        ▼              ▼                  ▼                  ▼              ▼
  Command.make   HttpApiEndpoint     Tool.make          catalog IR      (later)
  (unstable/cli) (unstable/httpapi)  Toolkit.make       JSON Schema +   Rpc.make
        │              │              McpServer.toolkit  generated d.ts
        ▼              ▼                  │                  ▼
     rat-stack     REST + OpenApi.fromApi │           search + execute
       CLI         + HttpApiClient        ▼           (two MCP tools,
                                     stdio / http      sandboxed runner)

Applied 2026-09-18 (slices 1 and 2)

Applied 2026-09-18 (slices 3 and 4)

Template acceptance 2026-09-18

Scaffolded joelhooks/rat-stack-scaffold-test from the template (gh repo create --template), cloned it, and installed with a fresh pnpm store (npm_config_store_dir pointed at an empty directory). Install took 15.6s; corepack picked pnpm 11.3.0 from packageManager even with 11.10.0 on PATH. The prepare script patched tsc for @effect/tsgo and installed the lefthook hook. pnpm turbo run check test build passed: 14 tasks, 57 tests. stats README.md, catalog --types, and pnpm env:check all worked on the built output. Nothing needed fixing. The throwaway repo joelhooks/rat-stack-scaffold-test still exists (agent tooling blocks gh repo delete; Joel removes it). Rerun this after any dependency or vendor change; it is the only test of the template as a template.

Original seed plan (before slices 3 and 4)

inspectFile (input { path }, output FileStats, failure FileStatsError) is the one capability shipped, projected to stats, POST /inspectFile, and the inspectFile MCP tool. Slices 3 and 4 (catalog IR with generated types, search + execute, subprocess sandbox) are next.

Historical cautions (2026-09-18)


Last changed 2026-10-06 in 9f29173. Source on GitHub. Change log.

Content updated .