OpenClaw mini gateway
A minimal headless gateway that routes agent/LLM traffic on a port, with SSE streaming and OAuth device login.
OpenClaw mini gateway
Challenge
Full agent platforms are heavy when all you need is a small always-on gateway to route model and channel calls for an experiment.
What we did
A trimmed OpenClaw fork with the UI and extras removed — backend only, started with `OPENCLAW_PORT=18889 pnpm start` — so it runs as a lightweight always-on service.
Result
A small gateway you can stand up on a port to front agent or LLM traffic without running the whole OpenClaw stack.
Dev-story article
OpenClaw mini gateway: how the project was built
We started from a full agent runtime built around a chat UI and a zoo of messaging channels, but what we actually needed was none of that: a headless process that binds to a port, forwards coding-agent and LLM traffic, streams tokens back, and handles login. The tension was surgical — keep the routing, streaming, and auth internals intact while cutting out the UI, the web modules, and every channel except the one used as storage, without the app-shaped TypeScript tree refusing to emit a standalone dist.
Sections
05
Modules
05
Stack
TypeScript + Telegram
Why the project exists
Full agent platforms are heavy when all you need is a small always-on gateway to route model and channel calls for an experiment.
We started from a full agent runtime built around a chat UI and a zoo of messaging channels, but what we actually needed was none of that: a headless process that binds to a port, forwards coding-agent and LLM traffic, streams tokens back, and handles login. The tension was surgical — keep the routing, streaming, and auth internals intact while cutting out the UI, the web modules, and every channel except the one used as storage, without the app-shaped TypeScript tree refusing to emit a standalone dist.
What was built
A trimmed OpenClaw fork with the UI and extras removed — backend only, started with `OPENCLAW_PORT=18889 pnpm start` — so it runs as a lightweight always-on service.
A minimal backend-only gateway that listens on OPENCLAW_PORT and proxies requests to coding-agent providers, streaming responses over SSE. It carries device-code OAuth login for the upstream providers, per-user context keyed by an x-user-id header, and an auth mode that can be switched off entirely for local runs. Telegram remains only as a storage/channel backend; there is no UI.
Main modules and user path
Backend-only reduction: removed the UI, web modules, and every channel except Telegram, then added a minimal single-purpose gateway entry that binds on OPENCLAW_PORT and avoids the old channel dependencies
Device-code OAuth login helpers for the coding-agent providers, plus an auth.mode of 'none' so a local instance can run with no login at all
SSE streaming was the finicky part — real-time stream flushing and SSE parsing went through a revert-and-reapply cycle before the token pipe held under load
Per-user profile and memory context routed by an x-user-id header, so one gateway serves distinct users without cross-talk
Build surgery to make an app-shaped TS tree emit a clean dist: rewriting .ts import paths to .js, tuning tsc emit config, and defaulting config/state to ~/.openclaw-mini
Architecture and technology decisions
Built with TypeScript, Telegram, LLM gateways.
TypeScript on Node, built with pnpm, fed by device-code OAuth against upstream coding-agent providers and streaming back over Server-Sent Events; the bulk of the work was deletion plus getting tsc to emit a runnable standalone dist.
Result and lessons
A small gateway you can stand up on a port to front agent or LLM traffic without running the whole OpenClaw stack.
A lean headless gateway you start with one env var and one command — no UI, no channel sprawl — that logs in, routes agent traffic, and streams responses; honestly a fork trimmed to a single job rather than a new product.
Related articles
Read next
Related project stories
These projects share nearby technical or product decisions, so they show how the same principle behaves in another context.
Dev-storyCMS
A dynamic headless CMS on webedge-db — content types, media, roles, and the public read API behind our sites and their articles.
Dev-storyWebEdge public site
Our lt/en/ru site on Astro, content pulled from the WebEdge CMS.
Dev-storyPi local-model workflow
Pi extension: the local model does the work, GPT-5.6 only gates the plan and review.
Have a similar idea?
Discuss your project