cd /news/ai-agents/hermes-agent-now-supports-claude-pro… · home topics ai-agents article
[ARTICLE · art-136190] src=hermes-agent.nousresearch.com ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Hermes Agent now supports Claude Pro/Max subscriptions

Nous Research released the Hermes Agent plugin "Claude Subscription DirectSDK (Experimental)," which drives the unmodified official Claude Code executable as a request-scoped model client for Claude Pro/Max subscriptions. The plugin requires Hermes Agent 0.21.4 or newer, Python 3.10+, and a logged-in Claude Code CLI, and it declares no credentials of its own. A live qualification completed seven Hermes calls with exactly seven upstream requests, twelve Hermes tool executions and twelve durable tool results, with context growing from 138,498 to 165,697 tokens and follow-up cache reads averaging 97.13%; native accounting reported $0.8793728 in list-price equivalent, not a verified subscription charge.

read15 min views7 publishedSep 21, 2026
Hermes Agent now supports Claude Pro/Max subscriptions
Image: source

Standalone Hermes Agent model-provider plugin: claude-subscription-directsdk-experimental, displayed as Claude Subscription DirectSDK (Experimental). It drives the unmodified official Claude Code executable as a request-scoped model client for your Claude Pro/Max subscription. Hermes keeps its normal agent loop, tools, approvals and compaction. Despite the name, the implementation speaks native stream-json directly and does not require the Python Agent SDK package.

