Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
5edec0a
Phase 1: register the http_server protocol, function type and render …
jonaslagoni Aug 1, 2026
64753c6
feat: add inbound header deserialization for OpenAPI header models
jonaslagoni Aug 1, 2026
8599985
feat: collect per-operation server response variants from OpenAPI res…
jonaslagoni Aug 1, 2026
f79b330
feat: add HTTP server common types renderer
jonaslagoni Aug 1, 2026
481843f
feat: add per-operation HTTP server register renderer
jonaslagoni Aug 1, 2026
d401ecf
feat: dispatch OpenAPI channels per protocol and add http_server
jonaslagoni Aug 1, 2026
438e200
test: add blackbox coverage for the http_server protocol
jonaslagoni Aug 1, 2026
85e39c9
test: add runtime verification for generated HTTP server stubs
jonaslagoni Aug 1, 2026
0f0e8af
docs: add openapi-http-server example
jonaslagoni Aug 1, 2026
aaaf6aa
docs: document the http_server protocol
jonaslagoni Aug 1, 2026
892ec6e
refactor: consolidate shared HTTP client/server generator pieces
jonaslagoni Aug 1, 2026
7b930f5
fix: offer http_server in the codegen init wizard
jonaslagoni Aug 1, 2026
3eb2437
fix(mcp): accept http_server in the MCP tool schemas
jonaslagoni Aug 1, 2026
23ce79b
feat(website): surface http_server in the playground and homepage
jonaslagoni Aug 1, 2026
517de8a
test: gate the hand-maintained protocol lists outside the generator
jonaslagoni Aug 1, 2026
0fbe50f
Merge branch 'main' into add_http_server_stubs
jonaslagoni Aug 1, 2026
1bea705
docs: rewrite the http_server page for readers, not reviewers
jonaslagoni Aug 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .claude/rules/protocols.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ paths:

## Supported Protocols

NATS, Kafka, MQTT, AMQP, EventSource, HTTP Client, WebSocket
NATS, Kafka, MQTT, AMQP, EventSource, HTTP Client, HTTP Server, WebSocket

HTTP Client and HTTP Server both live under `protocols/http/`. HTTP Server is
OpenAPI-only and generates Express handler stubs — the structural inverse of the
client.

## File Structure Per Protocol

Expand Down
45 changes: 45 additions & 0 deletions .claude/skills/add-protocol/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,48 @@ Follow these steps to add `$ARGUMENTS` protocol support:
13. Write runtime tests with Docker containers
14. Add blackbox test configurations
15. Verify all tests pass: `npm run prepare:pr`

## Phase 6: Downstream surfaces

The generator is not the only place that lists protocols. The CLI wizard, the
website and the MCP server each keep their own hand-maintained copy, none of
which is generated from the Zod schema. Miss one and the protocol ships but is
unreachable from that surface.

`test/protocol-surfaces.spec.ts` enforces this list — run it and let the failure
messages drive the work:

```bash
npm run build && npm test -- --testPathPattern=protocol-surfaces
```

16. `src/commands/init.ts` — add to `AsyncAPIChannelProtocolOptions` and/or
`OpenAPIChannelProtocolOptions` depending on which inputs support it. This
also gates the `--channels-protocols` flag, so re-run
`npm run generate:commands` to refresh `docs/usage.md`.
17. `website/src/components/Playground/ConfigForm.tsx` — the `PROTOCOLS` picker.
18. `website/src/utils/configCodegen.ts` — `PROTOCOL_INPUT_COMPATIBILITY`. The
picker filters on this, so an entry missing here hides the option entirely.
19. `website/src/components/Home/Protocols/index.tsx` — the homepage marquee.
19b. `website/src/components/Home/demos.ts` — the homepage showcase. Read that
file's header comment first: every snippet must be real generator output for
the demo's *own* embedded spec, and the hand-written `index.ts` pane must
compile against it. Extract the spec, run the CLI on it, paste verbatim
(eliding long bodies with `// ...`) — never adapt a snippet from another
document or write one from memory.
20. `mcp-server/lib/data/generators.ts` — add to `protocolValues` (every MCP tool
schema derives its `z.enum` from it), plus `protocolDescriptions` and
`clientImports` in `lib/tools/integration-tools.ts` — both are
`Record<Protocol, …>`, so `tsc` will name them if you forget. Add a usage
example to `lib/data/examples.ts`.
21. Docs: a `docs/protocols/<name>.md` page, plus the protocol lists in
`README.md`, `docs/README.md`, `docs/getting-started/protocols.md`,
`docs/generators/channels.md` and `docs/generators/README.md`. Follow the
`write-docs` skill — the page is for a reader with a task, not a summary of
the PR that built it.
22. An `examples/` project, per "no feature without docs + an example".

