# Claude Code Provider

Running models through the locally installed `claude` CLI on your Claude subscription.

`claude-code` (since v1.1.0) uses the locally installed and logged-in `claude` CLI as a model backend, so requests run on your Claude subscription instead of a pay-per-token API key. It is off by default and meant for personal setups: start Agenvoy with `agen --enable-claude-code` (the daemon must be stopped first with `agen stop`) to enable it for that TUI and the daemon it starts. Since v1.2.0 the daemon runs every agent, so the `claude` processes live in the daemon; a TUI started later without the flag follows the daemon's setting.

| Aspect | Behavior |
|---|---|
| Transport | One `claude -p` process per session, model and system prompt, speaking `stream-json`. Since v1.1.3 the process is keyed by a hash of the system prompt, so summary, dispatch and follow-up calls no longer restart the main loop's process and drop its cache, and a call without tools inside a session gets its own persistent process instead of a one-off run. The CLI's own tools and MCP servers are disabled (`--tools ""`, `--strict-mcp-config`); tool calls are executed by Agenvoy under its usual rules. Since v1.1.4 the provider lives in `go-llm-router` instead of this repository; Agenvoy passes in the enable flag, the sessions directory for state files and the cache TTL |
| Tools | Only the tool names plus the full `find_tools` schema are sent; every other schema is fetched on demand through `find_tools`. Since v1.1.3 every tool except `find_tools` and client tools is marked as a stub on each request: calling one before fetching its schema does not run it — Agenvoy returns the schema and asks for the call again. Unlike other providers it does not go through `run_tool` (v1.2.0): the tool list it receives excludes `run_tool` and tools are called by their own names |
| Models | Since v1.1.2 listed by the `claude` CLI itself: Agenvoy sends an `initialize` control request to `claude -p` (no tools, no MCP, no session persistence) and keeps each distinct `resolvedModel`, so the list is what your subscription can actually run. Before v1.1.2 it was read from `models.agenvoy.com`, the `claude` catalog. A trailing `-YYYYMMDD` date is dropped when the context window is looked up |
| Routing | Inside a tier, `claude-code` models rank ahead of every other provider, then `codex`; for the same base model under several providers, `claude-code` comes first. Since v1.1.1 a model named in the request, or the previous model kept for an unchanged subject, stays ahead of this reordering |
| Quota | Parsed from `claude -p /usage` — no API call — and shown with `Shift+U` and in `GET /v1/providers/quota` |
| Usage | Input tokens include cache writes, the same as for `claude` |
| Sessions | Since v1.1.1 each session + model keeps its own Claude Code session; since v1.1.2 only while the session runs on the `1h` prompt cache (both model and reasoning pinned): the first turn starts `claude` with `--session-id`, later turns reuse the live process or, after it exits or the daemon restarts, `--resume` it; if resuming fails a fresh session is started with the full history. State lives in `sessions/<sid>/.claude_code/<model>_<system prompt hash>.json` (`_plain` appended for calls without tools; `sessions/<sid>/claude_code_<model>.json` before v1.1.3). Under the `5m` cache — and for calls without a session (before v1.1.3 also calls without tools) — `claude` runs with `--no-session-persistence` and only a live process is reused — nothing is saved or resumed, so a session on `auto` no longer leaves a Claude Code session that would miss the cache anyway |
| Prompt cache | Since v1.1.1 `CLAUDE_CODE_PROMPT_CACHE_TTL` is `5m` when the session's model or reasoning is `auto` (and for one-off calls), `1h` when both are pinned; a TTL change restarts the process |
| Tool call format | `<tool_call name="...">` blocks, and since v1.1.1 also `<invoke name="...">` with `<parameter name="...">` children (namespaced tags included); since v1.1.4 a JSON body containing a literal `</tool_call>` is read to its end instead of being cut at that string. A reply that is only empty tags plus tool calls is shown as `Processing` (`Processing...` before v1.1.4) |
| When not enabled | Since v1.1.2 the `/model add` row is hidden unless `--enable-claude-code` is on and the `claude` binary is found (it used to appear regardless). Registered `claude-code@` models are skipped by the agent registry, routing, the `/model` list and the dispatcher picker; `GET /v1/providers` marks the row `hidden` |
