Problem
Every tool, website, agent, system, etc., that I use has its own way of reaching me. I wanted one endpoint anything could call, with one place to see whether a Notification was delivered. Shion is that hub.
What I built
Shion is a single Bun process that runs a Discord bot and an Elysia REST API. A caller sends POST /v1/notifications with a source, level and text, and Shion delivers it to me as a Discord DM. GET /v1/status reports readiness and Notification counters, and Swagger UI is served at /docs. Every /v1 route needs a bearer token, compared against a SHA-256 digest in constant time, and a response says delivered or why delivery failed, so a Notification is never dropped silently.
Watchers, such as the one that tracks OpenCode’s models, run as their own images and send Notifications through the same API.
It runs in Docker on Ubuntu Server 26.04. The hosts are only reachable over my Tailscale tailnet, so nothing is exposed to the public internet. It is also the test case for deploying to my new dev and prod servers, AICDEV00 and AICPRD00, behind Caddy (see the Infrastructure page).
GitHub Actions runs Biome, the typecheck, the test suite and a Docker build on every pull request, and a version tag publishes multi-arch images for linux/amd64 and linux/arm64 to Docker Hub. It’s deployed using GitHub Actions connecting to my server over SSH.

Results
- Shipped v0.1.0 on 2026-10-01, then v0.1.1 the same day, which stopped publishing the mutable
latesttag on release.
Stack
TypeScript, Bun, Elysia, Discord.js, Docker Compose, GitHub Actions, release-please and WUD.