blazers

Architecture

Blazers is a single Rust binary. One process serves the REST API, the admin dashboard, WebSockets, and three server-sent-event streams; a second mode (blazers mcp serve) exposes the same data over the Model Context Protocol.

System overview

Clients curl · SDK · browser blazers serve REST API /ws upgrade SSE streams Admin UI Rate limit · auth · RBAC middleware Feature modules collections · files · webhooks · cache · cron · secrets SQLite data.db (WAL) Filesystem uploads + secrets key External services webhook endpoints · cron HTTP calls · MCP clients

Crate layout

crates/
  blazers-core/    # SQLite schema, migrations, models, wire types
  blazers-server/  # HTTP API, realtime, admin dashboard, all features
  blazers-mcp/     # MCP stdio server (blazers_* tools)
  blazers/         # thin binary: `blazers serve` / `blazers kv` / `blazers mcp serve`

blazers-core owns persistence and knows nothing about HTTP. blazers-server owns every feature and embeds the dashboard assets (public/) into the binary via rust-embed. blazers-mcp talks to the same SQLite database directly, so MCP tools and the HTTP API always agree.

Request lifecycle

Every /api/* request passes through the same middleware stack:

  1. Request logging — method, path, status, duration.
  2. CORS — permissive, so browser apps on any origin can call the API.
  3. Rate limiting — per-IP token bucket.
  4. Content-Type check — mutating requests must send application/json (multipart uploads are exempt).
  5. Body limit — 10 MiB maximum request body.
  6. Handler — JWT auth (Authorization: Bearer <token>), then RBAC role checks against the target collection/bucket.

Persistence model

Everything lives in one SQLite file inside BLAZERS_DATA:

  • collections + dynamically-created record tables — schemaless-ish records validated against the collection's JSON schema.
  • buckets + files — metadata in SQLite, bytes on the filesystem under BLAZERS_DATA/files/.
  • users, permissions — auth and RBAC.
  • webhooks, webhook_logs, secrets, cache, notifications, logs, cron_jobs, cron_job_logs, ws_connections, ws_messages, pubsub_topics, pubsub_messages.

Because it is one file, backup is a file copy and export/import is a JSON document.

Realtime fan-out

Three independent channels share the same in-process hub pattern:

  • WebSocket (/ws) — persistent bidirectional connections; the server can push to one client or broadcast to all.
  • SSE (/api/notifications/stream, /api/logs/stream, /api/pubsub/{name}/stream) — one-way server→client streams over plain HTTP, ideal for dashboards and browsers that cannot hold WebSockets.

MCP mode

blazers mcp serve starts a stdio JSON-RPC server exposing tools such as blazers_list_collections, blazers_list_records, blazers_export, and blazers_import. It reads the same BLAZERS_DATA database, so an agent can inspect and modify a running Blazers backend without HTTP credentials. blazers mcp serve --kv HOST:PORT instead proxies a remote blazers kv listener and exposes blazers_kv_* tools over the inline TCP protocol.