64d408d5ba feat(gateways): add Requesty gateway (supersedes #2241) (#2484)
* feat(gateways): add Requesty hybrid gateway

Register Requesty as an OpenAI-compatible gateway with a short curated
catalog plus public /v1/models discovery. REQUESTY_API_KEY is only
resolved for the exact https /v1 base on the global, EU, US and AP hosts.

Signed-off-by: Thibault Jaigu <thibault.jaigu@gmail.com>

* test(gateways): cover Requesty model mapping and credential boundary

Signed-off-by: Thibault Jaigu <thibault.jaigu@gmail.com>

* docs: add Requesty gateway setup

Signed-off-by: Thibault Jaigu <thibault.jaigu@gmail.com>

* test(env): cover loading REQUESTY_API_KEY from provider env files

Signed-off-by: Thibault Jaigu <thibault.jaigu@gmail.com>

* docs(env): keep the Requesty EU base URL copyable

Signed-off-by: Thibault Jaigu <thibault.jaigu@gmail.com>

* test(provider-manager): include Requesty in the preset picker order

The ProviderManager tests navigate the preset list by index, so the new
Requesty preset (between OrcaRouter and Runcrate) must be listed or the
custom-provider tests stop one row short and time out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(providers): bind saved Requesty profile keys to the canonical endpoint

Requesty's dedicated key was registered in the gateway descriptor, the
request-time credential gate and the .env allowlist, but not in the
saved-profile credential lifecycle that LLMTR and API Route use. So:

- a keyed `requesty` profile retargeted to a non-Requesty URL installed
  and persisted its saved key as OPENAI_API_KEY for that URL;
- an ambient REQUESTY_API_KEY overrode a canonical profile's saved key,
  both on profile application and on relaunch;
- tmux teammates did not receive REQUESTY_API_KEY.

Withhold the saved key for retargeted Requesty profiles in profile
application and startup persistence, manage REQUESTY_API_KEY like the
other profile dedicated keys (keyless canonical profiles keep the
ambient key; relaunch prefers the selected profile's key and never
carries it to a noncanonical URL), and forward it to teammates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(providers): keep saved Requesty keys off shell-retargeted launches

A relaunch with a shell OPENAI_BASE_URL that points a saved Requesty
profile at a non-canonical URL still carried the profile's persisted
OPENAI_API_KEY to that URL. Drop persisted generic credentials for that
retarget, as the Merge and Runcrate guards already do; explicit shell
credentials still apply.

Also require the persisted profile to be a Requesty profile before its
generic key is recovered as REQUESTY_API_KEY, so a shell retarget of
another profile to Requesty no longer adopts that profile's key over a
shell REQUESTY_API_KEY.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(providers): drop saved Requesty auth and headers on shell retarget

The Requesty retarget boundary only gated the generic OPENAI_API_KEY
selection. Requesty supports custom auth headers, so a saved profile's
credential can also ride in the OPENAI_AUTH_* trio or
ANTHROPIC_CUSTOM_HEADERS, and a shell OPENAI_BASE_URL retarget still sent
those to the new endpoint.

Apply the existing Runcrate retarget handling to a Requesty retarget away
from its saved endpoint, so every credential channel follows the same
rule. A canonical regional switch and a saved non-canonical profile
relaunched at its own URL keep their saved auth, matching profile apply.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(providers): bind saved Requesty credentials to a canonical saved URL

The Requesty retarget boundary only checked the launch URL. A profile
saved for a non-canonical Requesty-route URL and relaunched with a shell
OPENAI_BASE_URL on canonical Requesty was not treated as a retarget, so
its proxy key, REQUESTY_API_KEY, custom-auth trio and custom headers all
reached Requesty.

Profile apply already treats only a canonically saved Requesty profile's
key as a Requesty key. Use the same rule on relaunch: saved credentials
follow only between canonical Requesty URLs. Any other launch drops them,
including the dedicated-key fallback. Explicit shell credentials still
apply.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(requesty): require CLAUDE_CODE_USE_OPENAI=1 for raw env setup

Without CLAUDE_CODE_USE_OPENAI=1, startup ignores a Requesty
OPENAI_BASE_URL, OPENAI_MODEL and REQUESTY_API_KEY env and falls back to
the default OpenGateway route. The README table row and the .env.example
block listed only the base URL and model. Name the selector in both, as
the PR description already does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(requesty): bind route identity and discovery to the canonical endpoint

Requesty's credential was bound to the canonical https /v1 hosts, but
the sibling sites that apply the same boundary for LLMTR, Merge,
Command Code and API Route did not include Requesty:

- URL route resolution, active-profile and capability resolution, and
  provider validation treated any Requesty host or retargeted profile
  as `requesty`, so validation accepted REQUESTY_API_KEY for a URL whose
  requests withhold it and capability surfaces kept the Requesty route.
- Hybrid discovery forwarded a caller or saved key to a noncanonical
  base URL, and a retargeted profile still triggered startup discovery.
- A profile saved for a noncanonical URL persisted no route identity,
  so the relaunch retarget guard missed it and its saved custom auth
  and headers followed a shell retarget onto canonical Requesty.
- REQUESTY_API_KEY was not protected from settings overrides when the
  host manages the provider.

Register Requesty at each of those sites, matching its siblings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(requesty): restore REQUESTY_API_KEY after discovery tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(requesty): clear a copied Requesty key on provider switch

A saved Requesty profile mirrors its key into OPENAI_API_KEY. The
copied-key detection in applyProviderFlag listed LLMTR and the other
dedicated gateways but not Requesty, so --provider openai or openrouter
kept the Requesty key as the generic credential for the new endpoint.
An independent shell OPENAI_API_KEY is still preserved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(requesty): give a Requesty teammate override its own key

Teammates now inherit REQUESTY_API_KEY, and Requesty prefers it over
OPENAI_API_KEY. applyAgentProviderOverrideToEnv cleared and replaced the
dedicated keys of Merge, OrcaRouter, Runcrate and Command Code, but not
Requesty, so an agentModels Requesty override kept using the parent's
key. Clear it for every override and install the configured key for a
canonical Requesty endpoint.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(requesty): prefer a mirrored Requesty key over a generic key pool

The request executor treats an OPENAI_API_KEY equal to a dedicated key
(LLMTR, Command Code, and others) as that provider's key and uses it
before the generic OPENAI_API_KEYS pool. REQUESTY_API_KEY was missing
from that list. A saved Requesty profile and a Requesty teammate
override both mirror their key into OPENAI_API_KEY, so an inherited or
ambient OPENAI_API_KEYS pool was sent to Requesty instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(requesty): scope the copied Requesty key to the Requesty route

ccab79e2 let an OPENAI_API_KEY equal to REQUESTY_API_KEY take
precedence as a copied provider key on every route, so a stale mirror
could be sent to another provider such as xAI instead of its own key.
Count it as copied only when the active route is requesty. The pool
test now sets the mirrored state directly instead of running the
override helper against the shared process env.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(requesty): apply the dedicated proxy and placeholder guards to Requesty

A saved Requesty proxy profile carries the requesty route id, but
buildLaunchEnv's noncanonical-launch list and buildStartupEnvFromProfile's
retained-proxy guard did not include Requesty. Ambient OPENAI_API_KEY,
OPENAI_API_KEYS and REQUESTY_API_KEY could reach the proxy on relaunch,
and a concrete shell selection skipped the guard entirely. LLMTR,
Merge, Command Code and API Route already withhold them.

REQUESTY_API_KEY was also missing from the placeholder-aware credential
checks in validation, route credential resolution and the picker, so a
template value such as SUA_CHAVE counted as usable and beat a real
OPENAI_API_KEY.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(requesty): mirror a saved Requesty key on in-process profile apply

A saved Requesty profile reaches the env through two producers. The
startup env (buildOpenAICompatibleStartupEnv) writes the key as both
OPENAI_API_KEY and REQUESTY_API_KEY and stamps the requesty route id.
The in-process apply (applyProviderProfileToProcessEnv) wrote only
OPENAI_API_KEY. Provider-flag switch-away recognizes a copied Requesty
key only when the two match, so after applying a keyed profile and then
selecting another provider, the Requesty secret stayed in
OPENAI_API_KEY and was sent to the new endpoint. The in-process apply
now writes the same mirror and route id as startup, like the ApiSmart,
Concentrate, API Route and Command Code profiles in that block.

The README, .env.example and website note now list the US and AP
regional hosts beside EU. Those four URLs are the only ones that
receive REQUESTY_API_KEY.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(requesty): keep a saved Requesty key from passing as shell input

A keyed canonical Requesty profile writes its saved key into
REQUESTY_API_KEY, both in the startup env and, since 1ce28be5, on
in-process apply. A keyless canonical Requesty profile adopts
REQUESTY_API_KEY as shell input. Nothing recorded where that value came
from, so selecting a keyless profile after a keyed one, in process or
after a relaunch from the keyed startup file, sent requests on the
keyed profile's account.

Requesty now uses the origin marker that Runcrate already uses for the
same keyless-adoption rule. CLAUDE_CODE_PROVIDER_PROFILE_REQUESTY_KEY_SHA256
is written where the saved key is installed (profile apply, startup
bootstrap, profile update, launch env), kept across env reapply,
forwarded to teammate panes, and cleared with the rest of the profile
env. Keyless adoption and the alignment check refuse a key that carries
the marker. Genuine shell input has no marker and still authenticates a
keyless profile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(requesty): restore a keyed Requesty profile's key on reconcile

A keyed canonical Requesty profile installs its saved key as
REQUESTY_API_KEY, and the request executor prefers that variable on the
Requesty route. Settings env is merged into the process after the
profile applies. applyActiveProviderProfileFromConfig then reapplies
the profile only when isProcessEnvAlignedWithProfile reports drift, and
that check compared ApiSmart, API Route and Command Code dedicated keys
but not REQUESTY_API_KEY. A settings or shell REQUESTY_API_KEY
therefore survived reconcile and was sent instead of the selected
profile's saved key.

The alignment check now compares REQUESTY_API_KEY for a keyed canonical
Requesty profile, so reconcile restores the saved key. A keyless profile
still uses shell or settings input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(requesty): state where REQUESTY_API_KEY is sent

REQUESTY_API_KEY is sent only to the four canonical Requesty URLs. Any
other OPENAI_BASE_URL runs as a custom endpoint and uses OPENAI_API_KEY.
The README row, .env.example and website note now say so. The website
note also gains the CLAUDE_CODE_USE_OPENAI=1 raw-env requirement that
0c467009 added to the README and .env.example.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* revert(requesty): return Requesty to gateway scope

Requesty is an OpenAI-compatible gateway, like Hicap and OpenRouter,
not a first-class provider. The commits after e04177c4 added
first-class credential ownership for it: saved-profile key handling
across apply, startup, relaunch and reconcile, provider-switch cleanup,
teammate forwarding and overrides, discovery and route-identity
changes, host-managed env, placeholder registries and a key-origin
marker. Each layer exposed another lifecycle edge for review to find,
and none of it is needed for the gateway.

Restore every code and test file to e04177c4: e3b95870, 41f409bf,
7d3dbb86, 55b02074, 89417454, b81ac70f, d84546e9, 433b680a, ccab79e2,
591f4a08, 9b56ef2e, 1ce28be5, 025da9bb and 3c7caf25. Profile and
lifecycle credential handling stays on the shared gateway baseline that
Hicap and OpenRouter use on main.

The request-time gate from the original integration is kept:
REQUESTY_API_KEY is sent only to the exact https /v1 base on the
global, EU, US and AP hosts. Any other OPENAI_BASE_URL uses
OPENAI_API_KEY.

The doc fixes that still match this code are kept: the
CLAUDE_CODE_USE_OPENAI=1 raw-env note, all four hosts, and the
key-scope sentence in the README, .env.example and website entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(requesty): cover the request-time credential gate end to end

The Requesty key gate lives in resolveRouteCredentialValue and was
tested only at the resolver. Drive the real OpenAI shim with a mocked
fetch and check the Authorization header for each base URL. The four
canonical https /v1 hosts get REQUESTY_API_KEY. http, a custom port and
another host never do, and only an OPENAI_API_KEY the user set follows
them. With the gate disabled, the test fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(requesty): isolate the credential gate test env

The gate test cleared variables by prefix and restored the whole
process env. It missed the provider-selection flags, so an inherited
CLAUDE_CODE_USE_GEMINI=1 with GEMINI_API_KEY routed the request to
Gemini and failed the test. The blanket restore could also overwrite
unrelated variables. Use snapshotEnv with an explicit list of
provider-selection and request-auth variables. Snapshot it after taking
the shared lock, clear the list before each case, and restore only
those keys before releasing the lock, as CONTRIBUTING.md asks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(requesty): run the credential gate test in a fresh process

The in-process gate test depended on a hand-kept list of every variable
the OpenAI shim reads. Each review found another one: provider flags,
then OPENAI_AZURE_STYLE and the GitHub token hydration marker. Run the
requests in a child process instead, the pattern the Merge gateway
tests use. Its env is the parent's with clearManagedProfileEnv applied
(the repo's managed provider key list) and a temporary config dir. Each
case sets its own variables inside the child, so nothing inherited
reaches the request and this process's env is never changed. The test
asserts the Authorization header for every canonical and non-canonical
URL, with and without OPENAI_API_KEY, and fails when the gate is
disabled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Signed-off-by: Thibault Jaigu <thibault.jaigu@gmail.com>
Co-authored-by: Thibault Jaigu <thibault.jaigu@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 21:26:38 -08:00
2026-04-30 18:22:01 +08:00
2026-04-30 18:22:01 +08:00

OpenClaude — Open terminal for any LLM

Twigpine%2Fopenclaude | Trendshift Twigpine%2Fopenclaude | Trendshift Twigpine%2Fopenclaude | Trendshift

OpenClaude is an open-source coding-agent CLI for cloud and local model providers.

Use OpenAI-compatible APIs, Gemini, GitHub Models, Codex OAuth, Codex, Ollama, Atomic Chat, and other supported backends while keeping one terminal-first workflow: prompts, tools, agents, MCP, slash commands, and streaming output.

PR Checks Release npm downloads Discussions Discord X Security Policy License

OpenClaude is also mirrored to Twigpine: gitlawb.com/node/repos/z6MkqDnb/openclaude

Quick Start | Setup Guides | Providers | Development | VS Code Extension | Partners | Community

Partners

Twigpine logo Bankr.bot logo Atomic Chat logo Xiaomi MiMo logo Atlas Cloud logo
Twigpine Bankr.bot Atomic Chat Xiaomi MiMo Atlas Cloud
AI/ML API logo Novita AI logo ApiSmart logo Concentrate logo Exa logo
AI/ML API Novita AI ApiSmart Concentrate Exa
GMI Cloud logo
GMI Cloud

Why OpenClaude

  • One CLI across cloud APIs and local model backends — no per-provider tooling
  • Guided provider setup and saved profiles with /provider
  • Coding-agent workflows in one place: bash, file tools, grep, glob, agents, tasks, MCP, and web tools
  • A bundled VS Code extension for launch integration and theme support
  • A pixel-art hero companion who fires an arrow every time you press Enter (really — see Meet your buddy)

Quick Start

Install

OpenClaude requires Node.js >=24.22.1 for npm installs and runtime (Node 26 recommended/default). Bun is only needed for source builds and local development.

npm install -g @twigpine/openclaude@latest

Upgrading from @gitlawb/openclaude? The package moved to the @twigpine scope and the old one is no longer updated. Both packages provide the openclaude command, so npm refuses to install one over the other — remove the old one first:

npm uninstall -g @gitlawb/openclaude
npm install -g @twigpine/openclaude@latest

Your settings and sessions (~/.openclaude and ~/.openclaude.json) are not touched. Don't use --force to install over the old package instead: a later uninstall of the old one would then remove the openclaude command. If that happens, uninstall @twigpine/openclaude and install it again.

If you're on Arch Linux, you can install OpenClaude from the community-maintained AUR package:

paru -S openclaude

If the install later reports ripgrep not found, install ripgrep system-wide and confirm rg --version works in the same terminal before starting OpenClaude.

Verify / troubleshoot installed version:

openclaude --version
npm view @twigpine/openclaude dist-tags
npm install -g @twigpine/openclaude@latest

Update-lock recovery: Global updates use .update.lock in the OpenClaude configuration directory (OPENCLAUDE_CONFIG_DIR, or ~/.openclaude). Existing locks are never removed automatically, even when old, to avoid overlapping package-manager installations. If an update was interrupted, first confirm that all OpenClaude update processes and their package-manager children have stopped; then remove only .update.lock from that directory and retry openclaude update. Do not remove the lock while an update is running.

Start

openclaude

Inside OpenClaude:

  • run /provider for guided provider setup and saved profiles
  • run /onboard-github for GitHub Models onboarding
  • run /search to choose the web search backend (Exa by default) or add a search API key

Note: OpenClaude does not automatically load project .env files. We recommend using the /provider command for setup, which saves provider profiles and credentials in .openclaude-profile.json. If you prefer environment variables, export them explicitly or run openclaude --provider-env-file .env for provider/setup variables. Export runtime/debug knobs from your shell or launcher.

Resume or fork a conversation

Resume an existing conversation by session ID, or continue the most recent conversation in the current directory:

openclaude --resume <session-id>
openclaude --continue

Add --fork-session to branch the conversation history into a new session ID instead of reusing the original transcript:

openclaude --resume <session-id> --fork-session
openclaude --continue --fork-session

Forking is conversation branching only. It does not create filesystem isolation, copy your working tree, or create a git worktree branch.

Manage saved conversations

Run /sessions inside OpenClaude to list this project's saved conversations. Press Enter on one to Resume, Delete (asks for confirmation, defaulting to Cancel), or go Back to the list. As a shortcut, press d on a row and then d again to delete it; any other key in between cancels. Deleting removes the transcript and its sidecar files from disk and cannot be undone. The session you are currently in is not listed and cannot be deleted.

In /resume, type a search query, then press Down and Enter on Search deeply using a background model to search conversation contents with the background search model, which can differ from the active chat model. This explicit action sends transcript excerpts and session metadata to the model provider, including from loaded sessions that do not match the query locally. Ordinary filtering stays local. Deep search considers up to 100 loaded sessions within the active filters, so older history may not be included. Transcript extraction uses up to 100 messages (the first 50 and last 50 for longer sessions), then keeps only the first 2,000 extracted characters. Matches outside that excerpt may be missed. Results remain available as more history loads; changing the query or active filters clears the previous search. If a search fails, the picker shows an error and lets you retry the same query.

Background sessions

Run long non-interactive prompts detached from the current terminal:

openclaude --bg "fix failing tests"
openclaude --bg --name auth-refactor "refactor auth middleware"
openclaude ps
openclaude logs auth-refactor
openclaude logs auth-refactor -f
openclaude kill auth-refactor

Background sessions are local child processes. OpenClaude does not start a daemon or network service, and permission/provider/model/settings flags are passed to the child process the same way they are for a foreground --print run. Session metadata and logs are stored under the resolved OpenClaude config directory, usually ~/.openclaude/bg-sessions/; OPENCLAUDE_CONFIG_DIR can point OpenClaude somewhere else. CLAUDE_CONFIG_DIR is ignored for OpenClaude background-session storage. Session names can be reused after older sessions reach a terminal state; use the session ID to inspect older logs with the same name. A naturally finished session is recorded as exited when its process returns zero and failed when it returns nonzero or handles a termination signal. stale remains the conservative result when the process disappears without an observed outcome; an explicit successful openclaude kill is recorded as killed, and killed takes precedence over a natural exited or failed outcome for the same process. Terminal outcomes are stored separately under bg-sessions/terminal/; deleting that directory makes finished sessions fall back to liveness-derived status. OpenClaude does not infer POSIX signal names on Windows. Unobservable force termination, host crashes, and power loss remain stale on every platform.

openclaude attach <id-or-name> currently reports the matching session and points to openclaude logs <id> -f; full terminal reattach is not implemented for local background sessions yet.

OpenClaude config cutover

OpenClaude stores its own config under ~/.openclaude and ~/.openclaude.json by default. It does not read ~/.claude, project .claude/ directories, or CLAUDE_CONFIG_DIR; new users can start with an empty OpenClaude config and do not need Claude Code installed.

If you previously used OpenClaude with .claude paths, migrate intentionally: copy only the settings, commands, agents, skills, scheduled tasks, or other files you personally created for OpenClaude into the matching .openclaude location. Do not blanket-copy .claude, and do not copy Claude Code credentials or auth files. For provider authentication, prefer running OpenClaude's provider setup again or exporting provider-specific environment variables.

Fastest OpenAI setup

macOS / Linux:

export CLAUDE_CODE_USE_OPENAI=1
export OPENAI_API_KEY=sk-your-key-here
export OPENAI_MODEL=gpt-4o

openclaude

Windows PowerShell:

$env:CLAUDE_CODE_USE_OPENAI="1"
$env:OPENAI_API_KEY="sk-your-key-here"
$env:OPENAI_MODEL="gpt-4o"

openclaude

Fastest local Ollama setup

macOS / Linux:

export CLAUDE_CODE_USE_OPENAI=1
export OPENAI_BASE_URL=http://localhost:11434/v1
export OPENAI_MODEL=qwen2.5-coder:7b

openclaude

Windows PowerShell:

$env:CLAUDE_CODE_USE_OPENAI="1"
$env:OPENAI_BASE_URL="http://localhost:11434/v1"
$env:OPENAI_MODEL="qwen2.5-coder:7b"

openclaude

For Ollama, OpenClaude uses Ollama's native chat API and requests a 32768-token context window on each chat request so same-session history is not silently truncated by Ollama's OpenAI-compatible shim. Set OPENCLAUDE_OLLAMA_NUM_CTX or OLLAMA_CONTEXT_LENGTH if you need a different request-level context size. See Advanced Setup for verification with ollama ps.

Setup Guides

Beginner-friendly guides:

Advanced and source-build guides:

Supported Providers

Provider Setup Path Notes
OpenAI-compatible /provider or env vars Works with OpenAI, OpenRouter, DeepSeek, Groq, Mistral, LM Studio, and other compatible /v1 servers
Z.AI GLM Coding Plan /provider or OpenAI-compatible env vars Uses OPENAI_API_KEY at https://api.z.ai/api/coding/paas/v4, defaults to glm-5.2, and offers the vision-capable glm-5.3-flash option
AI/ML API /provider or AIMLAPI_API_KEY (setup guide) Uses https://api.aimlapi.com/v1, auto-detects the OpenAI-compatible route from AIMLAPI_API_KEY, sends OpenClaude attribution headers, and discovers chat-capable models from the public /models catalog
Merge Gateway /provider or MERGE_GATEWAY_API_KEY (setup guide) Multi-provider model router at https://api-gateway.merge.dev/v1/openai; supports Chat Completions, Responses, authenticated model discovery, and routing policies
Concentrate /provider or CONCENTRATE_API_KEY Unified OpenAI-compatible gateway at https://api.concentrate.ai/v1; defaults to deepseek-v4-flash and auto-discovers the chat model catalog
LLMTR /provider or OpenAI-compatible env vars Multi-model gateway at https://llmtr.com/v1; /provider and --provider llmtr default to deepseek/deepseek-v4-flash, while raw env setup must set OPENAI_BASE_URL=https://llmtr.com/v1 and OPENAI_MODEL; accepts LLMTR_API_KEY or OPENAI_API_KEY after the route is selected and discovers tool-capable Chat Completions models from the public catalog
Command Code /provider or OpenAI-compatible env vars Hybrid OpenAI-compatible gateway at https://api.commandcode.ai/provider/v1; /provider and --provider commandcode default to deepseek/deepseek-v4-flash, while raw env setup must set OPENAI_BASE_URL=https://api.commandcode.ai/provider/v1 and OPENAI_MODEL; requires CMD_API_KEY, COMMANDCODE_API_KEY, or the official COMMAND_CODE_API_KEY after the route is selected and discovers Chat Completions models from the public catalog. Claude models are unsupported by this Chat Completions integration
ApiSmart /provider or APISMART_API_KEY Uses https://gw.apismart.ai/v1, defaults to DEEPSEEK_V4_FLASH, and supports optional APISMART_MODEL plus authenticated model discovery
API Route /provider or API_ROUTE_API_KEY Uses https://global.api-route.com/v1, defaults to claude-sonnet-4-6, and supports optional API_ROUTE_MODEL plus authenticated model discovery
GMI Cloud /provider, --provider gmi-cloud, or env vars Uses GMI_API_KEY at https://api.gmi-serving.com/v1 and defaults to Qwen/Qwen3.8-Max; --provider gmi-cloud also reads an optional GMI_MODEL, and the model list comes from authenticated discovery
OrcaRouter /provider, or ORCAROUTER_API_KEY with --provider orcarouter OpenAI-compatible model routing gateway at https://api.orcarouter.ai/v1, defaults to openai/gpt-5.5, with orcarouter/auto smart routing and authenticated model discovery. Existing environment setups must replace OPENAI_API_KEY with ORCAROUTER_API_KEY, even when a custom authentication header supplies the request credential. Custom headers remain supported.
Runcrate /provider or RUNCRATE_API_KEY with --provider runcrate OpenAI-compatible aggregating gateway at https://api.runcrate.ai/v1, defaults to deepseek-ai/DeepSeek-V4.1-Flash, with curated open models (DeepSeek, GLM, Qwen, GPT-OSS). Existing environment setups must replace OPENAI_API_KEY with RUNCRATE_API_KEY. Custom headers remain supported.
Hicap /provider or OpenAI-compatible env vars Uses api-key auth, discovers models from unauthenticated /models, and supports Responses mode for gpt- models
Requesty /provider or OpenAI-compatible env vars OpenAI-compatible gateway at https://router.requesty.ai/v1 (regional: https://router.eu.requesty.ai/v1, https://router.us.requesty.ai/v1, https://router.ap.requesty.ai/v1); /provider and --provider requesty default to openai/gpt-5-mini, while raw env setup must set CLAUDE_CODE_USE_OPENAI=1, OPENAI_BASE_URL, and OPENAI_MODEL; accepts REQUESTY_API_KEY or OPENAI_API_KEY after the route is selected, but sends REQUESTY_API_KEY only to these four Requesty URLs (any other OPENAI_BASE_URL uses OPENAI_API_KEY), and discovers chat models from the public /models catalog
Fireworks AI /provider or env vars First-class provider with 276 curated models (DeepSeek, Qwen, Llama, Gemma, and more); uses FIREWORKS_API_KEY
LongCat /provider or env vars Meituan LongCat OpenAI-compatible API at https://api.longcat.chat/openai/v1; uses LONGCAT_API_KEY and defaults to LongCat-2.0
ClinePass /provider or env vars AI model gateway with usage limits (5hr, weekly, monthly); uses CLINE_API_KEY at https://api.cline.bot/api/v1
Gemini /provider or env vars Supports API key only
Gemini on Vertex AI --provider gemini-vertex or env vars Native Gemini requests with Google ADC or an access token; setup
GitHub Models /onboard-github Interactive onboarding with saved credentials
Codex OAuth /provider Opens ChatGPT sign-in in your browser and stores Codex credentials securely
Codex /provider Uses existing Codex CLI auth, OpenClaude secure storage, or env credentials
Twigpine Opengateway Startup default, /provider, or env vars Smart gateway at https://opengateway.gitlawb.com/v1; requires an API key from https://gitlawb.com/opengateway/keys and routes Xiaomi MiMo and other partner models by OPENAI_MODEL
OpenCode Zen /provider or env vars Pay-as-you-go AI gateway; uses OPENCODE_API_KEY via https://opencode.ai/zen/v1; shared key with OpenCode Go
OpenCode Go /provider or env vars $10/mo subscription for open models (13 models); uses OPENCODE_API_KEY via https://opencode.ai/zen/go/v1; shared key with OpenCode Zen
Xiaomi MiMo /provider or env vars OpenAI-compatible API at https://mimo.mi.com; uses MIMO_API_KEY and defaults to mimo-v2.5-pro
NEAR AI /provider or env vars Unified gateway (Claude, GPT, Gemini + TEE open models); uses NEARAI_API_KEY at https://cloud-api.near.ai/v1
Cloudflare Workers AI /provider or env vars OpenAI-compatible API at https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai/v1; uses CLOUDFLARE_API_TOKEN. Replace <ACCOUNT_ID> with your Cloudflare account id.
Ollama /provider or env vars Local inference with no API key
Atomic Chat /provider, env vars, or bun run dev:atomic-chat Local Model Provider; auto-detects loaded models
Bedrock / Vertex / Foundry env vars Anthropic-family cloud routes; Vertex is for Claude on Vertex AI, not arbitrary Model Garden models

What Works

  • Tool-driven coding workflows: Bash, file read/write/edit, grep, glob, agents, tasks, MCP, and slash commands
  • Streaming responses: Real-time token output and tool progress
  • Tool calling: Multi-step tool loops with model calls, tool execution, and follow-up responses
  • Images: URL and base64 image inputs for providers that support vision. Paste from the clipboard with Ctrl+V (Alt+V on Windows). 1080p/4K screenshots still attach. If processing fails and the image is over the 5MB payload limit or the 8000px API edge, the prompt shows that error instead of "No image found". For Anthropic requests containing more than 20 images (including retained conversation history and tool results), local images must fit within 2000×2000 pixels. On Amazon Bedrock and Google Cloud Vertex AI, document blocks also count toward that 20-block threshold. OpenClaude attempts to resize them before sending; if processing cannot produce a compliant image, it reports an actionable error rather than silently dropping attachments. Resize the affected images or start a new conversation with fewer images (or documents on those partners).
  • Provider profiles: Guided setup plus saved user-level provider profile support
  • Local and remote model backends: Cloud APIs, local servers, and Apple Silicon local inference
  • Codebase intelligence (repo map): Structural map of the repository ranked by PageRank importance, auto-injected into context when the REPO_MAP flag is enabled or the REPO_MAP environment variable is set. Inspect with /repomap (2048-token default). See docs/repo-map.md for details.
  • A companion with signature moves: A truecolor pixel-art hero who lives beside your prompt and reacts when you work. See below.

Meet Your Buddy

Run /buddy to hatch a companion — a truecolor pixel-art hero who stands beside your prompt, idles, blinks, and fires their signature move every time you submit a message:

/buddy                  hatch (first run) or pet your companion
/buddy set robinhood    the green archer — arrow shot on every Enter
/buddy set kaio         gold-haired warrior — charges a full-width energy wave
/buddy set strawhat     stretchy punch that snaps back
/buddy set merlin       twinkling sparkle stream
/buddy set kage         spinning shuriken
/buddy set ember        dragon fire with a real heat gradient
/buddy set corsair      cannonball with smoke trail
/buddy name Robin       rename your companion
/buddy set random       back to your rolled hero

Companions respect prefersReducedMotion, degrade gracefully to line art in low-color terminals, and can be silenced with /buddy mute. Requires a terminal at least 100 columns wide for the full sprite.

Provider Notes

OpenClaude supports multiple providers, but behavior is not identical across all of them.

  • Anthropic-specific features may not exist on other providers
  • Tool quality depends heavily on the selected model
  • Smaller local models can struggle with long multi-step tool flows
  • Some providers impose lower output caps than the CLI defaults, and OpenClaude adapts where possible
  • AI/ML API uses the OpenAI-compatible route, defaults to gpt-4o, and only surfaces chat-capable models from its public catalog
  • Twigpine Opengateway is the fresh-install startup default and requires an API key from https://gitlawb.com/opengateway/keys. It uses one OpenAI-compatible base URL; switch between mimo-* and google/gemini-3.1-flash-lite-preview with /model, and do not pin the base URL to /v1/xiaomi-mimo.
  • Z.AI GLM Coding Plan uses https://api.z.ai/api/coding/paas/v4 with glm-5.2 by default. On that direct route, GLM-5.3-Flash is selectable as glm-5.3-flash and accepts image input. Its OpenClaude effort choices are low, high, and xhigh, with xhigh requesting Z.AI max; GLM-5.3 and the existing GLM-5.2 query controls remain supported. These capabilities are not claimed for gateways that happen to carry the same model name.
  • Xiaomi MiMo uses api-key header auth on the direct OpenAI-compatible route and currently does not support /usage reporting in OpenClaude
  • GitHub Copilot serializes sub-agent execution by default to reduce Premium Request consumption — see Agent Routing and Step Limits for tuning

For best results, use models with strong tool/function calling support.

Agents

Route different agents to different models (cost optimization, splitting work by model strength), cap sub-agent tool steps with maxSteps, and tune GitHub Copilot sub-agent behavior. Configured via settings, agent frontmatter, and environment variables:

  • per-agent provider/model overrides via agentModels + agentRouting in ~/.openclaude/settings.json
  • model-only routes that reuse your current provider's credentials
  • built-in agents (Explore and Plan [feature-gated], verification [feature-gated: requires VERIFICATION_AGENT + tengu_hive_evidence], code-reviewer [requires diff inline]) routable by type name

See Agent Routing and Step Limits for the full guide.

Web Search and Fetch

Exa is the default web search backend. With no setup, WebSearch on non-Anthropic models uses Exa's keyless free tier, which has per-second and daily limits. Run /search to pick a backend, add an API key, or test search:

/search              # pick a backend
/search key exa      # add an Exa API key (hidden input) for higher limits
/search remove-key   # remove a saved Exa key
/search status       # show which backend handles searches
/search test         # run a test search
/search anysearch    # select AnySearch (works without a key)
/search key anysearch # optionally add an AnySearch API key in the hidden input
/search keenable     # select Keenable (works without a key)
/search key keenable # optionally add a Keenable API key in the hidden input

Other backends in the auto chain that you configure with a key (Tavily, Brave, Firecrawl, …) run before the Exa free tier, and DuckDuckGo is the last-resort fallback. When the active provider is Ollama, OpenClaude uses the signed-in local Ollama Web Search endpoint ahead of the free tier. Set OLLAMA_API_KEY to enable the hosted Ollama endpoint as a fallback. Set EXA_FREE_TIER=0 if searches should never go to Exa without a key. See Web Search Providers for every backend and option.

If you use AI/ML API as your model provider, /search aimlapi (or WEB_SEARCH_PROVIDER=aimlapi) runs searches through the AI/ML API Toolbox web/search tool with your configured AI/ML API credential: AIMLAPI_API_KEY, or OPENAI_API_KEY when OPENAI_BASE_URL is the canonical https://api.aimlapi.com/v1 endpoint. Each search is billed to your AI/ML API balance at a variable price, and every run requests a $0.025 cost limit. It is only used when you select it and never joins the auto order. See Web Search Providers for credential restrictions and request details.

AnySearch is available as an explicit backend with /search anysearch or WEB_SEARCH_PROVIDER=anysearch. ANYSEARCH_API_KEY is optional; anonymous access has lower service limits. Set ANYSEARCH_MAX_RESULTS to an integer from 1 to 10 (default 10) to control the requested result count. AnySearch does not change the auto search order.

Keenable is available as an explicit backend with /search keenable or WEB_SEARCH_PROVIDER=keenable. KEENABLE_API_KEY is optional; keyless access is rate-limited per IP. Keenable does not change the auto search order.

Note: DuckDuckGo fallback works by scraping search results and may be rate-limited, blocked, or subject to DuckDuckGo's Terms of Service.

For Anthropic-native backends and Codex responses, OpenClaude keeps the native provider web search behavior unless you pick a specific backend with /search (for example /search exa).

To select Ollama search explicitly, use WEB_SEARCH_PROVIDER=ollama. A local Ollama route uses its configured OPENAI_BASE_URL or OLLAMA_BASE_URL; hosted search sends OLLAMA_API_KEY only to https://ollama.com/api/web_search.

WebFetch works, but its basic HTTP plus HTML-to-markdown path can still fail on JavaScript-rendered sites or sites that block plain HTTP requests.

Set a Firecrawl API key if you want Firecrawl-powered search/fetch behavior:

export FIRECRAWL_API_KEY=your-key-here

With Firecrawl enabled:

  • WebSearch can use Firecrawl's search API while the Exa free tier remains the default free path for non-Claude models
  • WebFetch uses Firecrawl's scrape endpoint instead of raw HTTP, handling JS-rendered pages correctly

Free tier at firecrawl.dev includes 500 credits. The key is optional.

WebFetch can also scrape pages through the AI/ML API Toolbox with your AI/ML API key. Each fetched page is one paid Toolbox run (about $0.0013; each run requests a $0.005 cost limit), so it is used only when you choose it:

export AIMLAPI_API_KEY=your-aimlapi-key
export WEB_FETCH_PROVIDER=aimlapi

WEB_FETCH_PROVIDER=aimlapi takes precedence over a Firecrawl key for WebFetch. Having AIMLAPI_API_KEY set without it does not change how pages are fetched. See AI/ML API Setup.

Headless gRPC Server

OpenClaude can run as a headless gRPC service with bidirectional streaming — integrate its agentic capabilities into other applications, CI/CD pipelines, or custom UIs. Start it with npm run dev:grpc; a test CLI client ships with the repo. See Headless gRPC Server for configuration and client generation from src/proto/openclaude.proto.

Development

Use Node.js >=24.22.1 (Node 26 recommended/default) and Bun 1.4.4 for source builds.

bun install
bun run build
node dist/cli.mjs

Day-to-day commands:

  • bun run dev — build and launch from source
  • bun test — full unit suite (Bun's built-in runner)
  • bun test path/to/file.test.ts — focused runs for the areas you touch
  • bun run test:coverage — coverage to coverage/lcov.info plus a visual report at coverage/index.html (bun run test:coverage:ui rebuilds just the UI)
  • bun run smoke — smoke checks
  • bun run doctor:runtime, bun run verify:privacy; for PR intent scanning, use the fresh-upstream, explicit-ref workflow in the local pre-push validation contract

Focused suites: bun run test:provider, bun run test:provider-recommendation.

To benchmark the launcher module compile cache, build the CLI and run:

bun run build
bun run benchmark:startup

The benchmark and built OpenClaude launcher require Node >=24.22.1; Node 26 is recommended/default.

The benchmark defaults to 30 separate-process warm runs and 10 isolated empty-cache runs. It reports the median, IQR, MAD, first cache-populating run, first warm-up, Node/OS/CPU details, bundle size, and commit. Direct bundle timings are included only as a secondary diagnostic; the full launcher result is the decision signal. Use bun run benchmark:startup -- --warm-runs 40 --cold-runs 10 to request a larger sample set. The benchmark records results without enforcing a timing threshold in CI.

OpenClaude leaves Node's standard compile-cache controls authoritative. Set NODE_DISABLE_COMPILE_CACHE=1 to disable the optimization, including for V8 coverage runs that require uncached compilation.

Before opening or updating a PR, run the authoritative local pre-push validation contract. The commands below are useful for narrow iteration, but they do not replace that required preflight:

  • bun run build
  • bun run smoke
  • bun run test:coverage when your change affects shared runtime or provider logic
  • focused bun test ... runs for the files and flows you changed

Repository Structure

  • src/ - core CLI/runtime
  • scripts/ - build, verification, and maintenance scripts
  • docs/ - setup, contributor, and project documentation
  • vscode-extension/openclaude-vscode/ - VS Code extension
  • .github/ - repo automation, templates, and CI configuration
  • bin/ - CLI launcher entrypoints

VS Code Extension

The repo includes a VS Code extension in vscode-extension/openclaude-vscode for OpenClaude launch integration, provider-aware Control Center, in-editor chat, theme support, and optional Microsoft Foundry / Azure OpenAI configuration (endpoint, API version, deployment, API key via Secret Storage) injected into launched terminals. See that folder's README.

Security

If you believe you found a security issue, see SECURITY.md.

Community

Contributing

Contributions are welcome. For larger changes, open an issue first so the scope is clear before implementation. See Development for the build, test, and pre-PR validation commands.

Disclaimer

OpenClaude is an independent community project and is not affiliated with, endorsed by, or sponsored by Anthropic.

OpenClaude originated from the Claude Code codebase and has since been substantially modified to support multiple providers and open use. "Claude" and "Claude Code" are trademarks of Anthropic PBC. See LICENSE for details.

License

MIT for OpenClaude contributors' modifications; the derived Claude Code remains Anthropic's. See more.

S
Description
runs anywhere. uses anything
Readme
94 MiB
Languages
TypeScript 98.9%
JavaScript 0.8%
Astro 0.2%