# Claude Any Manual

<p align="center">
  <img src="../logo-small.png" alt="Claude Any logo" width="220">
</p>

Claude Any is a pre-launch configuration layer for Claude Code. It lets you
choose a provider, model, base URL, API key, and provider options before Claude
Code starts, while passing normal Claude Code arguments through unchanged.

Credits: One Ciel LLC

Current version: `0.1.106`

## Install

Requirements:

- Python 3.10+
- Claude Code installed as `claude`
- Node/npm (used for the install shim and optional MCP web tooling)

**Install from the npm registry (recommended):**

```sh
npm install -g @oneciel-ai/claude-any
claude-any
```

**Upgrade:**

```sh
npm install -g @oneciel-ai/claude-any@latest
claude-any version
```

When `claude-any` is already running from an npm package, its interactive
self-update uses the prefix of the currently executing package. For example,
an executable loaded from `~/.local/lib/node_modules` updates `~/.local`, while
one loaded from `/usr/local/lib/node_modules` updates `/usr/local`. This avoids
installing a newer package into a different npm prefix while the shell keeps
resolving an older executable. If that active prefix is not writable, the
update fails with the target prefix shown instead of silently writing elsewhere.
Keep only one visible install prefix when possible; startup diagnostics warn
when multiple `claude-any` installs are on `PATH`.

**Uninstall:**

```sh
npm uninstall -g @oneciel-ai/claude-any
```

### Alternative install paths

Install directly from the GitHub repository:

```sh
npm install -g https://github.com/OneCielAI/claude-any.git
claude-any
```

POSIX source install:

```sh
git clone https://github.com/OneCielAI/claude-any.git
cd claude-any
./install.sh
claude-any
```

Windows PowerShell source install:

```powershell
git clone https://github.com/OneCielAI/claude-any.git
cd claude-any
.\install.ps1
claude-any
```

On Windows, Claude Any's default config directory is
`%APPDATA%\claude-any`. Helper scripts such as the statusline and tool guard
are installed under `%LOCALAPPDATA%\claude-any\bin`, and the launcher also
searches Windows npm shims such as `%APPDATA%\npm`. Set
`CLAUDE_ANY_CONFIG_DIR` only when you intentionally want a separate config and
router identity.

### Releasing (maintainers)

The `Publish to npm` workflow is the only supported publish path. It
publishes to the registry on every push to either the `main` or the
`nightly` branch. It reads the `NPM_TOKEN` repository secret, which must
hold a granular npm access token for `@oneciel-ai/claude-any` with
*Bypass 2FA for publishing* enabled.

Do not run `npm publish` from a local checkout. Local npm auth can differ
from the GitHub Actions token and can produce misleading `E401`/`E404`
errors even when the branch-push workflow publishes successfully.

Two channels exist:

- `main` → published with npm dist-tag `latest`. Version comes from
  `package.json` verbatim. This is what `npm install -g @oneciel-ai/claude-any`
  pulls.
- `nightly` → published with npm dist-tag `nightly`. The workflow appends
  `-nightly.YYYYMMDD-HHmmss.SHORTSHA` (UTC) to the `package.json` version
  inside the CI runner only — no commit is made. Each push produces a unique
  version. Users opt in with `npm install -g @oneciel-ai/claude-any@nightly`.

Nightly flow (ongoing work):

1. Commit to `nightly`. CI runs lint + tests and `Publish to npm`
   emits a fresh `X.Y.Z-nightly.YYYYMMDD-HHmmss.SHORTSHA` artifact.
2. Push `nightly` with `git push origin nightly`; this is the publish
   trigger.
3. Real users on `latest` are unaffected; only those who explicitly
   installed `@nightly` will pull it.

Stable release flow (promoting nightly into a real release):

1. Open a PR from `nightly` to `main` using the `release.md` template
   (compare URL with `?template=release.md`).
2. The PR bumps `version` in `package.json` and `VERSION` in
   `claude_any.py` to the new stable `X.Y.Z`. Highlights since the last
   stable are written in the PR body — those bullets become the GitHub
   Release notes.
3. Merge the PR. `Publish to npm` fires on main and pushes `X.Y.Z` with
   dist-tag `latest`.
4. Create the matching GitHub Release: `gh release create vX.Y.Z
   --title "vX.Y.Z" --notes "..."`. The release is the persistent record
   of stable release notes; no changelog file is maintained.
5. Fast-forward `nightly` to `main` so subsequent nightlies sit on top
   of the just-released code:
   `git checkout nightly && git merge --ff-only main && git push origin nightly`.


macOS has not been fully tested by the maintainer yet. The project uses
portable Python and shell wrappers, so it is expected to work; please report
issues if you find them.

## Interactive Menu

Run:

```sh
claude-any
```

The menu appears before Claude Code starts. Use arrow keys to move and Enter to
edit or select:

- Language: English, Korean, Japanese, Chinese.
- Provider: Anthropic, Ollama, Ollama Cloud, DeepSeek.com, OpenCode Zen, OpenCode Go, LM Studio, vLLM, NVIDIA hosted, self-hosted NIM.
- API key: enter only when the selected provider needs one.
- Base URL: provider-aware default or custom endpoint.
- Model: provider model picker when available, custom input otherwise.
- Options: provider-specific generation, timeout, and preset settings.
- Compatibility test: checks a plain text response, a required `tool_use`, and
  a `tool_result` follow-up before launching Claude Code.
- Launch Claude Code: starts Claude Code with the selected configuration.

The lower status area shows connection checks, API-key state, provider notes,
and compatibility-test results.
For vLLM and self-hosted NIM, the compatibility test also reads `/v1/models`
when available and prints the runtime `max_model_len` next to Claude Any's
configured `context_window` and `max_output_tokens`.
If the runtime model reports one context size but Claude Any is configured for
another, the test output shows both values so you can fix either the server
startup flags or the client preset.

