@gnldev/server has 394 recorded weekly downloads on npm, ranking #1616 of 2,391 tracked listings.
About @gnldev/server
@gnldev/server
Exposes the createGnl registry as auto-REST + OpenAPI + SSE. Every endpoint bottoms out in runDurable → the journal, replay and the at-most-once side-effect guarantee are inherited for free. (The durable counterpart to the common auto-REST pattern.)
Install:
pnpm add @gnldev/server— or use it from a repo clone:pnpm install && pnpm -r build.
npm i @gnldev/server # peer: @gnldev/durable · dep: hono
import { createRestApi } from '@gnldev/server';
import { serve } from '@hono/node-server';
import { SqliteStorage } from '@gnldev/durable/sqlite';
const api = createRestApi({
journal: new SqliteStorage('runs.db').runs,
agents: { support: { model: 'anthropic/claude-opus-4-8', tools, guard, maxSteps: 8 } },
});
serve({ fetch: api.fetch, port: 3000 }); // on its own port
// app.mount('/api', api) // inside a Hono app
Binding it to a Node server
createRestApi returns a fetch handler — callable, and carrying .fetch. On Node, bind it with the
bridge on this package's own subpath:
import { createServer } from 'node:http';
import { toNodeHandler } from '@gnldev/server/node';
express().use('/api', toNodeHandler(api)); // Express
await fastify.register(middie); fastify.use('/api', toNodeHandler(api)); // Fastify + @fastify/middie
koa.use(c2k((req, res, _next) => toNodeHandler(api)(req, res))); // Koa + koa-connect
createServer(toNodeHandler(api)).listen(3000); // node:http
nestApp.use('/api', toNodeHandler(api)); // Nest (Express or Fastify)
Two rules, both measured on live servers rather than reasoned about:
Bind at the middleware layer, not as a route. On Fastify the difference is the whole story:
middleware runs before body parsing, a route runs after it. fastify.all('/api/*', …) looks correct,
passes every GET, and answers 400 to a perfectly good POST — because Fastify's built-in JSON parser
has already drained the stream.
On Koa, declare the third parameter. koa-connect switches on fn.length: a middleware with
fewer than three parameters is assumed not to terminate the response, so it calls next() straight
after and Koa writes its own 404 over what was already sent — measured, ERR_HTTP_HEADERS_SENT and
404 on every route. Naming next without calling it selects the branch that waits, which is what a
handler that owns the response needs.
Mount before whatever parses request bodies. A parser that runs first reads the stream to the end
and hands the result to the framework, not to us. Get it wrong and the bridge says so
(body_consumed_upstream) instead of blaming your request. Your own routes keep the parser: it still
runs for everything mounted after.
Endpoints (per agent)
| Method | Path | Description |
|---|---|---|
| GET | /agents | List of registered agent metadata (client/playground selector) |
| POST | /agents/:name/run | Durable run {runId, prompt|messages, threadId?, approvals?} → {ok, runId, text, interrupts} |
| POST | /agents/:name/stream | SSE streaming run (schema below) |
| POST | /agents/:name/resume | {runId, approvals?} — the input is read from the journal |
| GET | /runs · /runs/:id | Run summaries / journal timeline |
| GET | /runs/:id/events | SSE — follow a run already started, by any process, from Last-Event-ID (or ?after=) |
| POST | /runs/:id/cancel | Cancel a run, in whichever process executes it |
| GET | /openapi.json | Generated schema |
| GET | /health | Liveness — process is alive. No storage access. Unauthenticated |
| GET | /ready | Readiness — can serve traffic; 503 if the journal is unreachable. Unauthenticated |
Health checks
/health and /ready answer two different questions, and pointing the wrong probe at the wrong one
causes the wrong action:
/health— is the process alive? It touches nothing. A failing dependency must not make an orchestrator kill and restart a healthy process: restarting it does not reconnect your database, it only discards whatever the process still had in flight. Use this for liveness probes./ready— can it serve? It reads from the journal, with a 2s budget because an unreachable database usually hangs rather than refusing. On failure the instance leaves the load balancer while staying alive to recover. Use this for readiness/traffic probes.
Both are deliberately unauthenticated — probes run before any credential exists, and usually never get one. For the same reason they report reachability and nothing else: no agent names, no counts, no configuration, and never the underlying error, which for a database failure routinely carries the host, database and user. That detail goes to your logs.
# Kubernetes
livenessProbe: { httpGet: { path: /health, port: 3000 } }
readinessProbe: { httpGet: { path: /ready, port: 3000 } }
SSE schema (/stream)
event + JSON data: text-delta {text} · tool-call {toolCallId,toolName,input} · tool-result {...} · error {error} · interrupt {interrupts[]} (when the stream ends) · done {runId,finishReason,usage}. The same schema is also used in the @gnldev/studio playground → @gnldev/client connects to both ends.
A run outlives its connection; a reader resumes where it left off
A run executes apart from the request that started it, on the process's executor. A closed tab, a
dropped connection or a proxy timeout stops the reading, never the run; only POST /runs/:id/cancel
(or an abortSignal your own code passes) stops it. A second request for a run in flight follows the
same execution — one effect, both get the answer.…
Description from the npm listing.
- ai
- agent
- llm
- typescript
- ai-sdk
- durable
- exactly-once
- rest
- hono
- openapi
- fetch-handler
README badge
Show your rank in a README or on your website. The badge updates automatically.
Charts
Images: 30d · 1y · all time · 1600×900 dark
Adoption over time
7/30/90-day growth
Ranking history
Listing placement
Listing placement
Filled points are observed values; hollow points come from Internet Archive snapshots of the listing page. Dashed segments span periods with no observations — values between points are not interpolated.
Each band is one page of 20. Weekly downloads on a linear scale. Placement is projected from weekly downloads, so it can differ from the marketplace's own sort order. Hover a dot to see the listing.
Recent observations
Full history (1)Similar npm AI SDKs plugins
All 20 @gnldev/server alternativesData source
Weekly downloads (trailing 7 complete days) come from the official npm downloads API. Downloads include CI and mirrors and are not equivalent to installs or users. npm publishes no ratings.
Listing: https://www.npmjs.com/package/@gnldev/server. First seen Oct 21, 2026; last successful collection Oct 21, 2026. See the methodology.