docs(wiki): auto-sync pages + cover counts with docs

github-actions[bot]
2026-06-29 11:40:21 +00:00
parent 3c115f10f1
commit 763c6f9f1c
3 changed files with 223 additions and 3 deletions

109
Claude-Web.md Normal file

@@ -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: <uuid>
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)

@@ -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 1595% 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

111
Plugins.md Normal file

@@ -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-<name>` (or `@scope/omniroute-cmd-<name>`).
```
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 <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/<name>/` — 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 <query>` (searches npm registry)
## Example plugin
See [`examples/omniroute-cmd-hello/`](../../examples/omniroute-cmd-hello/index.mjs) for a minimal working example with `meta` + `register()`.