How to Add a New AI Provider to OmniRoute's 341-Provider Catalog
Adding an AI provider to OmniRoute requires creating a typed provider definition in the appropriate authentication category file under src/shared/constants/providers/, which the AI_PROVIDERS proxy automatically aggregates at runtime.
OmniRoute maintains its extensive catalog of 341 AI providers in a structured, Zod-validated registry. Each provider is organized by authentication family—OAuth, API key, web cookie, local, and more. This guide walks through the exact steps to extend the catalog with a new service, based on the implementation in diegosouzapw/OmniRoute.
Understand the Provider Architecture
The provider system splits definitions across multiple files by authentication method, then merges them through a lazy-loading proxy. This design keeps related providers grouped together while presenting a unified interface to the rest of the application.
The aggregation happens in src/shared/constants/providers.ts, where _PROVIDER_SECTIONS collects all category exports:
// src/shared/constants/providers.ts
const _PROVIDER_SECTIONS = [
NOAUTH_PROVIDERS,
OAUTH_PROVIDERS,
APIKEY_PROVIDERS,
WEB_COOKIE_PROVIDERS,
LOCAL_PROVIDERS,
SEARCH_PROVIDERS,
AUDIO_ONLY_PROVIDERS,
UPSTREAM_PROXY_PROVIDERS,
CLOUD_AGENT_PROVIDERS,
SYSTEM_PROVIDERS,
];
The AI_PROVIDERS proxy builds its map on first access via getOrCreateAiProviders(), which iterates through sections and assigns them to a shared object. No manual registration is required—additions appear immediately.
Step 1: Select the Authentication Category
Determine how the new service authenticates users. OmniRoute supports these categories, each with its own file in src/shared/constants/providers/:
oauth.ts— OAuth 2.0 flows (authorization code, implicit, etc.)apikey.ts— Simple API key authenticationnoauth.ts— No authentication requiredwebcookie.ts— Session-based or cookie authenticationlocal.ts— Locally-hosted models (Ollama, LM Studio, etc.)search.ts— Search-specific providersaudioonly.ts— Speech-to-text or text-to-speech servicesupstreamproxy.ts— Proxied upstream connectionscloudagent.ts— Cloud-based agent platformssystem.ts— Internal or system-defined providers
Each file exports a constant (e.g., OAUTH_PROVIDERS) containing provider definitions keyed by provider ID.
Step 2: Define the Provider Object
Add a new entry to the selected category file. The definition must satisfy the AiProviderDefinition Zod schema defined in src/shared/validation/providerSchema.ts. At minimum, include:
id— Unique identifier (kebab-case or lowercase)name— Human-readable display namealias— Short shorthand for the provider- Auth-specific fields — Vary by category (e.g.,
authUrl,tokenUrlfor OAuth;keyNamefor API key)
Here's a complete OAuth example:
// src/shared/constants/providers/oauth.ts
import { OAUTH_PROVIDERS as BASE } from "./providers/oauth";
export const OAUTH_PROVIDERS = {
...BASE,
mynewprovider: {
id: "mynewprovider",
name: "My New Provider",
alias: "mynp",
authUrl: "https://mynewprovider.com/oauth/authorize",
tokenUrl: "https://mynewprovider.com/oauth/token",
defaultModel: "gpt-4o",
supportsChat: true,
supportsEmbedding: false,
// Additional capabilities as defined in providerSchema.ts
},
};
For API key providers, the pattern differs slightly:
// src/shared/constants/providers/apikey.ts
import { APIKEY_PROVIDERS as BASE } from "./providers/apikey";
export const APIKEY_PROVIDERS = {
...BASE,
anotherprovider: {
id: "anotherprovider",
name: "Another Provider",
alias: "ap",
keyName: "ANOTHER_PROVIDER_API_KEY",
defaultBaseUrl: "https://api.anotherprovider.com/v1",
defaultModel: "claude-3-opus",
supportsChat: true,
supportsStreaming: true,
},
};
Step 3: Verify Schema Compliance
OmniRoute validates every provider at module load time. The validateProviders function in src/shared/constants/providers.ts runs Zod validation against providerSchema.ts. Any missing required fields or type mismatches throw immediately, preventing invalid providers from entering the catalog.
Before committing, check that your definition includes all fields specified in the schema for your auth category. Common optional extensions include:
supportsImageInput— Vision/multimodal capabilitysupportsToolUse— Function calling supportsupportsStreaming— Server-sent events for responsesmaxContextTokens— Maximum context window sizepricing— Per-token cost structure
Step 4: Test the Registration
Create a unit test to verify the provider appears correctly in AI_PROVIDERS:
// tests/unit/providers.test.ts
import { AI_PROVIDERS } from "@/shared/constants/providers";
test("mynewprovider is registered and valid", () => {
const provider = AI_PROVIDERS.mynewprovider;
expect(provider).toBeDefined();
expect(provider.id).toBe("mynewprovider");
expect(provider.name).toBe("My New Provider");
expect(provider.authUrl).toContain("oauth");
expect(provider.supportsChat).toBe(true);
});
The proxy resolves dynamically, so tests verify both registration and field integrity without mocking the internal structure.
Key Implementation Files
| File | Purpose |
|---|---|
src/shared/constants/providers/oauth.ts |
OAuth provider definitions (or matching auth category) |
src/shared/constants/providers.ts |
Central aggregation, validation, and AI_PROVIDERS proxy |
src/shared/validation/providerSchema.ts |
Zod schema enforcing provider structure |
tests/unit/providers.test.ts |
Validation tests for new registrations |
Summary
- Choose the correct auth category file based on the provider's authentication method
- Define a complete provider object matching the Zod schema with required
id,name,alias, and auth-specific fields - Export from the category file — the
AI_PROVIDERSproxy automatically includes new entries viaObject.assigningetOrCreateAiProviders() - Run validation — schema mismatches throw at startup, protecting catalog integrity
- Add unit tests to confirm registration and field correctness
Frequently Asked Questions
What happens if I forget a required field in the provider definition?
OmniRoute throws a runtime error during application startup. The validateProviders function in src/shared/constants/providers.ts executes Zod validation immediately after merging provider sections, surfacing missing fields or type violations before the server accepts traffic.
Can I add custom fields not in the standard schema?
Only if you first extend providerSchema.ts. The validation is strict—unrecognized fields cause startup failures. Modify src/shared/validation/providerSchema.ts to add new optional or required fields, then update all existing providers or mark them with .optional() to maintain backward compatibility.
Does adding a provider require restarting the development server?
Yes. Since AI_PROVIDERS builds its map at module load time through getOrCreateAiProviders(), changes to provider definition files are only picked up on process restart. The proxy itself is lazy (creates the map on first access), but the underlying module cache must refresh to incorporate new source code.
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 →