# How to Set Up OAuth Providers Like Claude Code, Antigravity, Codex, Copilot, and Cursor in OmniRoute

> Easily set up OAuth providers like Claude Code, Antigravity, Codex, Copilot, and Cursor in OmniRoute. Securely store credentials via the API for seamless integration. Learn how now!

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: how-to-guide
- Published: 2026-07-04

---

**You configure OAuth providers in OmniRoute by POSTing access and refresh tokens to the `/api/v1/providers/{providerId}/connections` endpoint, which encrypts the credentials and stores them in `provider_connections` with automatic duplicate detection and token refresh.**

OmniRoute unifies LLM access through a centralized provider catalog. To set up OAuth providers like Claude Code, Antigravity, Codex, GitHub Copilot, and Cursor in OmniRoute, you register their OAuth credentials via the REST API. The platform then handles encryption, upsert logic to prevent duplicates, and automatic background refresh of access tokens.

## Understanding the OAuth Provider Catalog

OmniRoute maintains a strict registry of OAuth-only providers in [`src/shared/constants/providers/oauth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/oauth.ts). Each entry defines the provider’s ID, display name, icon, color, and authentication method.

```typescript
// src/shared/constants/providers/oauth.ts
export const OAUTH_PROVIDERS = {
  claude: {
    id: "claude",
    alias: "cc",
    name: "Claude Code",
    icon: "smart_toy",
    color: "#D97757",
    subscriptionRisk: true,
    riskNoticeVariant: "oauth",
  },
  antigravity: {
    id: "antigravity",
    name: "Antigravity",
    icon: "rocket_launch",
    color: "#F59E0B",
    subscriptionRisk: true,
    riskNoticeVariant: "oauth",
  },
  codex: {
    id: "codex",
    alias: "cx",
    name: "OpenAI Codex",
    icon: "code",
    color: "#3B82F6",
    subscriptionRisk: true,
    riskNoticeVariant: "oauth",
  },
  github: { 
    id: "github", 
    alias: "gh", 
    name: "GitHub Copilot", 
    icon: "code", 
    color: "#333333" 
  },
  cursor: {
    id: "cursor",
    alias: "cu",
    name: "Cursor IDE",
    icon: "edit_note",
    color: "00D4AA",
    subscriptionRisk: true,
    riskNoticeVariant: "oauth",
  },
};

```

The `authMethod: "oauth"` flag (implicit in this catalog) tells OmniRoute to expect encrypted access tokens and refresh tokens rather than static API keys.

## Creating OAuth Provider Connections

The public API endpoint for registering new OAuth credentials is:

```

POST /api/v1/providers/{providerId}/connections

```

This endpoint is handled by the generic route handler in `src/app/api/v1/providers/[provider]/connections/route.ts`, which forwards the payload to `createProviderConnection` in [`src/lib/db/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/providers.ts).

### Required Fields for OAuth Connections

| Field | Required | Description |
|-------|----------|-------------|
| `authType` | ✅ | Must be `"oauth"` for these providers. |
| `provider` | ✅ | The provider ID (e.g., `"claude"`, `"cursor"`). |
| `accessToken` | ✅ | OAuth access token from the provider’s token exchange. |
| `refreshToken` | ✅ | OAuth refresh token for automatic renewal. |
| `expiresAt` | ❌ | ISO-8601 timestamp of access-token expiry. |
| `email` | ❌ | User’s email, used for duplicate detection. |
| `displayName` | ❌ | Human-readable label (defaults to email). |
| `providerSpecificData` | ❌ | Provider-specific JSON (e.g., `workspaceId` for Codex). |

### Example: Adding Claude Code

```bash
curl -X POST https://my-omniroute.example.com/api/v1/providers/claude/connections \
  -H "Content-Type: application/json" \
  -d '{
        "authType": "oauth",
        "provider": "claude",
        "accessToken": "ya29.a0AfH6SM....",
        "refreshToken": "1//04iZk....",
        "expiresAt": "2027-03-01T12:34:56Z",
        "email": "alice@example.com",
        "displayName": "Alice-Claude",
        "providerSpecificData": {}
      }'

```

### Example: Adding GitHub Copilot