### LLM Option Presets

Open `LLM options`, then select `Apply preset` to apply a provider-aware preset
without editing every parameter manually. Claude Any currently includes:

- Balanced Claude Code: stable 4K-output default for normal Claude Code use.
- Coding deterministic: lower randomness for edits, scripts, and code review.
- Fast short tasks: shorter output and timeout for quick background jobs.
- Long context 65K: 65K context target with a 4K output reserve.
- Large output/report: 8K output for summaries and reports.
- Reasoning model: reasoning-friendly sampling.

The recommended preset is chosen from the current provider and model name. For
example, `coder` models prefer the coding preset, `r1`/`thinking` models prefer
the reasoning preset, and vLLM/NIM models configured for 65K context prefer the
long-context preset. For vLLM native mode, the server must still be launched
with a matching `--max-model-len`; Claude Any cannot raise the server-side
context limit from the client.

## Provider Setup

### Anthropic

Anthropic uses native Claude Code behavior by default. You can either log in
through Claude Code or use an Anthropic API key.

The model picker first uses Anthropic's `/v1/models` endpoint when an Anthropic
API key is configured. In direct Claude Native mode without an API key, Claude
Any cannot call that authenticated endpoint, so the refresh action seeds the
picker from Anthropic's public Models overview page instead. This keeps current
IDs such as `claude-opus-4-8`, `claude-sonnet-4-6`, and `claude-haiku-4-5`
visible while still allowing custom model IDs.

Claude Any stores refreshed Claude models in
`~/.config/claude-any/model-registry.json` with per-model recommendation
metadata. The registry separates conservative CLI defaults from provider hard
limits; for example, Claude Opus 4.8 is recorded with 1M context and 128K max
output limit metadata while the interactive preset remains a smaller balanced
default. The registry also records runtime hints from the Claude Opus 4.8
release, including Claude Code's default `high` effort, `xhigh` support,
adaptive thinking, fast-mode availability, and the sampling parameters that
Opus 4.8 rejects when set away from defaults.

If you need Claude Any router-owned behavior for Anthropic too, such as the
local browser chat UI, router event inspection, or router channel handling,
enable the Anthropic `route_through_router` LLM option and set an Anthropic API
key. In that mode Claude Code still talks to `http://127.0.0.1:<router-port>`,
and the router forwards Anthropic-compatible `/v1/messages` requests to the
configured Anthropic base URL. Direct Claude Native mode remains the default.

### Claude Code workflows and ultracode through the router

Claude Any does not implement Claude Code workflows itself. In non-native
provider mode, Claude Code still owns `/workflows`, `/deep-research`,
subagents, MCP tools, and plan/tool execution. Claude Any only provides the
Anthropic Messages-compatible gateway that Claude Code talks to through
`ANTHROPIC_BASE_URL=http://127.0.0.1:<router-port>`.

For providers routed through Claude Any, `LLM options` exposes:

- `workflows_enabled=true|false`: allows Claude Code dynamic workflow features
  through the router by removing Claude Any's experimental-beta disable env for
  that launch.
- `ultracode_enabled=true|false`: starts Claude Code with
  `--settings {"ultracode":true}`. This is blocked at launch unless the selected
  model capability set includes `xhigh_effort`.
- `claude_code_supported_capabilities=...`: comma-separated override for the
  selected model. Accepted values are `effort`, `xhigh_effort`, `max_effort`,
  `thinking`, `adaptive_thinking`, and `interleaved_thinking`.

Claude Any automatically infers Claude Code capabilities for known Claude model
IDs such as `claude-opus-4-8`, `claude-opus-4-7`, `claude-opus-4-6`, and
`claude-sonnet-4-6` when those IDs are served by a routed gateway such as
OpenCode. Other providers/models require an explicit capability override before
ultracode can be enabled. This avoids advertising `xhigh` workflow thinking for
models that have not been verified to preserve Claude Code's thinking/tool
round trip.

High-effort ultracode sessions can consume a large number of upstream tokens.
For routed providers, Claude Any can store multiple API keys for the same
provider and rotate them per upstream request. This distributes provider-side
quota/rate usage across those keys; it does not reduce the actual number of
tokens a task consumes.

```sh
claude-any set-api-keys opencode KEY1,KEY2,KEY3
claude-any --ca-provider opencode --ca-api-keys-env OPENCODE_API_KEYS --ca-no-launch
```

`OPENCODE_API_KEYS` can be comma-, semicolon-, or newline-separated. The first
key remains the primary key used for Claude Code router authentication and model
list checks; routed upstream calls use round-robin selection. If more than one
key is configured, `claude-any test` sends a lightweight text probe with each
key before the normal compatibility phases, so an expired or invalid secondary
key fails fast instead of surfacing mid-session.

- Claude Code docs: https://docs.anthropic.com/en/docs/claude-code
- Claude Console API keys: https://console.anthropic.com/settings/keys

### Ollama

Local Ollama normally does not need an API key. Use a local base URL such as:

```text
http://127.0.0.1:11434
```

Ollama also provides Anthropic Messages API compatibility for tools such as
Claude Code. If you use `:cloud` models through a local Ollama host, sign in on
that Ollama host:

```sh
ollama signin
```

Links:

- Ollama Anthropic compatibility: https://docs.ollama.com/api/anthropic-compatibility
- Ollama authentication: https://docs.ollama.com/api/authentication

### Ollama Cloud

Ollama Cloud is for direct calls to `https://ollama.com/api`. It requires an
Ollama API key. Cloud model names must end in `:cloud`.

Links:

- Ollama Cloud: https://ollama.com/cloud
- Ollama API keys: https://ollama.com/settings/keys
- Ollama sign in: https://ollama.com/signin

