Skip to content

fix(claude): remap Bifrost custom tools for OAuth cloaking#3214

Open
etnperlong wants to merge 4 commits intorouter-for-me:devfrom
etnperlong:fix/claude-custom-tool-remap
Open

fix(claude): remap Bifrost custom tools for OAuth cloaking#3214
etnperlong wants to merge 4 commits intorouter-for-me:devfrom
etnperlong:fix/claude-custom-tool-remap

Conversation

@etnperlong
Copy link
Copy Markdown

Summary

This fixes Claude OAuth tool cloaking for Anthropic Messages requests that pass through Bifrost.
When Bifrost forwards custom tools, it normalizes them into Anthropic-style entries such as:

{
  "type": "custom",
  "name": "bash"
}

CLIProxyAPI was treating any tool with a non-empty type as a Claude built-in tool. That worked for real Anthropic built-ins like web_search_20250305, but it also caused Bifrost-shaped custom tools to be skipped by the OAuth tool remapping logic.
As a result, requests forwarded through Bifrost could still expose lowercase third-party tool names like bash, read, and glob, even though direct Claude Code / OpenCode-style traffic would be remapped to Bash, Read, and Glob.

Why this matters

For Claude OAuth traffic, tool naming is part of the request fingerprint.
This project already remaps third-party tool names to Claude Code-style names to avoid that fingerprint. But the previous logic broke down once an upstream proxy rewrote custom tools into type: "custom" entries.
In practice, this meant:

  • direct requests could be cloaked correctly
  • the same request forwarded through Bifrost could bypass that cloaking
  • custom tools could be misclassified as built-ins and left unchanged
    That made the behavior inconsistent across Anthropic Messages clients and proxy paths.

What changed

This patch makes the built-in detection stricter:

  • only real Anthropic built-in tool types are treated as built-ins
  • type: "custom" tools are still handled as third-party custom tools
  • unknown typed tools are no longer added to the Claude built-in registry
    For Bifrost-shaped custom tools, the request is now normalized back into the form expected by the existing OAuth cloaking flow:
  • the custom tool name is remapped (bash -> Bash, etc.)
  • the synthetic type: "custom" field is removed before forwarding upstream

Tests

Added regression coverage for:

  • type: "custom" tools still receiving Claude OAuth tool prefix/remap handling
  • real built-in typed tools remaining untouched
  • type: "custom" and unknown typed tools staying out of the built-in registry

Validation

Tested with focused executor and helper package tests.
This was also verified against real traffic: after rebasing and deploying the patch, OpenCode requests forwarded through Bifrost were handled correctly by the Claude OAuth cloaking path.

## Optional shorter version
If you want a slightly shorter body for GitHub:
```md
## Summary
Fix Claude OAuth tool cloaking for Anthropic Messages requests forwarded through Bifrost.
Bifrost normalizes custom tools into entries like:
```json
{"type":"custom","name":"bash"}

CLIProxyAPI was treating any typed tool as a Claude built-in tool. That was too broad. Real built-ins such as web_search_20250305 should be preserved, but Bifrost-shaped custom tools should still go through the OAuth remapping path.
Because of that misclassification, forwarded requests could skip remapping for custom tools like bash, read, and glob, even though direct traffic would correctly become Bash, Read, and Glob.

Changes

  • treat only real Anthropic built-in tool types as built-ins
  • keep type: "custom" tools in the third-party remap flow
  • remove synthetic type: "custom" before forwarding upstream
  • prevent type: "custom" and other unknown typed tools from entering the built-in registry

Why this is needed

For Claude OAuth traffic, tool names are part of the client fingerprint. This project already rewrites third-party tool names to match Claude Code behavior, but that protection was bypassed when a proxy rewrote custom tools into type: "custom" entries.
This patch restores consistent cloaking behavior for both direct and Bifrost-forwarded Anthropic Messages requests.

Tests

Added regression tests covering:

  • remapping of Bifrost-shaped custom tools
  • no remapping for real built-in typed tools
  • correct built-in registry behavior for type: "custom" tools

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

This pull request targeted main.

The base branch has been automatically changed to dev.

@github-actions github-actions Bot changed the base branch from main to dev May 4, 2026 17:38
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves the identification of Claude built-in tools by checking tool types against a known list, including versioned suffixes. It also updates the OAuth tool remapping logic to remove the type field from custom tools to prevent processing issues. Comprehensive tests were added to verify these behaviors. The review feedback suggests optimizing the IsClaudeBuiltinToolType function to avoid unnecessary string allocations during prefix checks.

Comment thread internal/runtime/executor/helps/claude_builtin_tools.go
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 024ae66885

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread internal/runtime/executor/helps/claude_builtin_tools.go Outdated
@etnperlong etnperlong force-pushed the fix/claude-custom-tool-remap branch from 024ae66 to 59fc564 Compare May 5, 2026 09:39
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59fc564d36

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread internal/runtime/executor/claude_executor.go Outdated
@etnperlong etnperlong force-pushed the fix/claude-custom-tool-remap branch 3 times, most recently from efb9aa7 to 2395d50 Compare May 10, 2026 08:03
Treat only Anthropic built-in tool types as builtins so type:"custom" tools still get Claude Code name remapping. This keeps OAuth cloaking consistent across Anthropic Messages clients and prevents custom tools from being skipped.
Recognize newer builtin tool types so OAuth cloaking does not strip their type fields or rewrite valid builtin names as custom tools.
Precompute Claude builtin type prefixes so hot-path builtin detection no longer concatenates strings for every tool check.
Only strip synthetic type:"custom" wrappers during Claude OAuth cloaking so opaque typed tools keep their definitions and names across remap and prefix handling.
@etnperlong etnperlong force-pushed the fix/claude-custom-tool-remap branch from 2395d50 to 842e524 Compare May 10, 2026 13:08
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.

1 participant