* docs: move superpowers/research artifacts to isolated _tasks repo + docs tree cleanup
- Move docs/superpowers/{plans,specs} and docs/research/* into the gitignored,
separately-versioned _tasks/ repo; untrack the two tracked research design docs.
- Add CLAUDE.md "Planning & Research Artifacts" section overriding the superpowers
default save paths (docs/... -> _tasks/...); align REPOSITORY_MAP and
DOCUMENTATION_OVERHAUL_PLAN with the new convention.
- Drop 4 now-obsolete /api/discovery/* entries from check-docs-symbols allowlist
(stale-enforcement) and refresh code/spec path comments to _tasks/...
- Sweeps in concurrent docs-tree restructuring (root-level provider/guide docs,
compression spec cleanup, .mcp.json.example removal).
* docs: reorganize docs/ tree + fix stale facts across ~26 docs
Phase A — reorganization:
- Move 7 orphan root docs into subfolders (providers/ created; TIERS+USAGE_QUOTA→guides/;
plugins+PLUGIN_SDK→frameworks/); delete 8 obsolete/redundant docs (SUBMIT_PR superseded
by CONTRIBUTING; DOCUMENTATION_OVERHAUL_PLAN; INCIDENT_RESPONSE/PERF_BUDGETS/THREAT_MODEL;
3 ops snapshots). Rebuild README index (was missing ~40 files) + per-folder meta.json nav.
- Clean 14 dangling doc-path references in bin/ ops scripts, scripts/, workflow, tests;
fix the dockerignore-docs-coverage required-docs path (PROVIDERS→providers/CLAUDE_WEB).
Phase B — content accuracy (verified against code, not the audit summary):
- Functional: ENVIRONMENT flag defaults (INPUT_SANITIZER/MCP_ENFORCE_SCOPES=true,
COMPRESS_DESCRIPTIONS=false, dynamic heap); MCP-SERVER notion tool names (omniroute_*→
notion_*) + counts 87→94; coverage gate 75/70→60/60/60/60 (RELEASE_CHECKLIST, COVERAGE_PLAN,
ERROR_SANITIZATION, CONTRIBUTING); pre-push hook description; regenerate PROVIDER_REFERENCE (237).
- Count drift: providers 237, executors 70, migrations 106, db modules 94, oauth 19,
strategies 17, MCP 94, flags 38, TS 6.0, open-sse ~900/services 294 across architecture/
frameworks/ops docs; AUTO-COMBO 9→12 factors w/ correct DEFAULT_WEIGHTS; REASONING +2
patterns; STEALTH UA defaults; AGENT_PROTOCOLS +cursor-cloud/list-capabilities;
LANGUAGE_PACKS +id pack.
- Kept Node 20 (runtime guard accepts 20.20.2+; only engines is stricter) and MCP scopes=13
(mcpScopes.ts) — both were correct in the docs; corrected only the attribution.
* docs: finish content refresh — compression engines, CLI_TOKEN merge, metadata sweep
- Compression: document the additional built-in engines (CCR, headroom, ionizer,
session-dedup) in COMPRESSION_ENGINES; clarify LLMLingua-2 is the ultra-mode SLM
backend + cross-ref the extra engines in EXTENDING_COMPRESSION; add the id
(Indonesian) language pack to LANGUAGE_PACKS.
- AUTO-COMBO: replace the orphan 'How tiers fit' weight table (stale weights) with a
pointer to the canonical 12-factor DEFAULT_WEIGHTS table.
- Security: merge CLI_TOKEN_AUTH.md (legacy 32-char SHA-256 format) into CLI_TOKEN.md
as a 'Legacy format — still accepted' section (server accepts both HMAC + legacy),
delete CLI_TOKEN_AUTH.md, drop it from the index + security nav.
- Metadata: bump stale frontmatter (version/lastUpdated) to 3.8.40/2026-06-28 across the
doc set audited this pass, and normalize the in-body 'Last updated' header lines to match.
* fix(runtime): drop Node 20 from supported range + align all docs/diagrams/counts
- Node minimum is now 22 (aligned with package.json engines). SUPPORTED_NODE_RANGE in
src/shared/utils/nodeRuntimeSupport.ts (and the bin/ mirror) drops the 20.x line →
'>=22.22.2 <23 || >=24.0.0 <27'; getNodeRuntimeSupport now rejects Node 20 as
unsupported-major. Test updated (TDD): node-runtime-support.test.ts asserts Node 20
rejected. Docs aligned (TROUBLESHOOTING ×2, TERMUX, RELEASE_CHECKLIST, CODEBASE,
CLI-TOOLS, README, llm.txt + 42 i18n llm.txt mirrors, skills/cli-serve).
- Diagrams regenerated: mcp-tools-87 -> mcp-tools-94 (34 base + pool 6 = 94) and
auto-combo-9factor -> auto-combo-12factor (correct DEFAULT_WEIGHTS); SVGs re-rendered
via mermaid-cli; doc refs + diagrams/README updated; fixed a pre-existing broken
resilience-3layers image path.
- CLAUDE.md + AGENTS.md aligned to real counts (237 providers, 94 MCP tools / 34 base,
106 migrations, 94 db modules, 12-factor auto-combo, 17 strategies); README provider
count 231 -> 237; executor count corrected to 68 (provider executors, excl base/index)
and OAuth to 18 across architecture docs. check:docs-all now passes (0 strict drift,
0 broken links); removed dead .mcp.json.example doc link.
* fix(services): update installer Node hint to >=22.22.2 (aligned with dropped Node 20)
* docs: realign counts to current release tip after rebase
The release tip advanced while this work was in flight (Gemini CLI provider/executor
removed by #5246, plus other PRs). Re-counted against the current code and updated:
providers 237->236, executors 68->67, OAuth modules 18->17, open-sse services 294->298;
regenerated PROVIDER_REFERENCE.md (236). check:docs-all passes (0 strict drift).
* docs(changelog) + i18n: record Node 20 drop + fix nodeIncompatibleHint
- CHANGELOG: add [3.8.40] entries for the Node 20.x removal (runtime) and the docs
reorganization/accuracy audit.
- i18n: nodeIncompatibleHint across all 42 locales no longer lists Node 20.x as
supported (ASCII + CJK full-width variants), aligned with the dropped Node 20.
* fix(docs): repair CI breakages from the doc moves
- test: cli-plugin-system asserted docs/dev/plugins.md exists; the file moved to
docs/frameworks/PLUGINS.md — point the test at the new path (Unit fast-path 2/2 fix).
- frontmatter: PLUGINS.md and PLUGIN_SDK.md moved into the fumadocs-indexed
docs/frameworks/ which requires a 'title' frontmatter; the missing frontmatter
failed the Next.js MDX build (dast-smoke 'invalid frontmatter'). Added frontmatter
to both, plus the providers/ docs (consistency; that folder is not indexed).
16 KiB
title, version, lastUpdated
| title | version | lastUpdated |
|---|---|---|
| 📖 Setup Guide — OmniRoute | 3.8.40 | 2026-06-28 |
📖 Setup Guide — OmniRoute
Complete setup reference for OmniRoute. For the quick version, see the Quick Start in README.
Table of Contents
- Install Methods
- CLI Tool Configuration
- Protocol Setup (MCP + A2A)
- Timeout Configuration
- Split-Port Mode
- Void Linux (xbps-src)
- Uninstalling
Install Methods
npm (recommended)
npm install -g omniroute
omniroute
Dashboard opens at http://localhost:20128 and API base URL is http://localhost:20128/v1.
pnpm
pnpm install -g omniroute
pnpm approve-builds -g # Select all packages → approve
omniroute
pnpm users:
pnpm approve-builds -gis required to enable native build scripts forbetter-sqlite3and@swc/core.
Arch Linux (AUR)
yay -S omniroute-bin
systemctl --user enable --now omniroute.service
The AUR package installs OmniRoute and provides a systemd user service.
From Source
npm install
PORT=20128 DASHBOARD_PORT=20129 NEXT_PUBLIC_BASE_URL=http://localhost:20129 npm run dev
Note:
npm installauto-generates.envfrom.env.exampleon first run. Subsequent installs will not overwrite an existing.env, so customizations are preserved. To re-seed, delete.envbefore re-running.
Docker
See the Docker Guide for complete Docker setup including Compose profiles and Caddy HTTPS.
Desktop App (Electron)
OmniRoute ships a desktop wrapper built on Electron 41 + electron-builder 26.10. Available scripts (workspace root):
npm run electron:dev # Run desktop with hot-reload
npm run electron:build # Build for current OS (auto-detected)
npm run electron:build:win # Windows installer (NSIS + portable)
npm run electron:build:mac # macOS (dmg + zip, arm64+x64)
npm run electron:build:linux # Linux (AppImage + deb + rpm)
npm run electron:smoke:packaged # Smoke-test packaged build
Releases of the desktop installers are attached to GitHub Releases. For the full Electron deep-dive (signing, IPC bridge, distros), see ELECTRON_GUIDE.md (criado em fase posterior).
Headless server (CI/automation)
For unattended setups (Docker, Kubernetes, CI), use:
omniroute setup --non-interactive
omniroute providers test-batch
Combined with env vars (INITIAL_PASSWORD, OMNIROUTE_WS_BRIDGE_SECRET, etc.), this lets you spin up an OmniRoute instance fully scriptable.
CLI Options
| Command | Description |
|---|---|
omniroute |
Start server (PORT=20128, API and dashboard on same port) |
omniroute setup |
Guided CLI onboarding for password and first provider |
omniroute doctor |
Run local health checks without starting the server |
omniroute providers |
Discover, list, validate, and test providers from CLI |
omniroute config |
CLI tool configuration — list, get, set, validate configs |
omniroute status |
Offline status dashboard — version, DB, tools, config |
omniroute logs |
Stream usage logs from the API (supports --follow) |
omniroute update |
Check for or apply OmniRoute updates |
omniroute provider |
Manage provider connections — add, list, remove, test, default |
omniroute --port 3000 |
Set canonical/API port to 3000 |
omniroute --mcp |
Start MCP server (stdio transport) |
omniroute --no-open |
Don't auto-open browser |
omniroute --help |
Show help |
Headless setup can be scripted with flags or environment variables:
omniroute setup --non-interactive --password "$OMNIROUTE_PASSWORD"
omniroute setup --non-interactive --add-provider --provider openai --api-key "$OPENAI_API_KEY"
omniroute setup --non-interactive --add-provider --provider openai --api-key "$OPENAI_API_KEY" --test-provider
Run local diagnostics without opening the dashboard:
omniroute doctor
omniroute doctor --json
omniroute doctor --no-liveness
Manage providers from SSH or scripts without opening the dashboard:
omniroute providers available
omniroute providers available --search openai
omniroute providers available --category api-key
omniroute providers list
omniroute providers test <id-or-name>
omniroute providers test-all
omniroute providers validate
CLI Tool Configuration
1) Connect Providers and Create API Key
- Open Dashboard →
Providersand connect at least one provider (OAuth or API key). - Open Dashboard →
Endpointsand create an API key. - (Optional) Open Dashboard →
Combosand set your fallback chain.
2) Point Your Coding Tool
Base URL: http://localhost:20128/v1
API Key: [copy from Endpoint page]
Model: if/kimi-k2-thinking (or any provider/model prefix)
If your editor cannot send Authorization: Bearer ..., use the tokenized compatibility base instead:
Base URL: http://localhost:20128/api/v1/vscode/YOUR_KEY/
Models URL: http://localhost:20128/api/v1/vscode/YOUR_KEY/models
Chat URL: http://localhost:20128/api/v1/vscode/YOUR_KEY/chat/completions
Ollama Tags URL: http://localhost:20128/api/v1/vscode/YOUR_KEY/api/tags
Works with Claude Code, Codex CLI, Cursor, Cline, OpenClaw, OpenCode, and OpenAI-compatible SDKs.
Auto-configure with setup-*
Instead of pasting the base URL and key by hand, let OmniRoute write each tool's own config from the live model catalog. One command per tool:
omniroute setup-codex # ~/.codex/<name>.config.toml profiles
omniroute setup-claude # ~/.claude/profiles/<name>/settings.json
omniroute setup-opencode # ~/.config/opencode/opencode.json (openai-compatible)
omniroute setup-cline # Cline CLI + VS Code extension settings
omniroute setup-kilo # Kilo Code
omniroute setup-continue # ~/.continue/config.yaml (Continue / cn)
omniroute setup-cursor # prints Cursor's in-app steps
omniroute setup-roo # Roo Code import + autoImport pointer
omniroute setup-crush # ~/.config/crush/crush.json
omniroute setup-goose # ~/.config/goose/config.yaml
omniroute setup-qwen # ~/.qwen/settings.json
omniroute setup-aider # ~/.aider.conf.yml
Each accepts --remote <url> --api-key <key> to configure a local tool against a
remote OmniRoute, plus --dry-run to preview. The launchers
omniroute launch (Claude Code) and omniroute launch-codex (Codex) spawn the CLI
with the right env injected, writing no config at all.
For the full table (what each command writes, every flag, local vs remote, base-URL
/v1 conventions), see CLI Integrations.
For detailed per-tool configuration (Claude Code, Codex CLI, Cursor, Cline, OpenClaw, Kilo Code, Copilot, and more), see the dedicated CLI Tools Guide.
Protocol Setup (MCP + A2A)
MCP Setup (Model Context Protocol)
Start MCP transport in stdio mode:
omniroute --mcp
Recommended validation flow:
# 1. Start MCP server
omniroute --mcp
# 2. From your MCP client, call:
omniroute_get_health # Should return system health
omniroute_list_combos # Should return active combos
# 3. Or run the full E2E suite:
npm run test:protocols:e2e
MCP Client Configuration
Claude Code:
claude mcp add-server omniroute --type http --url http://localhost:20128/api/mcp/stream
Cursor / Cline:
Add to your MCP settings:
{
"mcpServers": {
"omniroute": {
"command": "omniroute",
"args": ["--mcp"],
"env": {}
}
}
}
Full MCP documentation: MCP Server README — 87 tools, IDE configs, Python/TS/Go clients.
A2A Setup (Agent-to-Agent Protocol)
Verify the Agent Card:
curl http://localhost:20128/.well-known/agent.json
Send a task:
curl -X POST http://localhost:20128/a2a \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":"quickstart","method":"message/send","params":{"skill":"quota-management","messages":[{"role":"user","content":"Give me a short quota summary."}]}}'
Full A2A documentation: A2A Server README — JSON-RPC 2.0, skills, streaming, task lifecycle.
Timeout Configuration
Basic Timeouts
For most deployments, you only need these two variables:
| Variable | Default | Purpose |
|---|---|---|
REQUEST_TIMEOUT_MS |
600000 |
Shared baseline for upstream response-start timeout, hidden Undici timeouts, TLS fingerprint requests, and API bridge request/proxy timeouts |
STREAM_IDLE_TIMEOUT_MS |
inherits REQUEST_TIMEOUT_MS |
Maximum gap between streaming chunks before OmniRoute aborts the SSE stream |
Backward compatibility is preserved: existing FETCH_TIMEOUT_MS, API_BRIDGE_PROXY_TIMEOUT_MS, and other per-layer timeout vars still work and override the shared baseline.
Provider-Specific Notes
For Claude Code-compatible upstreams (anthropic-compatible-cc-*), OmniRoute derives the outbound X-Stainless-Timeout header from the resolved fetch timeout so provider-side read timeouts stay aligned with your env configuration.
For third-party Claude Code-compatible reverse proxies, OmniRoute keeps the default anthropic-beta set conservative and, when Client Cache Control is left on Auto, only forwards client-provided cache_control markers. Enable the per-connection "Enable redact-thinking beta" toggle only when the upstream specifically requires redacted Claude thinking streams.
Advanced Timeout Overrides
| Variable | Default | Purpose |
|---|---|---|
FETCH_TIMEOUT_MS |
inherits REQUEST_TIMEOUT_MS |
Upstream response-start timeout used until response headers arrive |
FETCH_HEADERS_TIMEOUT_MS |
inherits FETCH_TIMEOUT_MS |
Undici time limit for receiving upstream response headers |
FETCH_BODY_TIMEOUT_MS |
inherits FETCH_TIMEOUT_MS |
Undici time limit between upstream body chunks (0 disables it) |
FETCH_CONNECT_TIMEOUT_MS |
30000 |
Undici TCP connect timeout |
FETCH_KEEPALIVE_TIMEOUT_MS |
4000 |
Undici idle keep-alive socket timeout |
TLS_CLIENT_TIMEOUT_MS |
inherits FETCH_TIMEOUT_MS |
Timeout for TLS fingerprint requests made through wreq-js |
API_BRIDGE_PROXY_TIMEOUT_MS |
inherits REQUEST_TIMEOUT_MS or 600000 |
Timeout for /v1 proxy forwarding from API port to dashboard port |
API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS |
max(API_BRIDGE_PROXY_TIMEOUT_MS, 300000) |
Incoming request timeout on the API bridge server |
API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS |
60000 |
Incoming header timeout on the API bridge server |
API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS |
5000 |
Keep-alive timeout on the API bridge server |
API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS |
0 |
Socket inactivity timeout on the API bridge server (0 disables it) |
Note: For streaming requests,
FETCH_TIMEOUT_MSonly covers connection setup / waiting for the first upstream response. Once the stream is active, OmniRoute will only abort on an actual stall (STREAM_IDLE_TIMEOUT_MS) or Undici body inactivity (FETCH_BODY_TIMEOUT_MS).
Reverse Proxy Compatibility
If you run OmniRoute behind Nginx, Caddy, Cloudflare, or another reverse proxy, make sure the proxy timeouts are also higher than your OmniRoute stream/fetch timeouts.
Split-Port Mode
Run API and Dashboard on separate ports for advanced scenarios (reverse proxy, container networking):
PORT=20128 DASHBOARD_PORT=20129 omniroute
# API: http://localhost:20128/v1
# Dashboard: http://localhost:20129
Void Linux (xbps-src) Template
For Void Linux users, you can build a native package using xbps-src. Save this block as srcpkgs/omniroute/template:
# Template file for 'omniroute'
pkgname=omniroute
version=3.8.0
revision=1
hostmakedepends="nodejs python3 make"
depends="openssl"
short_desc="Universal AI gateway with smart routing for multiple LLM providers"
maintainer="zenobit <zenobit@disroot.org>"
license="MIT"
homepage="https://github.com/diegosouzapw/OmniRoute"
distfiles="https://github.com/diegosouzapw/OmniRoute/archive/refs/tags/v${version}.tar.gz"
# Regenerate the checksum for each release with:
# curl -L -o /tmp/omniroute.tar.gz "https://github.com/diegosouzapw/OmniRoute/archive/refs/tags/v${version}.tar.gz" && sha256sum /tmp/omniroute.tar.gz
checksum=PLACEHOLDER_REGENERATE_PER_RELEASE
system_accounts="_omniroute"
omniroute_homedir="/var/lib/omniroute"
export NODE_ENV=production
export npm_config_engine_strict=false
export npm_config_loglevel=error
export npm_config_fund=false
export npm_config_audit=false
do_build() {
local _gyp_arch
case "$XBPS_TARGET_MACHINE" in
aarch64*) _gyp_arch=arm64 ;;
armv7*|armv6*) _gyp_arch=arm ;;
i686*) _gyp_arch=ia32 ;;
*) _gyp_arch=x64 ;;
esac
NODE_ENV=development npm ci --ignore-scripts
npm run build
cp -r .next/static .next/standalone/.next/static
[ -d public ] && cp -r public .next/standalone/public || true
local _node_gyp=/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js
(cd node_modules/better-sqlite3 && node "$_node_gyp" rebuild --arch="$_gyp_arch")
local _bs3_release=.next/standalone/node_modules/better-sqlite3/build/Release
mkdir -p "$_bs3_release"
cp node_modules/better-sqlite3/build/Release/better_sqlite3.node "$_bs3_release/"
rm -rf .next/standalone/node_modules/@img
for _mod in pino-abstract-transport split2 process-warning; do
cp -r "node_modules/$_mod" .next/standalone/node_modules/
done
}
do_check() {
npm run test:unit
}
do_install() {
vmkdir usr/lib/omniroute/.next
vcopy .next/standalone/. usr/lib/omniroute/.next/standalone
for _d in \
.next/standalone/.next/server/app/dashboard \
.next/standalone/.next/server/app/dashboard/settings \
.next/standalone/.next/server/app/dashboard/providers; do
touch "${DESTDIR}/usr/lib/omniroute/${_d}/.keep"
done
cat > "${WRKDIR}/omniroute" <<'EOF'
#!/bin/sh
export PORT="${PORT:-20128}"
export DATA_DIR="${DATA_DIR:-${XDG_DATA_HOME:-${HOME}/.local/share}/omniroute}"
export APP_LOG_TO_FILE="${APP_LOG_TO_FILE:-false}"
mkdir -p "${DATA_DIR}"
exec node /usr/lib/omniroute/.next/standalone/server.js "$@"
EOF
vbin "${WRKDIR}/omniroute"
}
post_install() {
vlicense LICENSE
}
Uninstalling
| Command | Action |
|---|---|
npm run uninstall |
Removes the system app but keeps your DB and configurations in ~/.omniroute. |
npm run uninstall:full |
Removes the app AND permanently erases all configurations, keys, and databases. |
For detailed uninstall instructions across all methods, see UNINSTALL.md.