### DeepSeek.com

DeepSeek.com is available as a routed provider through DeepSeek's
Anthropic-compatible Claude Code endpoint:

```text
https://api.deepseek.com/anthropic
```

Choose `DeepSeek.com` in the provider menu, or configure it headlessly:

```sh
claude-any --ca-provider deepseek --ca-model deepseek-v4-pro
```

Full one-shot setup:

```sh
claude-any --ca-provider deepseek --ca-base-url https://api.deepseek.com/anthropic --ca-model deepseek-v4-pro --ca-api-key-env DEEPSEEK_API_KEY --ca-no-launch
```

DeepSeek requires a DeepSeek API key. If launch is blocked because no key is
configured, Claude Any opens the API-key setup path so you can enter or select
the environment variable without restarting the launcher.

The DeepSeek provider is intentionally routed through Claude Any, which sets
the Anthropic-compatible base URL and model alias for Claude Code. Claude Any
passes the DeepSeek API key as `ANTHROPIC_AUTH_TOKEN`, matching DeepSeek's
Claude Code integration, and keeps `ANTHROPIC_API_KEY` unset to avoid Claude
Code's auth-conflict path. Avoid setting both variables manually in your shell;
let Claude Any prepare the auth environment for the selected provider.

DeepSeek V4 thinking-mode agent integrations require `supportsToolChoice:
false` in DeepSeek's own compatibility notes. Claude Any follows that behavior
for the DeepSeek.com provider: the model still receives the available tool
schemas, but forced `tool_choice` is removed before upstream calls and
compatibility tests for DeepSeek V4 models.

Links:

- DeepSeek Claude Code integration: https://api-docs.deepseek.com/quick_start/agent_integrations/claude_code
- DeepSeek V4 thinking compatibility notes: https://api-docs.deepseek.com/quick_start/agent_integrations/oh_my_pi
- DeepSeek API keys: https://platform.deepseek.com/api_keys

### OpenCode Zen

OpenCode Zen is available as a routed provider through the Zen gateway:

```text
https://opencode.ai/zen
```

Choose `OpenCode Zen` in the provider menu, or configure it headlessly:

```sh
claude-any --ca-provider opencode --ca-model claude-sonnet-4-6
```

Full one-shot setup:

```sh
claude-any --ca-provider opencode --ca-base-url https://opencode.ai/zen --ca-model claude-sonnet-4-6 --ca-api-key-env OPENCODE_ZEN_API_KEY --ca-no-launch
```

OpenCode Zen requires an OpenCode Zen API key. Claude Any uses
`https://opencode.ai/zen/v1/models` for the live model picker. Per the Zen
docs, Claude and Qwen Zen models use `/v1/messages`, while chat-compatible Zen
models use `/v1/chat/completions`. Models that require provider-specific
Responses or Gemini endpoints are still listed with metadata, but Claude Any
does not silently route those endpoint families yet.

Links:

- OpenCode Zen docs: https://opencode.ai/docs/ko/zen
- OpenCode Zen model catalog: https://opencode.ai/zen/v1/models

### OpenCode Go

OpenCode Go is available as a routed provider through the Go subscription
gateway:

```text
https://opencode.ai/zen/go
```

Choose `OpenCode Go` in the provider menu, or configure it headlessly:

```sh
claude-any --ca-provider opencode-go --ca-model qwen3.6-plus
```

Full one-shot setup:

```sh
claude-any --ca-provider opencode-go --ca-base-url https://opencode.ai/zen/go --ca-model qwen3.6-plus --ca-api-key-env OPENCODE_GO_API_KEY --ca-no-launch
```

OpenCode Go requires an OpenCode Go API key. Claude Any uses
`https://opencode.ai/zen/go/v1/models` for the live model picker. Per the Go
docs, Qwen and MiniMax Go models use `/v1/messages`, while GLM, Kimi,
DeepSeek, and MiMo Go models use `/v1/chat/completions`.

The OpenCode model catalog currently returns model IDs without endpoint or AI
SDK package metadata. Claude Any therefore shows the inferred endpoint family
next to OpenCode models in the picker, prefers Anthropic-compatible
`/v1/messages` for unknown OpenCode model IDs, and supports explicit per-model
overrides:

```sh
claude-anyctl provider-options opencode-go endpoint:custom-model=chat
claude-anyctl provider-options opencode endpoint:custom-model=messages
claude-any --ca-provider opencode-go --ca-provider-option endpoint:custom-model=chat --ca-no-launch
claude-any --ca-set-provider-option opencode endpoint:custom-model=messages --ca-no-launch
```

Links:

- OpenCode Go docs: https://opencode.ai/docs/ko/go/
- OpenCode Go model catalog: https://opencode.ai/zen/go/v1/models

### vLLM

Use a vLLM server that exposes the Anthropic Messages API used by Claude Code.
The base URL should be the server root, for example:

```text
http://127.0.0.1:8000
```

Claude Any and Claude Code will call `/v1/messages` under that base URL. Use an
API key only if your vLLM server is configured to require one.

For Claude Code, vLLM tool calling must be started with a parser that matches
the model family. A server can answer text requests and still fail Claude Code
if `--tool-call-parser` is wrong. For Qwen3-Coder, use `qwen3_xml`:

```sh
vllm serve Qwen/Qwen3-Coder-30B-A3B-Instruct \
  --host 0.0.0.0 \
  --port 8000 \
  --served-model-name qwen3-coder-30b \
  --max-model-len 65536 \
  --enable-auto-tool-choice \
  --tool-call-parser qwen3_xml
```

Hermes-style models and some older Qwen tool templates may use `hermes`
instead, but do not assume `hermes` is correct for every Qwen model. Run
`claude-any test` after changing the parser; the test now checks text,
`tool_use`, and `tool_result`.

