Anthropic tightened OAuth validation between 2026-04-14 and 2026-04-22. Requests are now classified as third-party and routed to extra-usage credits (or rejected with 'Third-party apps now draw from your extra usage, not your plan limits') unless the fingerprint matches real Claude Code. Ports the two upstream opencode-claude-auth fixes that address this: - PR #191 (merged, v1.4.10): PascalCase `mcp_` tool names. Hermes prefixes tools with lowercase `mcp_bash`; the validator now flags that as non-Claude-Code. Real CC uses `mcp_Bash` / `mcp_Read` / `mcp_Background_output`. Adds a request-side rewrite hook plus a response-side unhook that lowercases the first char after hermes strips the prefix, so the tool dispatcher continues to receive the original lowercase names. - PR #207 (open, attempted fix for Claude Code 2.1.112): updates the billing fingerprint. Changes the `cc_entrypoint` in the signed billing header from `cli` to `sdk-cli`, adds the `advisor-tool-2026-03-01` beta flag, injects the Stainless SDK headers that real CC sends (`x-stainless-*`) plus `anthropic-dangerous-direct-browser-access: true`, and appends `?beta=true` to the /v1/messages query string. All non-body signals ride the Anthropic Python SDK's per-request `extra_headers` and `extra_query` kwargs so we don't need to rewrap the HTTP client. Other changes: - Bump __version__ to 1.1.0 and document the rationale above in the module docstring. - Extend `_EXTRA_OAUTH_BETAS` so both prompt-caching and advisor-tool betas are appended to hermes's `_OAUTH_ONLY_BETAS` list. - 10 new unit tests covering PascalCase rewrite (request + response), sdk-cli entrypoint, Stainless headers, extra_query=beta:true, and preservation of pre-existing extra_headers. Smoke-tested on Linux with hermes-agent v0.10.0 against claude-sonnet-4-6, claude-opus-4-6, and claude-opus-4-7 \u2014 all return 200 and complete responses with the new patch loaded. Billing-tier routing (plan vs extra-usage) cannot be verified from the client side; this tracks the best-known upstream bypass as of 2026-04-22 but Anthropic may tighten validation again at any time. Refs: #6 Upstream: https://github.com/griffinmartin/opencode-claude-auth/pull/191 Upstream: https://github.com/griffinmartin/opencode-claude-auth/pull/207
hermes-claude-auth
Claude Code OAuth bypass for hermes-agent, use your Claude Code subscription (Max/Pro) with Hermes.
What this does
Patches hermes-agent at runtime to pass Anthropic's server-side OAuth content validation. It does not modify hermes-agent source files. Installation happens through a Python import hook that monkey-patches build_anthropic_kwargs on startup.
Why this exists
On 2026-04-04, Anthropic added server-side validation that rejects OAuth requests from third-party tools. This patch adds the billing header signature and system prompt structure the API expects.
Prerequisites
- hermes-agent installed (
~/.hermes/hermes-agent/) - Claude Code CLI authenticated (valid credentials at
~/.claude/.credentials.json) - hermes-agent configured for OAuth (
credential_poolhas aclaude_codeentry in~/.hermes/auth.json) - Python 3.11+
Install
curl -fsSL https://raw.githubusercontent.com/kristianvast/hermes-claude-auth/main/install-remote.sh | bash
Or clone manually:
git clone https://github.com/kristianvast/hermes-claude-auth.git
cd hermes-claude-auth
./install.sh
What install.sh does:
- Copies
anthropic_billing_bypass.pyto~/.hermes/patches/ - Installs the import hook as
sitecustomize.pyin the hermes venv's site-packages - Restarts
hermes-gateway.serviceif running
Uninstall
./uninstall.sh # remove hook only
./uninstall.sh --purge # remove hook + patch file
How it works
- Billing header: SHA-256 signed
x-anthropic-billing-headerinjected assystem[0] - System prompt relocation: Non-identity system entries moved to the first user message as
<system-reminder>blocks - Beta flag: Adds
prompt-caching-scope-2026-01-05 - Temperature fix: Strips non-default temperature on Opus 4.6 adaptive thinking, which prevents HTTP 400
Installed through a sitecustomize.py MetaPathFinder hook, so it runs at interpreter startup with no source modifications.
What gets modified
| File | Action |
|---|---|
~/.hermes/patches/anthropic_billing_bypass.py |
Created |
<venv>/lib/pythonX.Y/site-packages/sitecustomize.py |
Created or replaced |
| hermes-agent source files | NOT modified |
Compatibility
- Tested with hermes-agent on Python 3.11+
- Linux and macOS
- Depends on
build_anthropic_kwargs(is_oauth=...)inagent.anthropic_adapter, so it may need updating if hermes-agent changes that interface
Troubleshooting
Install issues
- "hermes-agent not found": Make sure Hermes is installed at
~/.hermes/hermes-agent/ - "No virtualenv found": Set
HERMES_VENVto point to your venv - Patch not loading: Check
journalctl --user -u hermes-gateway -n 50for[anthropic_billing_bypass]or[hermes-claude-auth]messages
Auth issues
-
Anthropic 401 authentication failedorNo Anthropic credentials found: Hermes reads Claude subscription credentials from~/.claude/.credentials.json. If Claude Code is authenticated (e.g. in macOS Keychain) but that file is missing or stale, Hermes fails even when Claude Code itself works. Fix:- Refresh Claude subscription login:
claude auth login --claudeai - macOS only — mirror the Keychain
Claude Code-credentialsentry into the file Hermes reads:python3 - <<'PY' import subprocess from pathlib import Path secret = subprocess.check_output( ['security', 'find-generic-password', '-s', 'Claude Code-credentials', '-w'], text=True, ).strip() cred_path = Path.home() / '.claude' / '.credentials.json' cred_path.parent.mkdir(parents=True, exist_ok=True) cred_path.write_text(secret) cred_path.chmod(0o600) print(f'wrote {cred_path}') PY - Remove stale
ANTHROPIC_TOKEN/ANTHROPIC_API_KEYvalues from~/.hermes/.env— they can override subscription auth. - Reset cached credentials:
hermes auth reset anthropic - Retry with a smoke test:
hermes chat -q 'Reply with exactly: AUTH TEST OK' --provider anthropic -m claude-sonnet-4-6 -Q
Credit: this macOS Keychain mirror step was written up by @DrQbz in issue #5.
- Refresh Claude subscription login:
Billing / routing issues
- HTTP 400: "Third-party apps now draw from your extra usage, not your plan limits": Anthropic's server-side validation has classified your requests as third-party and routed them to pay-per-token credits instead of your Max/Pro plan. Make sure you're on the latest version of this patch (it tracks the upstream opencode-claude-auth fingerprint changes). Reinstall with
./install.shand restarthermes-gateway. If the error persists after update, the bypass is currently broken upstream too — track issue #6 for status. - HTTP 400 persists after update: The billing salt or signature format may have been rotated by Anthropic again. Check for newer commits to this repo.
Credits
- griffinmartin/opencode-claude-auth, the original TypeScript implementation for opencode (MIT)
- NousResearch/hermes-agent, the AI agent this patches (MIT)
Disclaimer
This uses Claude Code subscription credentials outside the official Claude Code CLI. It works with Anthropic's current OAuth implementation but may break if Anthropic changes their validation. Use at your own risk.
License
MIT, see LICENSE.