The Problem

Developers and teams juggle multiple AI providers—Claude, GPT, Gemini, DeepSeek—each with its own SDK, API key, and rate limits. Tracking free-tier quotas across dozens of providers is manual and error-prone. OmniRoute consolidates all of that behind a single OpenAI-compatible endpoint.

What This Does

OmniRoute is an AI gateway that routes requests to 268+ providers (50+ free) through one API. It handles provider abstraction, quota tracking, auto-fallback, and token compression. The dashboard (src/app/(dashboard)/dashboard/) shows live free-tier budgets, and the project includes plugins for opencode (@omniroute/opencode-plugin/) and a CLI (bin/cli/) for managing providers, keys, and fallback policies.

The core logic lives in src/ (2,718 files) and open-sse/ (1,195 files). The open-sse/ directory contains the provider registry (open-sse/config/providers/index.ts) and tier configuration (open-sse/services/tierTypes.ts). The src/lib/db/secrets.ts handles secret persistence, and src/lib/oauth/ manages OAuth flows.

How It Is Wired

The system's internal call graph shows 54 resolved call edges. The most central functions—those called from the most places—are getMachineId (3 callers), normalizeSkillsProvider, isRecord, and cn (2 callers each). The module graph shows no obvious hub or cycle; the functions are spread across utilities and route handlers.

Entry points are scattered. src/app/healthz/route.ts defines GET and HEAD handlers for health checks. src/app/api/v1/responses/[...path]/route.ts handles POST requests to the main gateway. src/lib/oauth/config/index.ts exports getServerCredentials, but it is not called by anything else in the repo—suggesting it's either external-facing or dead code.

The system touches external resources: 3 functions perform cryptographic operations, 2 read/write a database, 1 calls a model for inference, and 2 read/write files. The src/lib/db/secrets.ts file is the primary database access point, handling getPersistedSecret and persistSecret. src/lib/oauth/utils/pkce.ts handles PKCE generation for OAuth flows.

How To Use It

# Clone and install
git clone https://github.com/moses-y/OmniRoute
cd OmniRoute
npm install

# Configure
cp .env.example .env
# Edit .env with your provider API keys and gateway settings

# Run with Docker
docker-compose up -d

# Or run the server directly
npm run dev

Configuration lives in .env (based on .env.example). The Docker setup includes both docker-compose.yml and docker-compose.prod.yml. The CLI (bin/cli/api.mjs) provides commands like providers, models, keys, and health for managing the gateway.

Real-World Use

A team using Claude Code and Cursor can point both tools at the OmniRoute endpoint. When Claude hits a rate limit, OmniRoute's auto-fallback routes to a free Gemini tier. The dashboard shows remaining free tokens across all providers, so the team knows when to buy credits or switch tools.

Code Health & Issues

Static analysis found 6 issues, 1 critical:

  • Critical - deploy-vps.yml workflow exposes VPS_HOST, VPS_USER, VPS_SSH_KEY to contributor-triggered jobs. A PR could exfiltrate credentials. Fix: move secret-using steps to a workflow_run job that never checks out PR code.
  • High - Third-party GitHub Actions pinned to tags (appleboy/ssh-action@v1, docker/setup-buildx-action@v4). Tag moves can execute malicious code. Fix: pin to commit SHAs.
  • High - continue-on-error on a correctness gate in docker-publish.yml (line 339). A failing test suite reports green. Fix: remove it.
  • Medium - Docker base image node:24-trixie-slim is unpinned. Fix: pin by digest.
  • Medium - 51 generated files committed to scripts/. Fix: gitignore and build in CI.
  • Low - 4 workflows lack timeout-minutes. A wedged job runs 6 hours. Fix: add timeouts.

The repo has 3,893 test files, GitHub Actions CI, and a license. Two dependencies are behind: @types/node (4 majors) and typescript (2 majors).

The Bottom Line

OmniRoute is a substantial, well-tested gateway with a wide provider catalog and genuinely useful free-tier tracking. The critical CI credential issue must be fixed before any public deployment. Teams already committed to multiple AI providers will find it valuable; single-provider users won't need it.