Links:

- vLLM Claude Code integration: https://docs.vllm.ai/en/latest/serving/integrations/claude_code/
- vLLM tool calling: https://docs.vllm.ai/en/stable/features/tool_calling/
- vLLM GitHub: https://github.com/vllm-project/vllm

### LM Studio

LM Studio exposes an Anthropic-compatible `/v1/messages` endpoint. Claude Any
uses that native path by default so Claude Code can talk to LM Studio directly.
Start LM Studio's Local Server and use this base URL:

```text
http://127.0.0.1:1234/v1
```

Then choose a model loaded in LM Studio, or set it headlessly with
`--ca-provider lm-studio --ca-model MODEL_ID`. If you need the older router
conversion path, set provider option `native=false`; the same base URL also
works for LM Studio's OpenAI-compatible `/v1/chat/completions` fallback.

Claude Any reads LM Studio's local `/api/v0/models` or `/api/v1/models`
metadata when available. The model catalog tells Claude Any what the model can
support, while `loaded_context_length` or `loaded_instances[].config.context_length`
tells it what LM Studio actually loaded. When you choose an LM Studio model,
Claude Any first applies its recommended Claude Code options, then asks LM
Studio to load or reload that model through `/api/v1/models/load` with the
recommended `context_length`. It only blocks launch/test if LM Studio rejects
that automatic load or reports that the model cannot provide at least 32K
context. This keeps normal users away from `n_keep`, `n_ctx`, and manual context
setup details.

### NVIDIA Hosted NIM

NVIDIA hosted models are available through NVIDIA API Catalog. Claude Any uses a
compatibility route for hosted models and requires an NVIDIA API key.

Links:

- NVIDIA API Catalog: https://build.nvidia.com/
- API Catalog quickstart: https://docs.api.nvidia.com/nim/docs/api-quickstart

### Self-Hosted NVIDIA NIM

Self-hosted NIM for LLMs can expose an Anthropic-compatible `/v1/messages`
endpoint. Use the NIM host base URL, not the OpenAI chat-completions URL.

Links:

- Claude Code with NIM: https://docs.nvidia.com/nim/large-language-models/latest/ai-assistant-integrations/claude-code.html
- NIM for LLMs getting started: https://docs.nvidia.com/nim/large-language-models/1.14.0/getting-started.html
- NGC personal keys: https://org.ngc.nvidia.com/setup/personal-keys

## Headless Usage

Claude Any options use the `--ca-*` prefix so they do not collide with Claude
Code flags. All other arguments pass through to Claude Code.

Headless mode is for launching Claude Code directly without opening the
pre-launch menu. It is useful for SSH sessions, scripts, scheduled jobs,
CI-like automation, and remote servers. Any `--ca-*` option updates Claude
Any's saved configuration first, skips the menu, starts the required
router services, then immediately executes Claude Code with the remaining
arguments.

Basic pattern:

```sh
claude-any --ca-provider PROVIDER --ca-model MODEL [claude-code args...]
```

Configuration precedence is deterministic:

1. Saved user choices from the interactive menu.
2. OS environment variables such as `CLAUDE_ANY_PROVIDER`.
3. Values loaded from `--ca-env-file .env.claude-any`.
4. CLI `--ca-*` parameters.
5. If `--ca-menu` is present, the final choice made in the interactive menu.

That lets automation provide defaults while still allowing a human operator to
make the final choice when needed.

Direct Claude Code launch examples:

```sh
# Open an interactive Claude Code session immediately with the saved model.
claude-any --ca-provider ollama-cloud --ca-model glm-5.1

# Run one non-interactive Claude Code prompt and print text output.
claude-any \
  --ca-provider ollama-cloud \
  --ca-model glm-5.1 \
  --ca-api-key-env OLLAMA_API_KEY \
  --ca-no-update-check \
  -p "Reply with OK only." \
  --output-format text

# Use the current saved Claude Any provider/model and pass args straight to Claude Code.
claude-any --ca-no-update-check -p "Summarize the current project." --output-format text
```

In these examples, `claude-any` is not just configuring settings. It starts
Claude Code in the same command. The `--ca-*` flags are consumed by Claude Any;
the prompt flags such as `-p` and `--output-format` are passed through to
Claude Code.

Provider setup examples:

```sh
# Local Ollama
claude-any \
  --ca-provider ollama \
  --ca-base-url http://127.0.0.1:11434 \
  --ca-model qwen3-coder \
  --ca-no-update-check \
  -p "Reply with OK only." --output-format text

# Ollama Cloud, reading the key from an environment variable
export OLLAMA_API_KEY="..."
claude-any \
  --ca-provider ollama-cloud \
  --ca-api-key-env OLLAMA_API_KEY \
  --ca-model glm-5.1 \
  -p "Summarize this repository." --output-format text

# vLLM Anthropic-compatible endpoint
claude-any \
  --ca-provider vllm \
  --ca-base-url http://127.0.0.1:8000 \
  --ca-model my-model \
  --ca-context-window 65536 \
  --ca-max-output-tokens 4096

# LM Studio local Anthropic-compatible server
claude-any \
  --ca-provider lm-studio \
  --ca-base-url http://127.0.0.1:1234/v1 \
  --ca-model local-model \
  --ca-context-window 32768

# NVIDIA hosted API Catalog through the local Claude Any router
export NVIDIA_API_KEY="..."
claude-any \
  --ca-provider nvidia-hosted \
  --ca-api-key-env NVIDIA_API_KEY \
  --ca-model moonshotai/kimi-k2.6 \
  --ca-request-timeout-ms 120000

# Self-hosted NIM Anthropic-compatible endpoint
claude-any \
  --ca-provider self-hosted-nim \
  --ca-base-url http://127.0.0.1:8000 \
  --ca-model model \
  --ca-api-key not-used
```