```bash
curl -X POST https://my-omniroute.example.com/api/v1/providers/github/connections \
  -H "Content-Type: application/json" \
  -d '{
        "authType": "oauth",
        "provider": "github",
        "accessToken": "gho_XXXXXXXXXXXXXXXXXXXX",
        "refreshToken": "ghr_XXXXXXXXXXXXXXXXXXXX",
        "expiresAt": "2027-01-15T08:00:00Z",
        "email": "bob@company.com",
        "displayName": "Bob-Copilot"
      }'

```

### Example: Adding Cursor IDE

```bash
curl -X POST https://my-omniroute.example.com/api/v1/providers/cursor/connections \
  -H "Content-Type: application/json" \
  -d '{
        "authType": "oauth",
        "provider": "cursor",
        "accessToken": "cursor-access-token",
        "refreshToken": "cursor-refresh-token",
        "expiresAt": "2026-12-31T23:59:59Z",
        "email": "carol@dev.com",
        "displayName": "Carol-Cursor"
      }'

```

## How OmniRoute Handles OAuth Storage and Security

When `createProviderConnection` in [`src/lib/db/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/providers.ts) receives a payload, it executes a four-stage pipeline:

1. **Validation** – Confirms `authType` is `"oauth"` and the provider ID exists in the catalog.
2. **Normalization** – Calls `normalizeProviderSpecificData` to standardize provider-specific fields (e.g., extracting `workspaceId` for Codex).
3. **Duplicate Detection** – Queries existing rows to prevent duplicate connections. For Codex, it matches on `email` and `workspaceId`; for others, it matches on `email` alone. If a match exists, OmniRoute upserts the record instead of inserting a new row.
4. **Encryption** – Invokes `encryptConnectionFields` to encrypt `accessToken` and `refreshToken` before writing to the SQLite `provider_connections` table.

After insertion, the function calls `_reorderConnections` to update the priority list, ensuring the new connection appears in the UI’s **Providers** page under the “OAuth Providers” tab.

## Token Refresh and Maintenance

OmniRoute automates OAuth token renewal via [`src/lib/oauth/refresh.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/oauth/refresh.ts). The background worker periodically identifies expiring tokens and calls the provider-specific refresh endpoint (e.g., for Claude Code). Upon receiving new tokens, the system invokes `updateProviderConnection` to write the updated access token and new expiry timestamp back to the database, maintaining uninterrupted access without user intervention.

## Summary

- **OAuth providers** are defined in [`src/shared/constants/providers/oauth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers/oauth.ts) with metadata and risk flags.
- **Registration** requires a `POST` to `/api/v1/providers/{providerId}/connections` with `authType: "oauth"`, `accessToken`, and `refreshToken`.
- **Duplicate detection** in [`src/lib/db/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/providers.ts) prevents multiple rows for the same credentials by matching on email and workspace identifiers.
- **Encryption** is applied to all secret fields before persistence via `encryptConnectionFields`.
- **Automatic refresh** is handled by [`src/lib/oauth/refresh.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/oauth/refresh.ts), which updates tokens silently in the background.

## Frequently Asked Questions

### What authentication method does OmniRoute use for Claude Code and Cursor?

OmniRoute uses the **OAuth** authentication method for Claude Code, Cursor, Antigravity, Codex, and GitHub Copilot. This requires obtaining an access token and refresh token from the provider’s OAuth flow, then submitting them to OmniRoute’s API endpoint, as opposed to using static API keys.

### How does OmniRoute prevent duplicate OAuth connections?

The `createProviderConnection` function in [`src/lib/db/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/providers.ts) queries the `provider_connections` table before inserting. For Codex, it checks for existing rows matching both the `email` and `workspaceId`; for other providers like Claude or Cursor, it checks the `email` alone. If a match exists, OmniRoute updates the existing record rather than creating a duplicate, preventing quota-splitting errors.

### Where are OAuth tokens stored and how are they secured?

OmniRoute stores OAuth tokens in the `provider_connections` table. Before persistence, the `encryptConnectionFields` function encrypts sensitive fields (access tokens and refresh tokens) at rest. The platform also supports `providerSpecificData` for additional metadata like workspace IDs, which are stored in the same encrypted record.

### Does OmniRoute automatically refresh expired OAuth tokens?

Yes. The [`src/lib/oauth/refresh.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/oauth/refresh.ts) module runs periodic background jobs to detect expiring tokens. When a token nears expiration, OmniRoute calls the provider’s refresh endpoint and updates the stored credentials via `updateProviderConnection`, ensuring continuous access without requiring manual re-authentication.