Simon-Pierre Boucher
All apps & projects
Web Platform
TypeScript

chat.spboucher.ai

A personal ChatGPT-class product over the entire OpenRouter ecosystem — not an API demo.

Live at chat.spboucher.ai: one login and one server-side API key put 409+ models from Anthropic, OpenAI, Google, Meta, Qwen, DeepSeek, and Mistral behind a single private, installable chat interface.

409+

Models in the synced catalog

15 s

SSE keep-alive ping interval

1

Server-side API key for every model

3

launchd agents (app, ngrok, backup)

14

Days of nightly backup retention

4

Usage dashboard periods (Today/7d/30d/All)

Overview

chat.spboucher.ai is a private, universal chat interface over the entire OpenRouter ecosystem: one login, one server-side API key, and 409+ models behind a single catalog. The catalog is synced dynamically from OpenRouter into SQLite rather than hand-maintained; removed models are marked Unavailable while historical conversations stay intact forever. Every message carries per-message model attribution, so the same conversation can move freely between Anthropic, OpenAI, Google, Meta, Qwen, DeepSeek, Mistral, and other providers without losing context or history.

Chat runs over a normalized SSE event protocol — generation.start, content.delta, reasoning.delta, usage — with 15-second keep-alive pings that survive ngrok and mobile radio sleep, and a stop button that truly aborts the upstream OpenRouter stream. Regeneration never destroys an answer: siblings live side by side with ‹ 1/2 › navigation so the same prompt can be compared across models. A persisted generation state machine (queued → starting → streaming → completed | cancelled | failed) lets a dropped mobile connection resync from the server, while prompt, completion, reasoning, and cached tokens plus reported cost feed a Today / 7d / 30d / All-time dashboard broken down by model.

The stack is a single Node.js process — Next.js 16 with TypeScript 5 serving both API and UI on port 3000 — backed by SQLite via better-sqlite3 in WAL mode for conversations, the message tree, generations, usage, the model catalog cache, and sessions. Hardened for a public tunnel with argon2id single-user auth, DB-backed sessions, aggressive login rate limiting, secure cookies, CSP headers, and zero unauthenticated API surface, it runs on MacLustr cluster node M4M64a under three launchd agents (app, ngrok, nightly backup), exposed via ngrok at chat.spboucher.ai as an installable, mobile-first PWA.

Key Features

One gateway, hundreds of models

409+ models from Anthropic, OpenAI, Google, Meta, Qwen, DeepSeek, Mistral, and more behind a single catalog synced dynamically from OpenRouter into SQLite — never hand-maintained.

Branching and regeneration

Regenerating never destroys an answer; sibling responses live side by side with ‹ 1/2 › navigation, so the same prompt can be compared across different models.

Real streaming that survives mobile

A normalized SSE protocol (generation.start, content.delta, reasoning.delta, usage) with 15 s keep-alive pings that survive ngrok and radio sleep; stop truly aborts the upstream stream.

Usage and cost tracking

Prompt, completion, reasoning, and cached tokens plus reported cost are persisted per generation and rolled up into a Today / 7d / 30d / All-time dashboard broken down by model.

Hardened for a public tunnel

argon2id single-user auth, DB-backed sessions, aggressive login rate limiting, Secure/HttpOnly/SameSite cookies, CSP and security headers, and zero unauthenticated API surface.

Instrument Panel PWA

Mobile-first installable PWA with ink/graphite surfaces, teal and amber accents, mono type for model IDs, and the signature Model Rail cartridge with a live context meter and price-per-1M chip.

How It Works

  1. PWA client

    The browser — phone or desktop, installed as a PWA — sends messages via POST /api/chat and consumes a server-sent event stream; every other route requires a session cookie.

  2. Single Next.js 16 process

    One Node.js process serves both the API and the UI on port 3000 on Apple Silicon node M4M64a, exposed publicly through ngrok at chat.spboucher.ai.

  3. OpenRouter client module

    A single client module (src/lib/openrouter/) normalizes errors and streaming before fanning out to Anthropic, OpenAI, Google, Meta, Qwen, DeepSeek, Mistral, and other upstream providers.

  4. Generation state machine

    Each generation is persisted through queued → starting → streaming → completed | cancelled | failed, so a dropped mobile connection resyncs from the server and cancel aborts the upstream stream.

  5. SQLite persistence and supervision

    better-sqlite3 in WAL mode stores conversations, the message tree, generations, usage, catalog cache, and sessions; three launchd agents keep the app and ngrok alive and run a nightly 03:30 backup with 14-day retention.

Tech Stack

Application

Next.js 16
TypeScript 5
SQLite (better-sqlite3, WAL)
Installable PWA

AI Gateway

OpenRouter API
Normalized SSE streaming
Dynamic model catalog sync
Generation state machine

Deployment

MacLustr node M4M64a
ngrok tunnel
chat.spboucher.ai
3 launchd agents

Highlights

  • One login and one server-side OpenRouter API key unlock a catalog of 409+ models across every major provider.
  • The model catalog syncs dynamically into SQLite; removed models are marked Unavailable while historical conversations stay intact forever.
  • Normalized SSE streaming with 15-second keep-alive pings survives ngrok and mobile radio sleep, and stop truly aborts the upstream generation.
  • Branching keeps every regenerated answer as a navigable sibling, enabling side-by-side comparison of models on the same prompt.
  • Per-generation token and cost accounting powers a Today / 7d / 30d / All-time usage dashboard broken down by model.
  • Runs as a single Node.js process on MacLustr node M4M64a under three launchd agents, with a nightly 03:30 SQLite backup and 14-day retention.

Explore chat.spboucher.ai

One private gateway to 409+ AI models — the full source is on GitHub.