OmniRoute Embedded Services: The Complete Guide to 9Router, CLIProxyAPI, Mux, and Bifrost
OmniRoute provides four embedded services—9Router, CLIProxyAPI, Mux, and Bifrost—each offering lightweight sidecar processes for local AI routing, authentication proxying, background orchestration, and gateway relay functionality.
OmniRoute's embedded services architecture lets developers run managed, loopback-only services alongside the main process without external dependencies. Unlike third-party LLM providers, these services install, start, stop, and monitor entirely on the local host, with HTTP endpoints restricted to localhost only. This article examines each service's functionality, supervisory lifecycle, and practical usage based on the OmniRoute source code.
OmniRoute Embedded Services Overview
| Service | Package | Default Port | Primary Function |
|---|---|---|---|
| 9Router | 9router |
20130 | Embedded AI router for internal LLM call routing |
| CLIProxyAPI | @anthropic/cli-proxy |
Auto-assigned | Local proxy for Anthropic CLI authentication flows |
| Mux | mux |
8322 | Background agent-orchestration daemon |
| Bifrost | @maximhq/bifrost |
8080 | Go-based AI-gateway relay backend |
All four services share a unified supervisory model implemented in src/lib/services/ServiceSupervisor.ts, ensuring consistent lifecycle management and security boundaries.
9Router: Embedded AI Router
9Router acts as an internal routing provider accessible via the 9router/{sub}/{model} namespace. It exposes an OpenAI-compatible HTTP endpoint that OmniRoute treats as a first-class provider.
How 9Router Integration Works
When you target a model with the 9router/ prefix, the executor in open-sse/executors/ninerouter.ts dynamically reads the current port and injected API key, strips the prefix, and proxies your request to the running 9Router process:
curl -X POST http://localhost:20128/v1/chat/completions \
-H "Authorization: Bearer $OMNIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"9router/openai/gpt-4o-mini","messages":[{"role":"user","content":"Hello"}]}'
The installer at src/lib/services/installers/ninerouter.ts handles npm install under DATA_DIR/services/9router using execFile('npm', …) without shell interpolation, mitigating injection risks.
CLIProxyAPI: Anthropic Authentication Proxy
CLIProxyAPI provides seamless fallback for Anthropic CLI workflows. Rather than requiring an injected API key like other services, it authenticates using the host's existing Anthropic CLI configuration.
Authentication Flow Handling
When OAuth tokens expire, CLIProxyAPI automatically negotiates fresh credentials through the local proxy. This eliminates manual token refresh interruptions in automated pipelines. The installer resides at src/lib/services/installers/cliproxy.ts, spawning the cliproxy binary from the @anthropic/cli-proxy package.
Mux: Background Agent Orchestration
Mux runs as a lifecycle-managed background daemon only—it has no routing executor and never appears in the provider registry. This design suits custom tooling requiring persistent local agents without exposing HTTP endpoints through OmniRoute's routing layer.
Key characteristics:
- Runs headless on port 8322
- No
open-sse/executors/counterpart exists - Useful for scheduled tasks, file watchers, or custom automation
The installer at src/lib/services/installers/mux.ts configures the headless mux server with identical supervision guarantees as routable services.
Bifrost: AI Gateway Relay
Bifrost operates as a local relay backend for AI-gateway traffic. When the supervised Bifrost instance reports healthy, OmniRoute automatically constructs the relay base URL at http://127.0.0.1:{port} unless you explicitly override with BIFROST_BASE_URL.
The routing backend logic in src/lib/services/routingBackend.ts detects Bifrost's availability and remaps /v1/relay/ traffic accordingly, transparently integrating the Go-based gateway into request flows.
Unified Service Supervision Model
All embedded services follow a four-stage lifecycle enforced by ServiceSupervisor.ts:
Installation
npm install {package} executes under DATA_DIR/services/{name} using direct process spawning without shell interpolation. Referenced in src/lib/services/installers/ninerouter.ts and sibling installer files.
Process Spawning and Security
ServiceSupervisor spawns services with:
- Ephemeral API keys generated and AES-256-GCM encrypted at rest (
src/lib/services/apiKey.ts) - 5 MiB circular log buffer for telemetry without disk exhaustion
- Environment isolation preventing credential leakage
Health Probing
Periodic HTTP health checks from src/lib/services/healthCheck.ts promote service state to running or trigger restart/error classification. Failed health probes surface through the status API immediately.
Local-Only Access Enforcement
src/server/authz/routeGuard.ts classifies all /api/services/* routes as LOCAL_ONLY, rejecting non-loopback requests regardless of authentication. This hard-rule (#17) prevents network exposure of service management endpoints.
Managing Embedded Services via API
OmniRoute exposes REST endpoints for complete lifecycle control. All examples assume OmniRoute runs on its default port 20128.
Installation
curl -X POST http://localhost:20128/api/services/9router/install \
-H "Content-Type: application/json" \
-d '{"version":"latest"}'
Startup
curl -X POST http://localhost:20128/api/services/9router/start
Status Monitoring
curl http://localhost:20128/api/services/9router/status
Returns combined database metadata and live health state.
Log Streaming (Server-Sent Events)
curl -N http://localhost:20128/api/services/9router/logs?tail=200
Streams from the 5 MiB ring buffer maintained by ServiceSupervisor.
Auto-Start Configuration
curl -X POST http://localhost:20128/api/services/9router/auto-start \
-H "Content-Type: application/json" \
-d '{"enabled":true}'
Persists across OmniRoute restarts via src/lib/services/bootstrap.ts registration.
Key Implementation Files
| File | Responsibility |
|---|---|
src/lib/services/ServiceSupervisor.ts |
Core lifecycle, health checks, ring-buffer logging |
src/lib/services/bootstrap.ts |
Service registration at process start (port, health path, auto-start) |
src/lib/services/registry.ts |
Global tool → ServiceSupervisor map |
src/lib/services/apiKey.ts |
Per-service key generation and AES-256-GCM encryption |
src/lib/services/modelSync.ts |
Periodic model fetching to service_models table |
src/lib/services/installers/*.ts |
Package-specific npm installation logic |
open-sse/executors/ninerouter.ts |
9Router request proxying and prefix stripping |
src/server/authz/routeGuard.ts |
LOCAL_ONLY enforcement for management routes |
src/app/api/services/{name}/*/route.ts |
HTTP route handlers per service |
Summary
- 9Router (
9routerpackage, port 20130) enables internal AI routing with OpenAI-compatible endpoints, accessible via9router/{sub}/{model}provider syntax - CLIProxyAPI (
@anthropic/cli-proxy, auto port) provides transparent Anthropic CLI authentication fallback without injected credentials - Mux (
muxpackage, port 8322) runs background agent workloads without routing exposure - Bifrost (
@maximhq/bifrost, port 8080) relays AI-gateway traffic automatically when healthy - All services share supervised lifecycle management: npm installation, encrypted API key injection, health probing, and
LOCAL_ONLYaccess restrictions - Management APIs at
/api/services/*offer complete install, start, stop, status, logging, and auto-start control
Frequently Asked Questions
How do OmniRoute embedded services differ from external LLM providers?
Embedded services install and run locally on the same host as OmniRoute, managed by ServiceSupervisor.ts, whereas external providers require network egress to third-party APIs. Embedded service endpoints are hard-restricted to localhost through routeGuard.ts, and their processes receive AES-256-GCM encrypted ephemeral API keys rather than persistent credentials stored in environment variables.
Can I use 9Router to route to arbitrary OpenAI-compatible endpoints?
Yes. The 9router/{sub}/{model} pattern strips the prefix and forwards to whatever upstream the 9Router process configures. The executor at open-sse/executors/ninerouter.ts resolves the current port and credential dynamically per-request, allowing 9Router's internal routing table to evolve without OmniRoute restarts.
Why does Mux not appear as a routing target?
Mux lacks an executor implementation in open-sse/executors/ because it serves purely as a background daemon for custom tooling. It registers in src/lib/services/registry.ts for lifecycle supervision but never enters the provider registry, keeping its port 8322 interface private to local consumers you configure separately.
What happens to embedded services when OmniRoute shuts down?
ServiceSupervisor terminates child processes gracefully on exit. Services with auto-start enabled relaunch automatically when OmniRoute boots, as processed by src/lib/services/bootstrap.ts. The 5 MiB log ring buffer persists only in memory—logs must be streamed via SSE or exported before restart if retention is required.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →