Skip to content
← projects / Vigie

Vigie

Unified monitoring for my web projects — cookieless analytics, uptime checks, scheduled-job tracking and a public status page.

Overview
year
2026
role
Full-stack design and development
status
Live
front
Vue 3, TypeScript
back
AdonisJS, MCP
data
PostgreSQL, Redis
Vigie — full-screen map view
Vigie — overview

Context

The problem

I had a dozen projects online and no overall view: did last night's cron run? Is the API still answering? How many visitors this week? Every answer meant logging into a different server.

Plugging a third-party service into each project would have multiplied the accounts, the costs and the cookie banners. I preferred to build the single tool I was missing.

What Vigie does

  • Visit analytics with no cookie and no persistent identifier — no consent banner required
  • Uptime monitoring: regular HTTP probes with history and uptime calculation
  • Scheduled-job supervision: a cron that hasn't checked in within its window raises an alert
  • Error tracking for the application errors reported by the connected projects
  • A public status page, fed by the same data as the internal dashboard

Every monitored project has its own API key, and never sees another project's data.

Architecture

LayerChoice
APIAdonisJS v6, TypeScript, Lucid
DatabasePostgreSQL 17
InterfaceVue 3, Vite, Pinia, TypeScript
DeploymentDocker Compose on a VPS, Caddy in front, GitHub Actions on main

Everything runs in containers — postgres, redis, api, worker, web — with no Node required on the host machine. The worker handles probes and rollups outside the request cycle, which keeps the API responsive no matter how many projects are being monitored.

The client-side agent

Collecting means putting code inside someone else's page: a bug here doesn't degrade Vigie, it degrades the site being monitored. So the script stays under two kilobytes, with no cookie and no browser fingerprint — and the budget is checked at build time, so the build fails rather than shipping something heavier.

It wraps pushState and replaceState to catch navigations in a single-page app, then restores the original methods: nothing is permanently altered for the host application. A @vigie/js plugin hooks straight into the Vue 3 router instead of guessing from history events.

An MCP server, to stay in the editor

What's broken? Is this error new? Did last night's cron run? Vigie exposes six read-only tools over MCP to answer those questions without opening the dashboard.

Two deliberate choices: no writes at all — an assistant that reads gets the diagnosis wrong, an assistant that writes gets production wrong; and internal codes translated on the way out, cause: "silent agent" rather than reason: 5, because a model facing an unknown code doesn't stop, it guesses.

What I took away

The hard part wasn't collection but retention: keeping years of measurement points without blowing up the database. The answer was progressive rollup — fine-grained data ages into hourly averages, then daily ones.

Architecture

01 · API

AdonisJS v6, TypeScript, Lucid — business logic and endpoints.

02 · Data

PostgreSQL 17, progressive rollup (fine → hourly → daily) to keep retention affordable.

03 · Interface

Vue 3, Vite, Pinia — dashboard and public status page.

04 · Exposure

Docker Compose on a VPS (Caddy, GitHub Actions), plus a read-only MCP server to query monitoring from the editor.

Interface

Application errors — grouped by fingerprint, with latest occurrences and stack trace.
Scheduled jobs — state, run history and an incident when one fails.
Uptime — URL checks with response time and 30-day history.

Next project

Pyro Radar

Continue