Full headless configuration with flags:

```sh
claude-any \
  --ca-language en \
  --ca-provider nvidia-hosted \
  --ca-base-url https://integrate.api.nvidia.com/v1 \
  --ca-model z-ai/glm-4.7 \
  --ca-advisor-model deepseek-ai/deepseek-v4-pro \
  --ca-api-key-env NVIDIA_API_KEY \
  --ca-max-output-tokens 4096 \
  --ca-context-window 65536 \
  --ca-request-timeout-ms 120000 \
  --ca-rate-limit-rpm 0 \
  --ca-rate-limit-status off \
  --ca-stream on \
  --ca-stream-word-chunking off \
  --ca-web-search \
  --ca-web-fetch \
  --ca-no-update-check \
  -p "Reply with OK only." \
  --output-format text
```

Full headless configuration with environment variables:

```sh
export CLAUDE_ANY_SKIP_MENU=1
export CLAUDE_ANY_LANGUAGE=en
export CLAUDE_ANY_PROVIDER=nvidia-hosted
export CLAUDE_ANY_BASE_URL=https://integrate.api.nvidia.com/v1
export CLAUDE_ANY_MODEL=z-ai/glm-4.7
export CLAUDE_ANY_ADVISOR_MODEL=deepseek-ai/deepseek-v4-pro
export CLAUDE_ANY_API_KEY_ENV=NVIDIA_API_KEY
export CLAUDE_ANY_MAX_OUTPUT_TOKENS=4096
export CLAUDE_ANY_CONTEXT_WINDOW=65536
export CLAUDE_ANY_REQUEST_TIMEOUT_MS=120000
export CLAUDE_ANY_RATE_LIMIT_RPM=0
export CLAUDE_ANY_RATE_LIMIT_STATUS=off
export CLAUDE_ANY_STREAM=on
export CLAUDE_ANY_STREAM_WORD_CHUNKING=off
export CLAUDE_ANY_WEB_SEARCH=on
export CLAUDE_ANY_WEB_FETCH=on
export CLAUDE_ANY_SELF_UPDATE_CHECK=off
export CLAUDE_ANY_UPDATE_CHECK=off
claude-any -p "Reply with OK only." --output-format text
```

The same values can be stored in a dotenv-style file and loaded explicitly:

```dotenv
CLAUDE_ANY_SKIP_MENU=1
CLAUDE_ANY_LANGUAGE=en
CLAUDE_ANY_PROVIDER=nvidia-hosted
CLAUDE_ANY_BASE_URL=https://integrate.api.nvidia.com/v1
CLAUDE_ANY_MODEL=z-ai/glm-4.7
CLAUDE_ANY_ADVISOR_MODEL=deepseek-ai/deepseek-v4-pro
CLAUDE_ANY_API_KEY_ENV=NVIDIA_API_KEY
CLAUDE_ANY_MAX_OUTPUT_TOKENS=4096
CLAUDE_ANY_CONTEXT_WINDOW=65536
CLAUDE_ANY_REQUEST_TIMEOUT_MS=120000
CLAUDE_ANY_RATE_LIMIT_RPM=0
CLAUDE_ANY_RATE_LIMIT_STATUS=off
CLAUDE_ANY_STREAM=on
CLAUDE_ANY_STREAM_WORD_CHUNKING=off
CLAUDE_ANY_WEB_SEARCH=on
CLAUDE_ANY_WEB_FETCH=on
CLAUDE_ANY_SELF_UPDATE_CHECK=off
CLAUDE_ANY_UPDATE_CHECK=off
```

```sh
claude-any --ca-env-file .env.claude-any -p "Reply with OK only." --output-format text
```

To let `.env` or CLI values prefill the menu while the user makes the final
choice, add `--ca-menu`:

```sh
claude-any --ca-env-file .env.claude-any --ca-model z-ai/glm-4.7 --ca-menu
```

Passing Claude Code arguments:

```sh
# Everything not recognized as --ca-* is passed through to Claude Code.
claude-any --ca-provider ollama-cloud -p "Write a short status report." --output-format text

# Use -- when you want to visually separate Claude Any setup from Claude args.
claude-any --ca-provider ollama-cloud --ca-model glm-5.1 -- -p "Reply OK" --output-format text
```

Compatibility tests without the menu:

```sh
# Auto mode: fast default. NVIDIA hosted uses a text-only quick test.
claude-any test 60 auto

# Smoke mode: text response plus required tool_use.
claude-any test 120 smoke

# Full mode: text, tool_use, and tool_result round trip.
claude-any test 180 full
```

Service cleanup and status:

```sh
claude-any status
claude-any stop
```

Common Claude Any setup flags:

