Relationships
#2326 Expose Swamp as a REST/OpenAPI endpoint (for GPT Actions and other REST clients)
Opened by usefulish · 9/21/2026
Problem Statement
swamp serve exposes Swamp's automation surface as a WebSocket protocol
(workflow.search / workflow.run / workflow.run.search / … streamed as
event + done/error frames). That is great for native clients, but it is
a poor fit for the dominant user-facing integration pattern: REST/OpenAPI.
The clearest example is a ChatGPT GPT Action, which can only consume an
OpenAPI 3.0 document over HTTPS. A WebSocket-only server is unreachable from a
GPT Action, so Swamp cannot be wired into ChatGPT (or any other REST-first
tool: Zapier, Retool, a plain fetch) without every integrator hand-rolling a
translation adapter.
This is the companion to #2323 (promote CodeBuddy/WorkBuddy to first-class clients): even first-class clients would benefit from a REST surface, and the user-facing ChatGPT integration specifically needs REST, not the full CLI.
Evidence: a working adapter already exists
To prove the gap is bridgeable with what Swamp ships today, I built
packages/swamp-chatgpt-gateway in automation-factory
(https://github.com/usefulish/automation-factory). It is a thin Deno HTTP
server that:
- Opens a short-lived WebSocket to
swamp serveper request, forwarding the caller's bearer token as thebearer.<token>subprotocol (auth is delegated entirely to Swamp — the gateway holds no credentials of its own). - Translates Swamp's frames into three REST endpoints:
GET /v1/workflows→workflow.searchPOST /v1/workflows/{name}/runs→workflow.run(synchronous; returns runId + event log)GET /v1/runs/{id}→workflow.run.search
- Relies on Swamp's grant model for scoping: a token granted only
read/runonworkflow:promo-model-checkerreturns only that workflow from the search endpoint, and a run of any other workflow is denied by Swamp withAccess denied … does not have 'run' on workflow:…. "List my approved workflows" and "run only what I'm allowed to" come for free.
Verified end-to-end against a real swamp serve --auth-mode token with a
grant-scoped token:
GET /v1/workflows→[promo-model-checker](the mintlify-docs workflow is correctly hidden — noreadgrant).POST /v1/workflows/promo-model-checker/runs→200,runId+ completed event stream (status: completed).POST /v1/workflows/@usefulish/mintlify-docs/runs→502carrying Swamp'sAccess denied … does not have 'run' on workflow:@usefulish/mintlify-docs.
Protocol gotcha worth knowing for anyone building this
Non-run calls (workflow.search, workflow.run.search,
workflow.history.get) return a single response payload frame and no
terminal done frame — only workflow.run streams events and then done.
A REST adapter must resolve on the response frame for those calls, not wait
for done. (This cost one debugging cycle; documenting it so the next
integrator doesn't repeat it.)
Proposed solution
Ship a first-class REST/OpenAPI surface for Swamp rather than leaving each integrator to reimplement the WS→REST translation. Options, roughly in order of preference:
- A
swamp serve --protocol rest(or a--rest-port) mode that exposes the same operations over HTTPS with an OpenAPI document served at/openapi.json, reusing the existing auth (bearer token / OAuth) and grant scoping. This keeps a single source of truth for authorization. - A reference REST gateway binary (
swamp gateway/swamp serve --rest-adapter) maintained in-repo, so GPT Actions and other REST clients have a blessed, version-matched adapter instead of N third-party ones. - At minimum, publish a canonical OpenAPI document for the operations
Swamp already supports, plus a note that
serveis WebSocket and how to bridge it — so the integration pattern is documented, not discovered.
The three-endpoint subset above (enumerate approved / run / fetch result) is the minimal useful surface for a user-facing assistant; model methods, data, access admin, and approve/reject can follow once the transport exists.
Why now
User-facing AI integrations (ChatGPT GPT Actions, agent harnesses) are the most likely first contact a new Swamp user has with the automation surface, and they are uniformly REST/OpenAPI. Today that audience is blocked at the transport layer. The evidence adapter shows the bridge is small and that Swamp's grant model already does the hard part (authorization).
Open
No activity in this phase yet.
usefulish commented 9/21/2026, 8:54:16 PM
Related real-world evidence (2026-09-21): we built a REST/OpenAPI adapter in front of swamp serve (packages/swamp-chatgpt-gateway) so a ChatGPT GPT Action can call Swamp. Two concrete findings that argue for a native REST/OpenAPI surface:
swamp serveis WebSocket-only. The token must be passed via?token=[REDACTED-SECRET-1]Authorization: Bearer), NOT thebearer.<token>WebSocket subprotocol — Swamp secrets can contain+ / =, which are outside the RFC 6455 subprotocol charset range, so runtimes like Deno rejectnew WebSocket(url, ["bearer.<token>"])with "Invalid protocol value". A native HTTP surface removes this class of bug entirely.- Every REST client today has to reimplement the WS protocol plus that token workaround. Even a generated/stabled OpenAPI spec emitted by
swamp serve(without a built-in HTTP server) would let clients generate SDKs and drop the custom adapter.
Our adapter is committed as a compatibility shim. A welcome first step is swamp serve emitting a stable OpenAPI spec; a full HTTP surface mapping workflow.search / workflow.run / workflow.run.search would be ideal.
Sign in to post a ripple.