Inspiration
Backends break at 3 a.m., and small teams have no on-call engineer. Most monitoring tools only send an alert, and then a person has to read logs, find the bug and write the fix. We wanted a tool that does the on-call work and keeps a human in charge of what ships.
What it does
Urchin watches your backend and, when something breaks, takes the incident from first signal to a verified fix.
- Detects problems: crashes, missing heartbeats, failed deploys, an unreachable live URL, slow responses and error spikes. It also reviews each push for risky changes and smoke-checks safe routes for bugs nothing has triggered yet.
- Diagnoses with context: it uses your own AI key (Claude, Gemini or Groq), recent commits, your project map, and, if you connect Railway, Railway's deployments, logs and CPU/memory.
- Fixes through GitHub: it opens a small pull request. Traffic problems get a performance optimization (a cache, a timeout, a
LIMIT), and those always need your approval. - Runs from Telegram: each incident is one message, edited as it moves along. You tap Yes to merge, and it watches the deploy and verifies the fix.
- Rolls back automatically: if the error returns, or the service is still slow, it reverts the change.
How we built it
- Backend: Cloudflare Workers with Hono, D1 and a cron that ticks every minute.
- Login and integrations: Firebase handles sign-in, and a GitHub App gives each organization access to its repos. A read-only Railway OAuth login handles the host side.
- Incident pipeline: a state machine: detected, diagnosing, fix proposed, approval, merge, deploy, verify, resolved or reverted. It saves its state after every stage, so work continues across cron ticks.
- Dashboard: React and Vite, with a project map drawn in React Flow.
- Tests: 199 automated checks run against mocked GitHub, Telegram, Railway and AI services.
Challenges we ran into
- AI provider outages: models returned overload errors at the worst moments, so we added long retries for transient errors and Groq as an alternative.
- Platform limits: Workers only keep running about 30 seconds after responding, so a fast path starts the diagnosis and the cron carries the rest.
- Database changes: SQLite can't alter a
CHECKconstraint, so adding new incident kinds meant rebuilding the incidents table in a migration. - Railway's API: an OAuth login answers "Not Authorized" to the usual project queries. We found the workspace and log queries that do work and tested them against a real account.
- Safety: an agent that edits code needs hard limits (see next section).
Accomplishments that we're proud of
- Real end-to-end run: on a real backend, a crash produced a Telegram alert, a diagnosis, a pull request, a Yes, a merge, a deploy and a verification.
- Hard limits: it never touches env, config,
package.json, lockfiles or CI files. It makes one fix attempt per incident, and large changes are forced to ask first. - Traffic problems: the same approve-and-verify flow handles them.
- Cross-checking GitHub with the host: Railway's own deployment, log and metric data feeds the diagnosis.
What we learned
- The guardrails matter more than the model.
- Fixes should be verified by evidence, whether that's the error stopping or response times coming back.
- One message per incident is a better experience than a stream of alerts.
- Every platform's API has quirks, so test against the real service early.
What's next for Urchin
- More hosts: Vercel, Render and Fly.io, plus build-log access on Railway as an optional broader permission.
- Charts: response times and error rates in the dashboard.
- Opt-in automation: auto-merge for performance changes you've allowed.
- More channels: Slack and email alongside Telegram.
- SDKs: official ones for more languages, beyond Node.