Do **not** hand-edit `website/src/schemas/configuration-schema.json`,
`website/static/codegen.browser.mjs` or `mcp-server/lib/resources/bundled-docs.ts`.
They are generated copies, refreshed by `generate:playground` /
`generate:mcp:docs` in the release pipeline rather than in feature PRs.
92 changes: 92 additions & 0 deletions .claude/skills/write-docs/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
name: write-docs
description: Write or review user-facing documentation in docs/ so it reads for the user rather than as a record of the work that produced it
---

# Write user-facing documentation

Use this whenever you add or edit anything under `docs/`, a protocol or
generator page, an `examples/*/README.md`, or the root `README.md`.

## The failure this exists to prevent

Docs written at the end of an implementation session tend to preserve the
*conversation* rather than serve the reader. The tell is a section that answers
a question the reader never asked, but a reviewer did: why the scope was drawn
where it was, what was considered and rejected, what the author decided not to
build.

Real example. `docs/protocols/http_server.md` shipped with:

```md
## Explicit non-goals

- **No frameworks other than Express**, and no framework-agnostic core layer.
- **No listener or server construction.**
```

Three things are wrong with it. The support table two screens up already said
`Frameworks other than Express ❌`, so it is duplication. "No framework-agnostic
core layer" describes the shape of the *implementation*, which no user can act
on. And "non-goal" claims a permanent intent the project has not committed to —
multiple frameworks are a plausible future feature, and the docs should not
foreclose it.

None of the other protocol pages have such a section. It existed because it was
in the PR description.

## Capability tables answer "can I do X?"

Every row names a feature a reader might come looking for, answered `✅` / `❌`
(with a short parenthetical when `❌` needs a pointer). See the table in
`docs/protocols/http_client.md`: `Download ❌`, `XML Based API ❌`,
`Bearer Authentication ✅`.

Never phrase a row in negative space. `| Frameworks other than Express | ❌ |`
is not a feature anyone searches for, and it makes the reader reconstruct the
positive fact. When the answer is a choice rather than a yes/no, put the value
in the cell:

| Instead of | Write |
|---|---|
| `\| Frameworks other than Express \| ❌ \|` | `\| Frameworks \| Express \|` |
| `\| Protocols besides MQTT v5 \| ❌ \|` | `\| Protocol version \| MQTT v5 \|` |

And do not repeat a table row in prose further down — pick one home for the fact.

## Write for someone with a task

Every heading should name something the reader is trying to do or understand:
`Authentication`, `Base URL`, `Error handling`, `Path parameters`,
`Multi-status responses`. `docs/protocols/http_client.md` is the model — read it
before writing a new protocol page.

State what the code does, and what the reader should do about it. If a
limitation matters, say what happens and what to do instead — the reader needs
the behaviour, not the reasoning that produced it.

## Rewrites

| Instead of | Write |
|---|---|
| "Explicit non-goals" / "Out of scope" / "Deliberate omissions" | Nothing — the support table already carries `❌` rows. If a `❌` needs elaboration, put it in the table cell: `❌ (compose your own middleware)` |
| "There is no `basePath` option because none is needed" | "Mounting under a prefix needs no extra configuration" |
| "`response` and `next` are deliberately not handed over: passing them would make the contract ambiguous" | "The callback's return value is the response. Reach for `request` when you need something unmodelled" |
| "The Ajv validator is compiled once, outside the route handler" | "Validation costs no per-request compilation" |
| "This was chosen over X because Y" | Delete. Design rationale belongs in the PR description or `.claude/thoughts/`, not `docs/` |
| "Known limitation" as a trailing section | Fold into the task-shaped section it affects, under a heading naming the situation ("Multiple response bodies") |

## Before you finish

- Does every `##` name a reader task, not a project decision?
- Does anything appear twice — once in the support table, once in prose?
- Would a sentence make sense to someone who never saw the PR? If it only makes
sense as an answer to a reviewer, cut it.
- Does it claim permanent intent ("never", "non-goal", "will not support") about
something that is merely unbuilt? Say what is supported today instead.
- Are the code samples real generator output? Never write them from memory —
run the CLI, or copy from `examples/` or `test/runtime/typescript/src/`.
- New page under `docs/protocols/`? Add it to the protocol lists in `README.md`,
`docs/README.md`, `docs/getting-started/protocols.md`,
`docs/generators/channels.md` and `docs/generators/README.md` — and run
`npm test -- --testPathPattern=protocol-surfaces`, which checks exactly that.
1 change: 1 addition & 0 deletions .cursor/rules/protocols.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Current implementations:
- **AMQP**: Enterprise messaging with exchanges/queues
- **EventSource**: Server-sent events
- **HTTP Client**: RESTful API communication
- **HTTP Server**: Typed Express handler stubs from an OpenAPI document (OpenAPI-only; shares the `http/` directory with the client)
- **WebSocket**: Bidirectional communication