| Flag | Purpose |
| --- | --- |
| `--ca-env-file PATH` | Load `CLAUDE_ANY_*` values from a dotenv-style file. |
| `--ca-menu` | Apply env/flag values, then open the interactive menu for the final user choice. |
| `--ca-language en|ko|ja|zh` | Set display language. |
| `--ca-provider PROVIDER` | Set provider and skip the menu for this launch. |
| `--ca-model MODEL` | Set the current provider model. |
| `--ca-advisor-model MODEL` | Set the Advisor model; use `off` to disable it. |
| `--ca-base-url URL` | Set the current provider base URL. |
| `--ca-api-key KEY` | Store the current provider API key directly. Prefer env vars for scripts. Use `clear`, `unset`, `none`, or `off` to remove stored key(s). |
| `--ca-api-key-env ENVVAR` | Store the current provider API key from an environment variable. |
| `--ca-api-keys KEY1,KEY2` | Store multiple current-provider API keys and rotate them per routed upstream request. |
| `--ca-api-keys-env ENVVAR` | Store multiple current-provider API keys from a comma-, semicolon-, or newline-separated environment variable. |
| `--ca-set-api-key PROVIDER KEY` | Store a key for a specific provider. Use `clear`, `unset`, `none`, or `off` to remove stored key(s). |
| `--ca-set-api-key-env PROVIDER ENVVAR` | Store a provider key from an environment variable. |
| `--ca-set-api-keys PROVIDER KEY1,KEY2` | Store multiple API keys for a specific provider. |
| `--ca-set-api-keys-env PROVIDER ENVVAR` | Store multiple provider keys from an environment variable. |
| `--ca-provider-option KEY=VALUE` | Set a provider option for the current provider. OpenCode endpoint overrides use `endpoint:<model-id>=messages|chat|responses|gemini`. |
| `--ca-set-provider-option PROVIDER KEY=VALUE` | Set a provider option for a specific provider without switching the current provider first. |
| `--ca-max-output-tokens VALUE` | Set provider output-token cap. |
| `--ca-context-window VALUE` | Set provider/router context-window cap where supported. |
| `--ca-request-timeout-ms VALUE` | Set upstream request timeout in milliseconds. |
| `--ca-stream-idle-timeout-ms VALUE` | Set stream idle timeout in milliseconds; if no bytes arrive for this long, the router can retry or fail instead of hanging forever. |
| `--ca-rate-limit-rpm VALUE` | Set provider RPM limit; default `0` disables router throttling. |
| `--ca-rate-limit-status on|off` | Show or hide RPM/rate-limit status in the Claude Code statusline; default is `off`. |
| `--ca-stream on|off` | Enable or disable streaming through the router. |
| `--ca-stream-word-chunking on|off` | Split streamed text into smaller word-like chunks when enabled. |
| `--ca-ollama-num-ctx VALUE` | Set Ollama `num_ctx`. |
| `--ca-ollama-ctx-range MIN MAX` | Set Ollama auto context range. |
| `--ca-ollama-option KEY=VALUE` | Set an Ollama option such as `temperature=0.3`. |
| `--ca-web-search` / `--ca-no-web-search` | Force-enable or disable web-search MCP for this launch. |
| `--ca-web-fetch` / `--ca-no-web-fetch` | Enable or disable fetch MCP for web page content. |
| `--ca-no-self-update-check` | Skip the Claude Any npm self-update check. |
| `--ca-no-update-check` | Skip the Claude Code update check. |
| `--ca-status` | Print status and exit. |
| `--ca-stop` | Stop managed router services and exit. |

Notes for automation:

- `--ca-api-key-env` avoids putting secrets directly in shell history.
- `--ca-api-keys-env` is the safer form for multi-key round-robin; set the
  environment variable to `KEY1,KEY2,KEY3` or one key per line.
- `--ca-api-key` and `--ca-set-api-key` are available for direct key passing,
  but prefer the environment-variable forms in shared scripts and terminals.
- To remove stored credentials, use the launch-menu API key panel's
  `Clear stored API key(s)` action or run `claude-any set-api-key PROVIDER clear`.
- `claude-any stop` is safe to run before scripted tests to remove stale
  router/proxy processes.
- npm-installed interactive launches check the npm registry for a newer
  Claude Any version and ask before running `npm install -g --prefix <active-prefix>
  @oneciel-ai/claude-any@latest`. Headless/non-TTY launches are not interrupted;
  set `CLAUDE_ANY_SELF_UPDATE_CHECK=off` or pass `--ca-no-self-update-check` to
  disable it explicitly.
- Use `claude-any test 60 auto` for a quick readiness check and reserve
  `claude-any test 180 full` for deeper provider validation.
- Headless flags persist in `~/.config/claude-any/config.json`, so the next
  interactive launch starts from the same provider/model settings.

## Router Chat and Plan Artifacts

Claude Code Plan mode uses internal Claude Code tools and UI state. Claude Any
keeps `EnterPlanMode` available for non-Anthropic providers and handles the
Plan-mode transition in the router when the upstream model does not reliably
select that internal tool. If Claude Code forces `tool_choice=EnterPlanMode`,
the router returns a valid Anthropic `tool_use` locally. If a long
implementation request receives only a short or empty non-actionable text
response, the router promotes that response to `EnterPlanMode` using
language-agnostic structure checks. Other unsupported Claude Code self-tools
are still removed before forwarding requests to non-Anthropic providers.

For troubleshooting, write `TRACE` to `~/.config/claude-any/log-level`; the
router then records redacted request and response summaries in:

- `~/.config/claude-any/requests.jsonl`
- `~/.config/claude-any/responses.jsonl`

The router also exposes a provider-neutral control plane for headless sub
agents. It is intentionally separate from `/v1/messages` so it does not change
Claude Code's API traffic.

Endpoints:

| Endpoint | Method | Purpose |
| --- | --- | --- |
| `/ca/chat/health` | `GET` | Check chat service availability. |
| `/ca/chat/messages` | `POST` | Send a message. |
| `/ca/chat/messages?after=N` | `GET` | Poll messages after the last seen id. |
| `/ca/chat/wait?after=N&timeout=60` | `GET` | Long-poll until messages arrive or timeout. |
| `/ca/chat/stream?after=N&timeout=300` | `GET` | Server-sent event stream for agents that must wait for replies. |
| `/ca/chat/files` | `POST` | Upload a text/base64 file and optionally announce it to a channel. |
| `/ca/chat/files/NAME` | `GET` | Fetch an uploaded file. |
| `/ca/plan/artifacts` | `POST` | Create and serve a plan artifact file. |
| `/ca/plan/artifacts` | `GET` | List plan artifacts. |
| `/ca/plan/artifacts/NAME` | `GET` | Fetch a plan artifact. |

