Skip to content

fix: align claude oauth request shape#11

Merged
rekram1-node merged 1 commit intoanomalyco:masterfrom
harshav167:fix/claude-oauth-request-shape
Jan 9, 2026
Merged

fix: align claude oauth request shape#11
rekram1-node merged 1 commit intoanomalyco:masterfrom
harshav167:fix/claude-oauth-request-shape

Conversation

@harshav167
Copy link
Contributor

Summary

  • align Claude Code OAuth requests to Claude CLI shape (beta=true, claude-cli user-agent)
  • normalize headers and remove fine-grained tool streaming beta for OAuth
  • keep tool-name prefixing from PR fix: claude oauth by renaming tools on in/out #10 (oc_)

Why this over PR #10

PR #10 prefixes tool names, which helps tool-call routing, but the OAuth rejection happens before tool calls are processed. The 400 error is returned from /v1/messages itself. This change fixes the request signature mismatch (endpoint query + user-agent + beta list) so Claude Code OAuth tokens are accepted.

Notes

  • This is scoped to OAuth requests only; API key behavior is unchanged.

Test plan

  • Verified locally by routing OpenCode through ccflare and confirming POST /v1/messages?beta=true with user-agent: claude-cli/... and OAuth beta list; request succeeds.

@harshav167
Copy link
Contributor Author

Why this is a better long-term fix than PR #10 alone

PR #10 fixes tool call naming by prefixing oc_ and de-prefixing in the stream. That helps tool routing after a request is accepted, but it doesn’t address the OAuth rejection happening before any tool calls are processed. The 400 error (credential only authorized for use with Claude Code…) is returned directly from /v1/messages.

This PR fixes the actual request-signature mismatch that Anthropic is enforcing for Claude Code OAuth tokens:

  • Request shape: adds beta=true for /v1/messages (Claude Code does this; OpenCode didn’t)
  • Client identity: overrides user-agent to match Claude CLI (claude-cli/...)
  • Beta list: removes fine-grained-tool-streaming for OAuth and keeps only the Claude Code-compatible set

So it targets the auth acceptance criteria, not just tool call formatting. We keep the tool prefix change because it’s still useful, but without the request-shape alignment, OAuth tokens are rejected before tools are even considered. This makes the fix more robust and future-proof against further Claude Code OAuth enforcement.

If desired, we can still iterate on tool naming (e.g., {name}_tool / PascalCase) in a follow-up, but this request-shape alignment is the prerequisite for OAuth access to work at all.

@rekram1-node
Copy link
Contributor

Why is claude-code-20250219 conditional on incoming headers rather than always included?

@JimiHFord
Copy link

JimiHFord commented Jan 9, 2026

I'm still trying to wrap my head around this issue. I just got into opencode a few days ago because of Oh My Opencode. Could someone please help me understand what the issue is and how #10 and #11 fix things? All I think I know is that Anthropic is trying to restrict tools like opencode from pretending to be claude code, and these PRs somehow help obfuscate the api requests that get sent to them somehow?? Anyone know how to get unblocked on this issue:

{B65A55DC-5B80-4E8B-B431-55DB2E495AF8}

Edit: ok I think I'm starting to understand after @harshav167 's latest comment. Thanks!

@dbnewman
Copy link

dbnewman commented Jan 9, 2026