## Protocol File Structure
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/runtime-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ jobs:
service: ''
test-command: 'test:http'
needs-service: false
- test-type: 'HTTP Server'
service: ''
test-command: 'test:http-server'
needs-service: false
- test-type: 'Regular Tests'
service: ''
test-command: 'test:regular'
Expand Down
5 changes: 3 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## What this is

`@the-codegen-project/cli` — an oclif-based CLI (binary name `codegen`) that reads API specification documents (AsyncAPI v2/v3, OpenAPI 2.0/3.0/3.1 + Swagger, JSON Schema Draft 4/6/7) and generates TypeScript code: payload/message models, parameter models, header models, general types, protocol channel helpers (NATS, Kafka, MQTT, AMQP, EventSource, HTTP client, WebSocket), and full clients. It is a standalone repo that happens to live inside the `platform-and-services` monorepo — it uses **npm** (not the monorepo's pnpm) and requires **Node.js 22+**.
`@the-codegen-project/cli` — an oclif-based CLI (binary name `codegen`) that reads API specification documents (AsyncAPI v2/v3, OpenAPI 2.0/3.0/3.1 + Swagger, JSON Schema Draft 4/6/7) and generates TypeScript code: payload/message models, parameter models, header models, general types, protocol channel helpers (NATS, Kafka, MQTT, AMQP, EventSource, HTTP client, HTTP server, WebSocket), and full clients. It is a standalone repo that happens to live inside the `platform-and-services` monorepo — it uses **npm** (not the monorepo's pnpm) and requires **Node.js 22+**.

## Commands

Expand Down Expand Up @@ -75,4 +75,5 @@ The `.cursor/rules/*.mdc` files are the detailed, authoritative spec — read th
- Use `Logger` from `src/LoggingInterface.ts`, never `console.log`. Avoid `any` without justification, hardcoded paths, and sync file ops in generators.
- **MQTT channel code requires protocol v5** (user properties) and must topic-filter incoming messages — see `protocols.mdc`.
- Conventional commits (`feat:`, `fix:`, `docs:`, …); releases are automated via semantic-release (`.releaserc`).
- No feature without docs + an example: update `docs/`, add to `examples/`, regenerate `schemas/`.
- No feature without docs + an example: update `docs/`, add to `examples/`, regenerate `schemas/`. Anything under `docs/` is written for the reader, not as a record of the work — no "non-goals", no design rationale, no capability rows phrased in negative space (`Frameworks other than Express ❌`). Use the `write-docs` skill; `docs/protocols/http_client.md` is the model page.
- **Protocol lists are duplicated across surfaces the generator doesn't own** — the `codegen init` wizard, the website playground and homepage, and the MCP server tool schemas each keep a hand-maintained copy. `test/protocol-surfaces.spec.ts` fails with the exact file and literal to add; the `add-protocol` skill has the full checklist. Never hand-edit the generated copies (`website/src/schemas/configuration-schema.json`, `website/static/codegen.browser.mjs`, `mcp-server/lib/resources/bundled-docs.ts`) — the release pipeline regenerates those.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
- 📊 Every generator fully customizable to fit your hearts desire
- 👀 Integrate it into any project (Demos in [Next.JS](./examples/typescript-nextjs), [TypeScript Libraries](./examples/typescript-library))
- 💅 [Create custom generators to your use-case](https://the-codegen-project.org/docs/generators/custom)
- 🗄️ Protocol agnostic generator ([NATS](https://the-codegen-project.org/docs/protocols/nats), [Kafka](https://the-codegen-project.org/docs/protocols/kafka), [MQTT](https://the-codegen-project.org/docs/protocols/mqtt), [AMQP](https://the-codegen-project.org/docs/protocols/amqp), [event-source](https://the-codegen-project.org/docs/protocols/eventsource), [HTTP Client](https://the-codegen-project.org/docs/protocols/http_client), [WebSocket](https://the-codegen-project.org/docs/protocols/websocket), read the [docs](https://the-codegen-project.org/docs#protocols) for the full list and information)
- 🗄️ Protocol agnostic generator ([NATS](https://the-codegen-project.org/docs/protocols/nats), [Kafka](https://the-codegen-project.org/docs/protocols/kafka), [MQTT](https://the-codegen-project.org/docs/protocols/mqtt), [AMQP](https://the-codegen-project.org/docs/protocols/amqp), [event-source](https://the-codegen-project.org/docs/protocols/eventsource), [HTTP Client](https://the-codegen-project.org/docs/protocols/http_client), [HTTP Server](https://the-codegen-project.org/docs/protocols/http_server), [WebSocket](https://the-codegen-project.org/docs/protocols/websocket), read the [docs](https://the-codegen-project.org/docs#protocols) for the full list and information)
- ⭐ And much more...

# How it works
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Each protocol has its own limitations, corner cases, and features; thus, each ha
- [MQTT](./protocols/mqtt.md)
- [EventSource](./protocols/eventsource.md)
- [HTTP Client](./protocols/http_client.md)
- [HTTP Server](./protocols/http_server.md)
- [WebSocket client and server](./protocols/websocket.md)

### [Migrations](./migrations/README.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/generators/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ All available generators, across languages and inputs:
| OpenAPI | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| JSON Schema | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |

> OpenAPI `channels` and `client` generate an HTTP client — see the [`openapi-http-client` example](https://github.com/the-codegen-project/cli/tree/main/examples/openapi-http-client).
> OpenAPI `channels` and `client` generate an HTTP client — see the [`openapi-http-client` example](https://github.com/the-codegen-project/cli/tree/main/examples/openapi-http-client). OpenAPI `channels` can also generate the *server* side with the [`http_server`](../protocols/http_server.md) protocol — see the [`openapi-http-server` example](https://github.com/the-codegen-project/cli/tree/main/examples/openapi-http-server).

| **Languages** | [`payloads`](./payloads.md) | [`parameters`](./parameters.md) | [`headers`](./headers.md) | [`types`](./types.md) | [`channels`](./channels.md) | [`client`](./client.md) | [`models`](./models.md) | [`custom`](./custom.md) |
|---|---|---|---|---|---|---|---|---|
Expand Down
4 changes: 2 additions & 2 deletions docs/generators/channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ This is supported through the following inputs: [`asyncapi`](../inputs/asyncapi.

It supports the following languages; [`typescript`](#typescript)

It supports the following protocols; [`nats`](../protocols/nats.md), [`kafka`](../protocols/kafka.md), [`mqtt`](../protocols/mqtt.md), [`amqp`](../protocols/amqp.md), [`event_source`](../protocols/eventsource.md), [`http_client`](../protocols/http_client.md), [`websocket`](../protocols/websocket.md)
It supports the following protocols; [`nats`](../protocols/nats.md), [`kafka`](../protocols/kafka.md), [`mqtt`](../protocols/mqtt.md), [`amqp`](../protocols/amqp.md), [`event_source`](../protocols/eventsource.md), [`http_client`](../protocols/http_client.md), [`http_server`](../protocols/http_server.md), [`websocket`](../protocols/websocket.md)

## Options
These are the available options for the `channels` generator;
Expand All @@ -53,7 +53,7 @@ Depending on which protocol, these are the dependencies:
- `MQTT`: https://github.com/mqttjs/MQTT.js v5
- `AMQP`: https://github.com/amqp-node/amqplib v0
- `EventSource`: `event_source_fetch`: https://github.com/Azure/fetch-event-source v2, `event_source_express`: https://github.com/expressjs/express v4
- `HTTP`: none — uses the global `fetch` built into Node.js 18+ (the generated client relies on the native `fetch`/`Headers`; swap in `node-fetch`, `axios`, etc. via the `makeRequest` hook if needed)
- `HTTP`: `http_client`: none — uses the global `fetch` built into Node.js 18+ (the generated client relies on the native `fetch`/`Headers`; swap in `node-fetch`, `axios`, etc. via the `makeRequest` hook if needed), `http_server`: https://github.com/expressjs/express v4
- `WebSocket`: https://github.com/websockets/ws v8

For TypeScript, the generator creates one file per protocol plus an index file that re-exports all protocols as namespaces. For example;
Expand Down
1 change: 1 addition & 0 deletions docs/getting-started/protocols.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The Codegen Project currently supports these messaging protocols:
| **[AMQP](../protocols/amqp.md)** | Advanced Message Queuing Protocol | Enterprise messaging, reliable message delivery |
| **[EventSource](../protocols/eventsource.md)** | Server-Sent Events (SSE) protocol | Real-time web updates, streaming data to browsers |
| **[HTTP Client](../protocols/http_client.md)** | RESTful API communication | HTTP APIs, REST services |
| **[HTTP Server](../protocols/http_server.md)** | Typed Express handler stubs from an OpenAPI document | Implementing a REST API against its specification |
| **[WebSocket](../protocols/websocket.md)** | Full-duplex communication protocol | Real-time web applications, bidirectional communication |

## How Protocol Support Works
Expand Down
Loading
Loading