Message shape:

```json
{
  "channel": "agents",
  "sender_id": "codex",
  "recipients": ["kimi", "qwen"],
  "thread_id": "task-123",
  "parent_id": 42,
  "message": "I need the current test failure output."
}
```

The response includes a monotonically increasing `id`. Store that id and pass
it back as `after=N` to receive only new messages.

Headless examples:

Use the router base printed by `claude-any status` or the launch log. On POSIX
systems the default is per-user (`8799 + uid % 1000`) unless
`CLAUDE_ANY_ROUTER_PORT` is set. The examples below use `8799` only as a
placeholder.

```sh
# Send a direct message.
curl -s http://127.0.0.1:8799/ca/chat/messages \
  -H 'content-type: application/json' \
  -d '{"channel":"agents","sender_id":"codex","recipients":["kimi"],"message":"Please inspect the failing test."}'

# Poll for updates addressed to kimi.
curl -s 'http://127.0.0.1:8799/ca/chat/messages?channel=agents&recipient=kimi&after=0'

# Wait on SSE until a response arrives.
curl -N 'http://127.0.0.1:8799/ca/chat/stream?channel=agents&recipient=codex&after=10&timeout=300'

# Create a plan artifact that other agents can fetch by URL.
curl -s http://127.0.0.1:8799/ca/plan/artifacts \
  -H 'content-type: application/json' \
  -d '{"title":"handoff","name":"handoff.md","content":"# Plan\n- reproduce\n- patch\n- verify"}'
```

Artifacts are stored under `~/.config/claude-any/plan-artifacts/`; chat
messages are stored in `~/.config/claude-any/chat-messages.jsonl`.

## Local Browser Chat

The router serves a local browser chat UI at:

```text
http://127.0.0.1:8799/ca/web/chat
```

The page posts browser messages to `/ca/channel/messages`, where they are picked
up by the active Claude Code session through the Claude Any channel bridge. The
active session can use its normal Claude Code tools and configured MCP servers.
Replies are sent back with the built-in `claude-any-router` MCP `send_message`
tool and streamed to the browser through `/ca/channel/stream`.

The web composer also supports file attachments. Attached files are uploaded to
`/ca/channel/files`, stored under `~/.config/claude-any/chat-files/`, and added
to the browser message as router file URLs. The active Claude Code session can
then fetch or inspect those files with its usual tools instead of switching to a
separate provider-only chat.

The reverse direction uses the built-in `claude-any-router` MCP server. Claude
Code can call `send_file` with either a local `path` or inline `content` to copy
the file into the same chat file store and publish a browser-visible attachment
message on the web-chat channel. Use `recipients: "web"` and `delivery: ["web"]`
when the attachment should only appear in the browser session.

In router mode, the session web chat uses the terminal wake bridge for browser
messages so requests enter the running Claude Code session instead of creating a
separate provider-only `/v1/messages` conversation. If messages remain queued,
restart Claude Any after installing the current build so the active terminal is
wrapped by that wake bridge. It is deliberately
local-only by default and does not create
Cloudflare tunnels, Tailscale routes, DNS records, or public hostnames. If the
selected provider is Anthropic and the browser chat should use the router, turn
on the Anthropic `route_through_router` option and configure an Anthropic API
key.

## External Web Access

Claude Any does not currently automate Cloudflare Tunnel, Tailscale Funnel, or
other public-network configuration. The launcher should keep router and web
chat surfaces on local per-user ports by default, then let the operator decide
how to expose that local service. This avoids cross-instance interference when
multiple Claude Any sessions run on the same machine.

For Cloudflare users, the supported documentation path is Cloudflare MCP rather
than built-in tunnel creation:

1. Start Claude Any and find the local router/web-chat base with
   `claude-any status` or the launch log.
2. Connect your MCP client to Cloudflare's official API MCP endpoint:
   `https://mcp.cloudflare.com/mcp`.
3. Authorize Cloudflare with OAuth or an API token scoped to the account/zone
   you want to manage.
4. Use the MCP client to create or update a Cloudflare Tunnel/public hostname
   that points to the local Claude Any web/chat port.
5. Use a unique hostname per Claude Any instance, and never overwrite an
   existing DNS record or tunnel route unless you explicitly intend to.

This keeps Cloudflare credentials and resource ownership outside Claude Any.
Users can also expose the local port with the Cloudflare dashboard,
`cloudflared`, nginx, Caddy, SSH forwarding, or another gateway. Tailscale
automation is intentionally not documented as a built-in Claude Any workflow
because Serve/Funnel state is machine-wide enough to risk interference between
concurrent instances.

## Recommended Uses

Claude Any is a good fit for slower background work where steady throughput
matters more than instant interaction:

- Docker host maintenance and cleanup.
- Windows, Linux, and remote server administration.
- Finding unused files and turning cleanup into repeatable scripts.
- Periodic security checklists and configuration review.
- Log review for failed sign-in attempts, exposed services, suspicious access,
  and other intrusion indicators.
- Noisy Windows Event Log review, including possible virus, ransomware,
  brute-force, and remote-access intrusion attempts.
- Drafting operational reports from command output and logs.
- Turning requests like "install PostgreSQL in a Docker container" or "analyze
  today's Docker logs and email me a report" into commands, scripts, scheduled
  jobs, and summaries.

### Tiered Supervision Pattern

A practical operating pattern is to combine models by cost and capability:

- Small or cheaper models watch logs, detect possible issues, and prepare first
  summaries.
- A larger model reviews the findings, writes policy, decides priority, and
  plans the response.
- Small models then execute routine commands, cleanup, reporting, or scheduled
  checks under the larger model's supervision.