@JimiHFord Anthropic are claiming that third party CLI tools violate their TOS (I couldn't actually find any violations reading it as its still user-based interaction), and they want to control usage within Claude code as their Max products lose money, Claude code is closed-source so nobody can contribute/improve it and its a sub-par tool.

@harshav167
Copy link
Contributor Author

harshav167 commented Jan 9, 2026

@rekram1-node I made claude-code-20250219 conditional because in captures Claude Code sometimes sends only oauth-2025-04-20 + interleaved-thinking. The goal was to keep the request signature as close as possible to what the caller already requested. OpenCode currently includes claude-code-20250219, so behavior is unchanged in practice.
@JimiHFord quick summary: Anthropic now rejects Claude Code OAuth tokens unless the /v1/messages request looks like Claude Code. PR #10 only renames tools (post-accept), but the rejection happens before tools are processed. This PR fixes the pre-accept signature (beta=true, claude-cli user-agent, OAuth beta list) so tokens are accepted; PR #10 then makes tool calls work. Unblock: update the plugin to this PR and re-login with Claude Code OAuth—requests should succeed without the error.

@JimiHFord
Copy link

incredible - thanks so much!! attempting right now. I'm assuming I'll have to uninstall opencode and install from source so I can follow this comment?

@rekram1-node rekram1-node merged commit 89067ea into anomalyco:master Jan 9, 2026
@harshav167
Copy link
Contributor Author

Note on testing: you can override the plugin via config now (no core source edits needed):

// ~/.config/opencode/opencode.jsonc
"plugin": [
  "file:///path/to/opencode-anthropic-auth/index.mjs"
]

This loads the local plugin without touching opencode core.

@Davincible
Copy link

@rekram1-node from what I can see the claude-code-20250219 is only included on sonnet and opus model calls, not haiku

@JimiHFord
Copy link

ah! ok I think I'm following now, thanks @harshav167 !

@harshav167
Copy link
Contributor Author

Update on testing config override: built-in plugins are appended after config plugins, so a config entry alone won’t override the built-in anthropic plugin. To use a local plugin without editing opencode source, set OPENCODE_DISABLE_DEFAULT_PLUGINS=true and add the local plugin in opencode.jsonc (plus any other plugins you still want, e.g. copilot).

Also: once this PR is merged and the plugin is published, official OpenCode installs will pull the updated opencode-anthropic-auth version automatically (no local override needed).

@deveworld
Copy link

deveworld commented Jan 9, 2026

Tested this locally and it works great!

Setup:

  • Cloned the repo
  • Added to ~/.config/opencode/opencode.json:
    "plugin": ["file:///path/to/opencode-anthropic-auth/index.mjs"]
  • Ran with OPENCODE_DISABLE_DEFAULT_PLUGINS=true opencode

Thanks for the fix! 🙏

@harshav167
Copy link
Contributor Author

image Worked
Used claude code to do and created readme haha

OpenCode Anthropic Auth Plugin

# Install
git clone https://github.com/anthropics/opencode-anthropic-auth.git ~/opencode-anthropic-auth
cd ~/opencode-anthropic-auth && bun install

# Setup
mkdir -p ~/.config/opencode
cd ~/.config/opencode
bun add file:~/opencode-anthropic-auth
echo '{"plugin":["opencode-anthropic-auth"]}' > opencode.json
echo 'export OPENCODE_DISABLE_DEFAULT_PLUGINS=true' >> ~/.zshrc
source ~/.zshrc

# Run
opencode

Uninstall

cd ~/.config/opencode && bun remove opencode-anthropic-auth
rm -rf ~/opencode-anthropic-auth

youre in the wrong branch in the picture broski

@Sewer56
Copy link

Sewer56 commented Jan 9, 2026

Can we not keep the renaming? #10 (comment)

One could easily just check for oc_ and reject a request.
Instead, capitalize them to match Claude Code tools.

@JimiHFord
Copy link

youre in the wrong branch in the picture broski

@harshav167 which one is the right branch? 😅

@JimiHFord
Copy link

Can we not keep the renaming? #10 (comment)

One could easily just check for oc_ and reject a request. Instead, capitalize them to match Claude Code tools.

@Sewer56 that was my first thought too

@nguyenngothuong
Copy link

nguyenngothuong commented Jan 9, 2026

✅ Confirmed Working!

Just applied this fix on Ubuntu VPS and authentication is working perfectly now. Thanks for the quick fix and merge!

Setup Details:

  • Environment: Ubuntu VPS with OpenCode 1.1.8, tmux session
  • Issue: Getting "credential only authorized for Claude Code" error with Claude Max OAuth tokens
  • Solution Applied:
    1. Cloned this repo with PR fix: align claude oauth request shape #11 merged (v0.0.7)
    2. Updated ~/.config/opencode/config.json:
      {
        "plugin": ["file:///root/opencode-anthropic-auth/index.mjs"]
      }
    3. Added to ~/.bashrc: export OPENCODE_DISABLE_DEFAULT_PLUGINS=true
    4. Re-authenticated with opencode auth login → Selected Anthropic → Claude Pro/Max

Result: OAuth authentication now works without errors! 🎉

The fix properly aligns the request signature with Claude Code by adding the beta=true query parameter and correct user-agent header. Perfect solution for the Jan 9, 2026 API change.

Thanks @harshav167 for creating this fix and @rekram1-node for the quick merge!

@harshav167
Copy link
Contributor Author

@Sewer56 @JimiHFord short answer: we can match CC tool names, but it’s not required to fix the OAuth rejection. The 400 is returned before any tool calls are processed; this PR fixes the request signature so tokens are accepted. I kept oc_ because it’s the smallest change and already merged in #10. If we want {name}_tool/PascalCase matching, that should be a follow-up with a clear mapping + collision checks.

@itlackey
Copy link

itlackey commented Jan 9, 2026

Bumped version to 0.0.7 and installed. Back in business! Thanks for the quick work!

@Sewer56
Copy link

Sewer56 commented Jan 9, 2026

@harshav167 I am aware, however. If we keep the oc_ prefix, then it's trivial to just make a change server side on their end to block the clients again. Heck, you may be at the risk of getting banned since at that point as it's super obvious you're going around the intended blockade. You're telling the whole world you're using OpenCode.

@rekram1-node
Copy link
Contributor

^^ this is a good point and should be fixed before people use it

@harshav167
Copy link
Contributor Author

@Sewer56 @rekram1-node fair point. The oc_ prefix is easy to fingerprint. PR #10 already merged that behavior, but I agree we should replace it with a less obvious mapping.

Proposal for follow‑up: map tool names to Claude Code conventions ({name}_tool / PascalCase) and strip any OpenCode‑specific prefixes entirely. That keeps tool calls working without advertising “OpenCode” in the payload.

I kept oc_ in this PR only because it was already merged and this change is focused on unblocking OAuth at the request‑acceptance layer.

@kzhrv
Copy link

kzhrv commented Jan 9, 2026

You have to map to Claude Code conventions.

Random strings won't cut it either as there is length, algorithm, etc., already encoded in these "random strings".

@harshav167
Copy link
Contributor Author

You have to map to Claude Code conventions.

Random strings won't cut it either as there is length, algorithm, etc., already encoded in these "random strings".

youre more than welcome to do it bro 😊

@Th0rgal
Copy link

Th0rgal commented Jan 9, 2026

Thanks @harshav167 , I thought I was going to have to use my human tokens

fernando234234 added a commit to fernando234234/Roo-Code that referenced this pull request Jan 9, 2026
Fixes Claude Code OAuth token authentication issues by aligning the
request shape with what Anthropic's API expects for OAuth tokens.

Changes:
- Update User-Agent to match Claude CLI format: "claude-cli/VERSION (external, cli)"
- Remove fine-grained-tool-streaming beta header (incompatible with OAuth)
- Add tool name prefixing with "oc_" prefix to bypass tool validation
- Strip prefix from tool names in responses for internal consistency
- Prefix tool names in conversation history to match tool definitions

The tool name prefixing is necessary because Anthropic's API validates
tool names against a known list when using OAuth tokens. By prefixing
with "oc_" we can use custom tool names while maintaining compatibility.

Inspired by fixes from:
- anomalyco/opencode-anthropic-auth#10
- anomalyco/opencode-anthropic-auth#11

Thanks to @anomalyco for the original research and implementation.
@Adam0Sam
Copy link

Adam0Sam commented Jan 9, 2026

you're a godsend @harshav167 . made my day 🙏

@aw338WoWmUI
Copy link

is it possiable that we can use anthropic agent sdk to use the claude code subs?

@chrisayl
Copy link

chrisayl commented Jan 9, 2026

Sadly, it's back again

@igordertigor
Copy link

Back for me too. Used to work for a few hours in between.

roomote bot pushed a commit to RooCodeInc/Roo-Code that referenced this pull request Jan 11, 2026
Fixes Claude Code OAuth token authentication issues by aligning the
request shape with what Anthropic's API expects for OAuth tokens.

Changes:
- Update User-Agent to match Claude CLI format: "claude-cli/VERSION (external, cli)"
- Remove fine-grained-tool-streaming beta header (incompatible with OAuth)
- Add tool name prefixing with "oc_" prefix to bypass tool validation
- Strip prefix from tool names in responses for internal consistency
- Prefix tool names in conversation history to match tool definitions

The tool name prefixing is necessary because Anthropic's API validates
tool names against a known list when using OAuth tokens. By prefixing
with "oc_" we can use custom tool names while maintaining compatibility.

Inspired by fixes from:
- anomalyco/opencode-anthropic-auth#10
- anomalyco/opencode-anthropic-auth#11

Thanks to @anomalyco for the original research and implementation.
@joachim-isaksson
Copy link
Contributor

opencode itself seems to point to this PR as the one that kills the context-1m-2025-08-07 beta header that I add in my config when accessing /messages once again. I'm not sure I follow everything in the discussion here around that, but could that be fixed? I like my 1m context window and I presume claude code sends that header to get that context window too? :-/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.