Requirements #

  • Hermes Agent 0.21.4 or newer, or main at/after118984d7a02f (hermes-agent PR #117451, the core half of #105863). On an older Hermes the plugin fails to load with a clearFailed to load user provider plugin warning rather than half-working.
  • Python 3.10+ on Linux, macOS or Windows. Native runs in its own process group (POSIX session / Windows CREATE_NEW_PROCESS_GROUP ) and cancellation kills the whole tree (killpg /taskkill /T ), so thenode child behind the npmclaude.cmd shim never outlives a cancelled request. The suite runs on all three in CI.
  • The official Claude Code CLI, installed and logged in. This plugin has no credentials of its own; everything goes throughclaude .

The plugin checks for claude at every seam and never guesses:

When What happens without claude
plugin load one warning in the log; the provider stays registered so setup can explain what is missing
hermes model → this provider the flow stops with the install hint and writes nothing to config
/model , Desktop/TUI picker the pinned catalog is listed (no live account picker)
a request fails immediately with the install hint instead of a Popen traceback

Install Claude Code with npm install -g @anthropic-ai/claude-code, or point CLAUDE_SUBSCRIPTION_DIRECTSDK_COMMAND at the binary if it lives outside PATH. The plugin.yaml declares the same requirement under external_dependencies.

Install #

hermes plugins install claude-subscription-directsdk      # from the Hermes plugin catalog (pinned, reviewed)
hermes plugins install NousResearch/hermes-plugin-claude-subscription-directsdk
git clone https://github.com/NousResearch/hermes-plugin-claude-subscription-directsdk \
    ~/.hermes/plugins/claude-subscription-directsdk-experimental

claude auth login
hermes model          # pick "Claude Subscription DirectSDK (Experimental)"

Per-profile installs go under ~/.hermes/profiles/<profile>/plugins/ instead. The plugin declares kind: model-provider, so Hermes' provider discovery imports it directly; no plugins.enabled entry is needed.

Status #

Single-request admission is implemented and live-qualified. Native 2.1.263 can attempt extra generations despite --max-turns 1 and disabled HTTP retries. A request-scoped loopback relay now forwards only the first Messages request and rejects subsequent attempts locally. Hermes receives the first completed upstream response, its actual usage and native stop reason; blocked native recovery does not turn a completed response into an exception. Truncated/incomplete streams and upstream HTTP errors remain failures.

The integrated subscription-backed review completed seven Hermes calls with exactly seven upstream requests, twelve Hermes tool executions and twelve durable tool results. Context grew from 138,498 to 165,697 tokens; follow-up cache reads averaged 97.13%. Native accounting reported $0.8793728 in list-price equivalent, not a verified subscription charge. An earlier attempt began at 187K but exceeded the current native route's 200K bound after tools; that incomplete attempt is not counted as a successful review.

A real subscription-backed Hermes task built and tested a CSV auditor. Separate live qualifications exercised streaming tool rounds, restart/resume, host-side denial, authentic steering, cancellation during generation, and a real CLI subagent completion. This is a review build, not a full-parity or production-readiness claim. See the remaining limitations below.

Native Claude Code 2.1.263 is qualified. Replay acknowledgments and extra-body behavior are version-sensitive interfaces, not a public arbitrary-history SDK guarantee. The generic host support (external-process providers, replay carriers, setup gating) lives in Hermes core; this repository is only the provider.

Login and select #

claude auth login
hermes --provider claude-subscription-directsdk-experimental -m sonnet

Authentication belongs to the official CLI. The plugin never opens, copies, refreshes, or prints its credential files. No Hermes API key is required or sent by the plugin. The normal Hermes client path rejects inherited API-key, custom Anthropic endpoint, and cloud-backend overrides before spawning; the error names conflicting environment variables without printing their values. Remove those overrides from the launching environment when selecting OAuth. There is no silent HTTP/API-key fallback in this client.

Subscription entitlement and extra-usage settings still belong to the account and native service. Disable extra usage in the account if you do not want overage billing. A native list-price cost estimate is not proof of a subscription charge.

For a separately CLI-managed auth directory:

CLAUDE_CONFIG_DIR=/path/to/official-cli-config claude auth login
export CLAUDE_SUBSCRIPTION_DIRECTSDK_CONFIG_DIR=/path/to/official-cli-config

An inherited CLAUDE_CONFIG_DIR also works. To select an executable outside PATH, set CLAUDE_SUBSCRIPTION_DIRECTSDK_COMMAND to its absolute path. There is no unrestricted public CLI-flags setting; isolation and denial flags are plugin-owned. The low-level Python Client(env=...) injection is available for explicitly controlled local fixtures and does not apply the inherited-environment guard. It is not the normal Hermes provider path or an OAuth certification mechanism.

Persistent configuration:

model:
  provider: claude-subscription-directsdk-experimental
  default: sonnet

Auxiliary/fallback routing remains owned by Hermes. Configure those routes explicitly if they must also use the subscription; this provider does not silently change other selected providers.

Ownership and replay #

Each chat.completions.create starts a fresh process in a private temporary directory. Native tools, skills and setting sources are disabled. MCP advertises only the current Hermes tool inventory, has inert callbacks, and is denied execution by native dontAsk. Full descriptions and schemas are supplied through tools plus validated generation fields in CLAUDE_CODE_EXTRA_BODY, applied from a private native settings file; the system prompt uses a private file too. This avoids the OS per-argument/environment-string limit. Authentication and identity fields are never replaced.

Canonical history is replayed in order. Historical user frames use shouldQuery:false, each with a zero-turn acknowledgment; the final user/tool-result frame queries. There is no parked native session or native approval wait, and the adapter adds no synthetic continue prompt. The local admission relay prevents native recovery from issuing another upstream request. The native token-budget reminder is disabled because Hermes owns budgets and replay reconstructs that reminder across the cache boundary. Other native annotations remain present, so the wire prompt is not byte-identical Hermes-only context.

The relay binds an ephemeral loopback port with a random per-request route. Native authorization headers pass through memory directly to the upstream; headers are not logged or persisted. The upstream request body and native identity headers are preserved, while HTTP transfer encoding is normalized. The relay captures streamed text, signed thinking, tool arguments, usage and stop reason before native recovery can replace them. Cancellation shuts down the active upstream connection and the native process; request teardown removes the listener. No external relay service or bundled vendor executable is required.

Long-context caching qualification

A real Sonnet 5 Hermes review task reproduced poor cache reuse: its first request had 187,049 input tokens; the next tool round read only 6,989 of 190,840 input tokens from cache (3.66%), rewriting 183,849 tokens into the one-hour cache. Identical-request testing at 179K tokens had passed, but did not exercise this replay boundary.

Disabling the native reminder restored stable prefixes without adding cache markers or changing cache TTL. A completed seven-call review used ten real Hermes tool executions, ran six offline tests, and wrote its review artifacts. Context grew from 187K to 212K; follow-up requests averaged 97.99% cache reads, or 85.45% including the cold start. Native list-price accounting totalled $1.1030034, not a verified subscription charge. These are Sonnet 5 results: Fable 5.1 required usage credits on the qualification account and was not exercised with paid credits. Model entitlement and allowance consumption remain native-account dependent.

Text streams incrementally. A complete tool batch is published only after assistant completion, message_stop, final usage and native exit. Hermes then applies its own hooks, approvals, tools and persistence. Tool names map through mcp__hermes__; original names must be unique ASCII alphanumeric/underscore/hyphen identifiers of at most 50 characters.

--max-turns 1 is a logical native step; the relay supplies the HTTP admission boundary. error_max_turns is accepted with a complete tool batch, usage and exit code 1. Native num_turns may be 2 at that boundary. A completed first response also survives a locally denied recovery attempt or native refusal rendering; Hermes receives the actual refusal, not the CLI's synthetic error text. Other failures remain failures.

A versioned reasoning_details envelope retains ordered native assistant messages and signed thinking. Unchanged projections preserve native blocks, including harmless surrounding-whitespace normalization. Transformed assistant text/tool projections replay canonical text and tool-use blocks instead of stale signed thinking; foreign provider reasoning carriers are ignored. Edited-assistant replay passed against the real service. Native autocompaction is disabled so Hermes retains compaction ownership; this does not establish parity for every history transformation or cross-model signed replay.

Mid-turn /steer uses Hermes' standard delivery: a standalone typed user row appended after the newest tool result. This provider adds no steering-specific transport. Natural change-of-plan steering passed live in the real loop; transport fidelity cannot guarantee model obedience.

Lifecycle and request support #

Outside an event loop, create is synchronous; inside an event loop, it returns an offloaded coroutine. Streams also support async for. One client should belong to one independently cancellable Hermes owner.

cancel() kills the owned process tree (POSIX process group / Windows taskkill /T) without closing another thread's active descriptors. close() prevents new calls and finalizes idle/unstarted streams; active consumers unwind after cancellation. Early stream exit requires close() / aclose(). Live interruption stopped generation and the observed native PID exited.

Supported translation includes text, base64/native images and documents, canonical tools/results, output-token limits, stop sequences, reasoning enable/disable and effort, and JSON-schema response-format projection. Unsupported native sampling fields are omitted rather than forwarding deprecated temperature from auxiliary callers. Reasoning effort is clamped to native-supported levels, including Hermes minimal/ultra inputs. Native thinking deltas surface as reasoning_content. Model/service restrictions still apply.

Unknown parameters fail explicitly. Unsupported surfaces include assistant prefill, strict function mode, forced tool choice, parallel_tool_calls=False, n>1, JSON-object-only mode, arbitrary headers/body fields, remote image downloads, and cross-model signed-history parity. The read-idle timeout defaults to 180 seconds, resets on native output, and accepts Hermes' finite HTTPX read-timeout shape. Large prompts remain subject to native/OS limits.

Setup: hermes model → Claude Subscription DirectSDK (Experimental) #

Selecting the provider asks the Claude CLI itself, never Anthropic, before anything is saved:

  1. Installed?claude must resolve on PATH (orCLAUDE_SUBSCRIPTION_DIRECTSDK_COMMAND ). Otherwise one line: install withnpm install -g @anthropic-ai/claude-code , and the flow stops without touching config.
  2. Logged in?claude auth status (local credential store, ~0.3s). Logged in showscredentials: ✓ (Claude Pro) . Logged out on a terminal startsclaude auth login inline; it opens the browser and takes the pasted code, then the flow re-checks and continues. Without a TTY it prints the instruction and stops.
  3. Which models? The CLI'sinitialize handshake returns the account's own picker (verified through the admission relay: zero upstream requests). Rows are mapped to Hermes route ids and deduplicated (opus andopus[1m] are one 1M route). Rows the CLI marks "Draws from usage credits", plus Fable on non-Max plans per Anthropic's plan rule, carry a dim· usage credits note; nothing is hidden. If the handshake fails the pinned catalog below is used.

The same discover_models() feeds provider_model_ids(), so the TUI/Desktop pickers and /model list the account's picker too.

Subscription usage: same metering as claude -p, ~1.7x the interactive TUI #

Measured Sept 9 2026 on a Pro plan (Sonnet 5 1M, ~500K fresh input tokens per arm, output pinned to Hello!, session meter read on claude.ai before/after each arm):

arm list-$ pushed session meter Δ points per $
claude -p (two windows) 2.12 / 1.94 +19 / +17 8.9 / 8.8
this provider 2.36 +21 8.9
Claude Code interactive TUI (two runs) 2.22 / 2.25 +12 / +11 5.4 / 4.9

This provider draws subscription usage at exactly the claude -p / Agent SDK rate; there is no Hermes-specific penalty. Interactive Claude Code is metered at roughly 0.58x that rate, so plan for about 60% of the TUI's throughput per 5-hour window (≈ $6.5 vs ≈ $11 list-equivalent of Sonnet 5 on Pro). The wire-level usage buckets are identical across arms, so the weighting is server-side and applies to every -p/SDK harness. On identical coding tasks Hermes sent ~0.6x the tokens native Claude Code did; if your drain looks higher, compare Hermes /usage with Claude Code /cost on the same task.

Model metadata and accounting #

The picker exposes these explicit native routes:

Model Native selection Context
Sonnet 5 claude-sonnet-5[1m] 1,000,000
Haiku 4.5 claude-haiku-4-5-20251001 200,000
Opus 5 claude-opus-5[1m] 1,000,000
Opus 4.8 claude-opus-4-8[1m] 1,000,000
Fable 5.1 claude-fable-5-1[1m] 1,000,000

Short names sonnet, haiku, opus and fable resolve to the corresponding pinned routes above. Known 1M model IDs also receive the native [1m] suffix automatically; Haiku does not. Unknown model IDs pass through unchanged with no invented context metadata. An explicit Hermes model.context_length still overrides the host's window, including a smaller compaction budget.

The local relay sets ANTHROPIC_BASE_URL, which makes Claude Code apply its gateway defaults. Its documented Sonnet 5 gateway default is 200K unless [1m] is selected; this was the cause of the earlier downgrade, not evidence of a general subscription limit. Both native argv and Hermes metadata now select the same window. See Claude Code model configuration.

Native initialization can enumerate the current picker without a Messages request, but its returned list did not include Opus 4.8. The plugin therefore keeps the five requested version-pinned entries rather than silently dropping the older model or promoting every unknown future model to 1M. It does not spawn a model or query an HTTP /models endpoint when opening Hermes' picker. Existing installations may need Refresh models to discard the previous cached list; the live picker above replaces this static list whenever the CLI is logged in.

The follow-up probes used native 2.1.258. The Sonnet 5 1M route accepted 902,783 actual input tokens and returned the requested response, with native contextWindow: 1000000 and exactly one upstream request. Native list-price equivalent was $3.611238. A subsequent short sonnet request verified automatic routing to claude-sonnet-5[1m]; a real haiku request resolved to Haiku 4.5 with a 200K window. Opus 5 and Opus 4.8 were then smoke-tested through the integrated relay: each resolved to its [1m] route, reported a 1,000,000-token native window, returned the requested reply in exactly one upstream request, and cost $0.001485 list-equivalent each. Fable 5.1 was rejected by the native client on the qualification account: Fable 5.1 requires usage credits. That is Anthropic's documented plan rule, not a routing defect: on Pro (and Team standard seats) Fable 5 / 5.1 bill to pay-as-you-go usage credits from the first request, while Max plans include them up to 50% of weekly limits (Claude Fable models on your plan). The entry stays in the picker because every paid plan can reach it; the provider surfaces the native error verbatim and never falls back to another model. Native discovery also labels Opus 1M as drawing usage credits on Pro. Plan-aware picker badges from the native initialize handshake (which reports subscriptionType without an upstream request) are a follow-up.

Hermes compaction qualification

A real multi-turn run with a 200K Hermes window and compression.threshold: 0.75 automatically compacted after a turn with 154,038 input tokens, at an approximately 168K next-request preflight estimate. The real summarizer completed, SQLite archived fifteen original rows and retained a summary, and the next ordinary request succeeded at 144,568 input tokens. Two additional model calls executed a real read_file and returned both the remembered project codename and the exact file value; that tool result was verified in SQLite. This final-routing run used eleven upstream requests total and $1.221155 native list-price equivalent. Native autocompaction remained disabled: the summary and durable commit were owned by Hermes. The earlier native-200K control also passed; no compressor implementation change was needed.

Token usage retains native uncached/cache-read/cache-write/output components. Completed responses also retain native total_cost_usd and modelUsage. When every reported model has costBasis: list and the total is finite and nonnegative, Hermes records that exact native amount as estimated API list-price equivalent, not an actual subscription invoice or extra-usage charge. It is never marked free/included or replaced with guessed alias prices. Missing or invalid final accounting remains unknown; interrupted requests must not be interpreted as free or zero-token service work. Hermes' iteration and runtime budgets remain host-owned; this provider does not add an account-level overage cap.

Verification #

~/.hermes/hermes-agent/.venv/bin/python3 -m pytest tests/
python evals/directsdk_admission.py /path/to/claude
python evals/directsdk_cache_wire.py /path/to/claude

Transport invariant tests cover signed replay and harmless normalization, transformed projections, final tool batches/usage, async use, lazy failure, invalid parameters, conflicting auth, and active/d/unstarted stream cleanup. The admission regression fails on the previous implementation (two upstream requests) and passes with one request, preserving first-response usage including zero values. Its cancellation control verifies upstream socket closure. A real-native ten-case loopback qualification covers normal text, tools, output/context limits, thinking-only recovery, refusal, HTTP errors, disconnects and cancellation, with one upstream request per call. Its responses are synthetic protocol fixtures, not paid-model evidence.

Installed-plugin discovery ($HERMES_HOME/plugins/<name>/) and every missing- claude path are covered against a temporary HERMES_HOME, including constructing the bundled client without spawning native or accessing auth. A fresh subscription-backed AIAgent loop completed two API calls with host read_file execution and SQLite persistence; separate service requests accepted edited-assistant replay. Native loopback qualification also accepted 182K of tool schemas plus a 176K system prompt through file-backed settings. Loopback responses remain fixtures, not paid-model evidence.

The subscription-backed task, CLI delegation, streaming, resume, denial, steering and interruption receipts are separate private artifacts. No auth data or trajectories are committed to this repository. Remaining qualification includes broader history transformations, cross-model signed replay, native versions/platforms, and adversarial steering reliability. Subscription invoice/overage reconciliation is not available from native list-price accounting.

Attribution #

Extracted from hermes-agent PR #105863 (feat: add Claude Subscription DirectSDK (Experimental) provider) by @teknium1 and @unsupportedpastels. The provider-agnostic parts of that PR (external-process provider profiles, provider-native replay carriers, setup-flow gating, picker plumbing) land in Hermes core via hermes-agent PR #117451; the provider itself lives here as a standalone plugin because Hermes does not bundle vendor-specific subscription transports in-tree. The claude presence checks were added during extraction.

MIT licensed; see LICENSE.

── more in #ai-agents 4 stories · sorted by recency
── more on @hermes agent 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/hermes-agent-now-sup…] indexed:0 read:15min 2026-09-21 ·