It is not a replacement for dedicated monitoring, EDR, SIEM, or security
products. It is useful as an operator assistant that can inspect logs, propose
scripts, summarize findings, and produce readable reports while preserving
premium Claude/Codex tokens for harder work.
Used this way, Claude Any can become a free or low-cost system security watcher
for routine checks and summaries.

## Web Search

Non-native providers may not have Claude Code's remote web-search capability.
Claude Any can wire separate MCP tools for DuckDuckGo search and URL fetch so
agents can still perform web research through explicit tools.

## Service Lifecycle

Claude Any starts provider helpers on demand rather than keeping every helper
alive permanently.

- `claude-any stop` stops managed Claude Any router processes.
- When launching Claude Code, Claude Any starts only the services required by
  the selected provider.
- Routed providers use the Claude Any router on a stable per-user local port.
  `CLAUDE_ANY_ROUTER_PORT` wins when set; otherwise POSIX systems default to
  `8799 + (uid % 1000)`. This avoids cross-user router reuse on shared hosts.
- Ollama Cloud, DeepSeek.com, NVIDIA hosted, and other router-backed providers
  use that local router. Hosted API Catalog models do not require a separate
  NVIDIA proxy.
- For clean provider-switch testing, run `claude-any stop`, select the provider,
  then launch or test. Current launches also try to clear stale same-user router
  processes before spawning.

## External Channel Delivery

Routed, non-Claude-Native sessions use the LLM channel delivery path for
external systems such as AI-Net. SSE/MCP notifications are stored in
`chat-messages.jsonl`, delivered to the LLM context, and can use MCP tools when
the response requires them. Automatic direct handling is router-owned and does
not spawn a hidden Claude Code `-p` process. The direct handler calls the
selected routed provider through `/v1/messages`, executes MCP `tools/call`
requests over the initialized SSE connection, feeds `tool_result` blocks back
to the same LLM conversation, then queues a visible summary for the next
interactive routed request. Logs to check:

```text
channel_sse_message_received
channel_sse_mcp_rpc_response
channel_llm_direct_router_request
channel_llm_tool_call
channel_llm_tool_result_forwarded
channel_llm_summary_queued
channel_llm_summary_injected
channel_llm_direct_response
```

If those entries appear, the notification was processed. Terminal notices remain
best-effort diagnostics; the durable transcript surface is the summary queue,
which is injected into the next routed Claude Code request so the visible
session can summarize what happened. User-initiated `claude-any ... -p` remains
ordinary Claude Code pass-through usage.

## Development Story

Claude Any started because long Claude Code sessions can run out of premium
tokens even on a high plan. The intent is to keep work moving while waiting for
the next token window: slower but usable providers can handle summaries,
research, journals, simple code, and delegated background tasks.

During development, Anthropic-compatible Messages endpoints proved to be the
cleanest integration path for Claude Code. Ollama, vLLM, and NIM can expose
those routes. Generic OpenAI-compatible chat endpoints were not selected as the
primary route because tool-call translation was less stable around parameters,
tool results, repeated calls, retries, and model selection.

The vLLM work also showed that a successful text response is not enough for
Claude Code. The selected model and server need compatible tool-call formatting.
In particular, Qwen3-Coder should use vLLM's `qwen3_xml` tool parser. Claude Any
therefore expanded its compatibility test to cover text, `tool_use`, and
`tool_result` phases.

Local Qwen 3.6 27B Q4 runs were tested through Ollama and vLLM on RTX 5090 and
MSI GB10-class hardware. They worked, but the speed belongs in a different
category from native Claude Code or Codex. For this hybrid workflow, some
hosted/cloud models from NVIDIA NIM and Ollama Cloud were more practical than
expected.

## Demo Assets

Demo images, GIF, and MP4 are generated from a script:

```sh
python scripts/make_demo_assets.py
```

Generated files live in `docs/assets/`.

## Next Stage TODO

- **True NVIDIA hosted upstream streaming**: the current NVIDIA hosted router
  path opens an SSE stream back to Claude Code, but calls NVIDIA hosted
  `/v1/chat/completions` with `stream:false` and emits the converted Anthropic
  response only after the upstream request completes. Implement an OpenAI
  streaming parser for NVIDIA hosted so text deltas are forwarded to Claude Code
  as they arrive.
- **Safe streamed tool-call conversion**: when enabling NVIDIA upstream
  streaming, accumulate OpenAI `tool_calls` / function-call chunks until each
  tool input JSON object is complete, then emit valid Anthropic
  `content_block_start`, `input_json_delta`, and `content_block_stop` events.
  Text deltas can stream immediately; tool-use blocks must preserve Claude
  Code's strict content-block ordering and indexes.
- **Streaming diagnostics**: add router debug logs or a compatibility subtest
  that distinguishes "Claude Code SSE is open" from "upstream provider is truly
  streaming" so long NVIDIA hosted waits are easier to explain.

## Troubleshooting

- If the first request says a model does not exist, re-open the menu and select
  a model that the current provider actually serves.
- If Ollama Cloud returns authentication errors, check `OLLAMA_API_KEY` or use
  the API key menu.
- If local Ollama cloud models fail, run `ollama signin` on the Ollama host.
- If vLLM or NIM returns model `404`, map Claude Code's model aliases to the
  served model name or select the custom model entry.
- If vLLM tool calls fail, verify both model support and the vLLM
  `--tool-call-parser`/chat-template combination. Qwen3-Coder should start with
  `--enable-auto-tool-choice --tool-call-parser qwen3_xml`.
- If Claude Code update checks fail due to disk space, clean local caches or
  skip the check with `--ca-no-update-check`.

## Security Checklist

- Do not commit `~/.config/claude-any/`.
- Do not commit API keys, tokens, screenshots containing secrets, or router logs.
- Prefer environment variables for keys in automation.
- Revoke and rotate any key that was pasted into chat, logs, or issue reports.
