diff --git a/Claude-Web.md b/Claude-Web.md new file mode 100644 index 0000000..71c5b19 --- /dev/null +++ b/Claude-Web.md @@ -0,0 +1,109 @@ +> 🌍 [View in other languages](Languages) + + +# Providers — Claude Web + +## claude-web + +Web-cookie-based provider for **Claude AI** (`claude.ai`) using session cookie authentication. + +### How It Works + +1. User pastes their `claude.ai` session cookies into the OmniRoute dashboard +2. `ClaudeWebExecutor` transforms OpenAI-format requests to Claude Web API format +3. Requests are sent via **`tls-client-node`** with **Chrome 124 TLS fingerprint** to bypass Cloudflare Turnstile +4. Responses are streamed back via SSE (`text/event-stream`) + +### Required Cookies + +| Cookie | Purpose | Source | +| -------------- | ------------------------------ | -------------------------------------- | +| `sessionKey` | Main authentication | `claude.ai` browser session | +| `routingHint` | Anthropic routing | `claude.ai` browser session | +| `cf_clearance` | Cloudflare Turnstile clearance | Auto-set by Cloudflare after challenge | +| `__cf_bm` | Cloudflare bot management | Auto-set by Cloudflare | +| `_cfuvid` | Cloudflare visitor ID | Auto-set by Cloudflare | + +> **Note**: `cf_clearance` is bound to the TLS fingerprint of the browser that solved Cloudflare's Turnstile challenge. The `tls-client-node` library (via `claudeTlsClient.ts`) spoofs a Chrome 124 TLS handshake so the clearance token works from the OmniRoute server. + +### API Reference + +**Endpoint**: `POST /api/organizations/{orgId}/chat_conversations/{convId}/completion` + +**Required Headers**: + +``` +accept: text/event-stream +anthropic-client-platform: web_claude_ai +anthropic-device-id: +content-type: application/json +Referer: https://claude.ai/chat/{convId} +``` + +**Request Body**: + +```json +{ + "prompt": "user message", + "model": "claude-sonnet-4-6", + "timezone": "Asia/Jakarta", + "locale": "en-US", + "personalized_styles": [...], + "tools": [...], + "rendering_mode": "messages", + "create_conversation_params": { + "name": "", + "model": "claude-sonnet-4-6", + "is_temporary": false + } +} +``` + +### Architecture + +``` +User Cookies (claude.ai) + ↓ +OmniRoute Dashboard + ↓ +ClaudeWebExecutor (open-sse/executors/claude-web.ts) + ↓ Request transformation (OpenAI → Claude Web format) + ↓ +tlsFetchClaude() (open-sse/services/claudeTlsClient.ts) + ↓ Chrome 124 TLS fingerprint spoofing + ↓ +tls-client-node (Go native binding, koffi) + ↓ +claude.ai API + ↓ SSE stream +``` + +### Files + +| File | Purpose | +| ----------------------------------------------------- | ---------------------------------------------------- | +| `src/shared/constants/providers.ts` | Provider registration (WEB_COOKIE_PROVIDERS) | +| `src/lib/providers/webCookieAuth.ts` | Cookie utilities (normalize/extract session cookies) | +| `open-sse/executors/claude-web.ts` | Executor implementation | +| `open-sse/executors/index.ts` | Executor registration | +| `open-sse/services/claudeTlsClient.ts` | TLS fingerprint spoofing via tls-client-node | +| `open-sse/services/__tests__/claudeTlsClient.test.ts` | TLS client tests | +| `tests/unit/claude-web.test.ts` | Executor tests | + +### Testing + +```bash +# Unit tests +node --import tsx/esm --test tests/unit/claude-web.test.ts + +# TLS client tests +npx vitest run open-sse/services/__tests__/claudeTlsClient.test.ts +``` + +### Setup + +1. Start OmniRoute: `omniroute` +2. Go to Dashboard → Providers → Add Provider +3. Select "Web Cookie" category +4. Choose "Claude Web" +5. Paste your full cookie header from `claude.ai` browser DevTools (Network tab → Copy as fetch → Cookie header) diff --git a/Home.md b/Home.md index b33733b..928c16d 100644 --- a/Home.md +++ b/Home.md @@ -1,6 +1,6 @@ # 🚀 OmniRoute — The Free AI Gateway -**Never stop coding. Connect every AI tool to 231 providers — 50+ free — through one endpoint.** +**Never stop coding. Connect every AI tool to 237 providers — 50+ free — through one endpoint.** Plug Claude Code, Codex, Cursor, Cline, Copilot & Antigravity into FREE Claude / GPT / Gemini. Auto-fallback. @@ -12,7 +12,7 @@ Plug Claude Code, Codex, Cursor, Cline, Copilot & Antigravity into FREE Claude / | Feature | Description | |---------|-------------| -| **231 AI Providers** | OpenAI, Anthropic, Gemini, DeepSeek, Groq, xAI, Mistral, and many more | +| **237 AI Providers** | OpenAI, Anthropic, Gemini, DeepSeek, Groq, xAI, Mistral, and many more | | **50+ Free Tiers** | OAuth + free-tier providers for zero-cost AI access | | **17 Routing Strategies** | Priority, weighted, round-robin, cost-optimized, context-relay, and more | | **Token Compression** | RTK + Caveman engines save 15–95% tokens automatically | @@ -42,7 +42,7 @@ Use the **sidebar** to navigate through all documentation sections: - **[Features](Features)** — All features explained - **[Architecture](Architecture)** — System design and internals - **[API Reference](API-Reference)** — REST API documentation -- **[Providers](Provider-Reference)** — All 231 supported providers +- **[Providers](Provider-Reference)** — All 237 supported providers - **[Combos & Routing](Auto-Combo)** — Routing strategies - **[Compression](Compression-Guide)** — Token compression pipeline - **[MCP Server](MCP-Server)** — MCP tools and transports diff --git a/Plugins.md b/Plugins.md new file mode 100644 index 0000000..188e7d3 --- /dev/null +++ b/Plugins.md @@ -0,0 +1,111 @@ +> 🌍 [View in other languages](Languages) + + +# OmniRoute CLI Plugin System + +Extend the `omniroute` CLI without modifying its core. Plugins follow the `omniroute-cmd-*` naming convention, similar to `gh extension` or `kubectl plugin`. + +## Quick start + +```bash +# Install a plugin from npm +omniroute plugin install stripe + +# Install a local plugin in development +omniroute plugin install ./my-plugin + +# List installed plugins +omniroute plugin list + +# Scaffold a new plugin +omniroute plugin scaffold myplugin +cd omniroute-cmd-myplugin +omniroute plugin install . +``` + +## Plugin anatomy + +A plugin is an npm package named `omniroute-cmd-` (or `@scope/omniroute-cmd-`). + +``` +omniroute-cmd-myplugin/ +├── package.json # must have "type": "module" and "main": "index.mjs" +├── index.mjs # exports register(program, ctx) + optional meta +└── README.md +``` + +### `package.json` + +```json +{ + "name": "omniroute-cmd-myplugin", + "version": "0.1.0", + "type": "module", + "main": "index.mjs", + "engines": { "omniroute": ">=4.0.0" }, + "keywords": ["omniroute-plugin", "omniroute-cmd"] +} +``` + +### `index.mjs` + +```js +export const meta = { + name: "myplugin", + version: "0.1.0", + description: "My plugin for OmniRoute", + omnirouteApi: ">=4.0.0", +}; + +export function register(program, ctx) { + program + .command("myplugin") + .description(meta.description) + .option("-n, --name ") + .action(async (opts, cmd) => { + const gOpts = cmd.optsWithGlobals(); + const res = await ctx.apiFetch("/api/combos", { + baseUrl: gOpts.baseUrl, + apiKey: gOpts.apiKey, + }); + const data = await res.json(); + ctx.emit(data, gOpts); + }); +} +``` + +## Plugin context API + +The `ctx` object passed to `register(program, ctx)`: + +| Property | Type | Description | +| ---------------------------- | ---------------- | -------------------------------------------------- | +| `ctx.apiFetch(path, opts)` | `async function` | Authenticated fetch to the OmniRoute server | +| `ctx.emit(data, opts)` | `function` | Output in table/json/jsonl/csv per `--output` flag | +| `ctx.t(key)` | `async function` | i18n translation lookup | +| `ctx.withSpinner(label, fn)` | `async function` | Wraps async fn with ora spinner | +| `ctx.baseUrl` | `string` | Resolved base URL | +| `ctx.apiKey` | `string \| null` | API key if provided | + +## Discovery + +Plugins are discovered from: + +1. `~/.omniroute/plugins//` — user-local installs +2. `OMNIROUTE_PLUGIN_PATH` env var — custom directory + +Loading errors are caught and printed as warnings — a broken plugin never crashes the CLI. + +## Security + +Plugins run with the same Node.js process privileges as `omniroute`. Only install plugins from sources you trust. `omniroute plugin install` shows an explicit warning and requires `--yes` or interactive confirmation. + +## Publishing + +1. Ensure `package.json` has `"keywords": ["omniroute-plugin"]` +2. `npm publish` as normal +3. Users discover via `omniroute plugin search ` (searches npm registry) + +## Example plugin + +See [`examples/omniroute-cmd-hello/`](../../examples/omniroute-cmd-hello/index.mjs) for a minimal working example with `meta` + `register()`.