feat: allowed_tools and require_approval for MCP servers (lands #328) - #476
Merged
Merged
Conversation
…CP tools The allowed_tools extraction in PR #328 broke 50 integration tests because Request#apply_defaults sets mcp_servers: [] on every request, and an empty array is truthy — so the MCP branch in normalize_params ran unconditionally and assigned params[:tools] = nil (via .presence), which the Anthropic gem then serialized as "tools": null on every request body. - Only assign params[:tools] when toolsets were actually extracted - Support allowed_tools as tool-name strings/symbols as well as {name: ...} hashes, ignoring entries in any other format - Make normalize_mcp_tools consistently return nil when nothing is extracted, and align test names with that behavior - Fix Layout/SpaceInsideArrayLiteralBrackets rubocop offenses Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BgneVvQLw5Uc9jQxRHz6Zj
…q8' into review-328
With function tools already declared, the Anthropic transform dropped a server's allowed_tools rather than send them, so the restriction was silently lost exactly when a request used both. The mcp_toolset entry is now appended to the request's tools. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KfFzc97pARf86bj8LNR59B
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KfFzc97pARf86bj8LNR59B # Conflicts: # CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lands #328 by @dark-panda, whose commit is kept as authored, plus the two follow-ups it needed to go green.
f1fb203— the original change: MCP servers acceptallowed_toolsandrequire_approvalin the common format. OpenAI Responses passes them through; Anthropic turnsallowed_toolsinto anmcp_toolsetentry (default_config: {enabled: false}, oneconfigsentry per allowed tool).414821c— the fix diagnosed on feat: Addallowed_toolsandrequire_approvalto option transforms #328 in July:Anthropic::Requestdefaultsmcp_servers: []on every request, so the new branch ran unconditionally and serialized"tools": null, failing 50 WebMock body expectations.:toolsis now set only when a toolset was extracted. Also acceptsallowed_toolsentries as strings/symbols, and fixes the rubocop offenses.aee2f01— new: with function tools already on the request, the transform previously kept them and dropped the server'sallowed_tools, silently losing the restriction exactly when a request used both. The toolset is now appended beside the existing tools; the test that pinned the old behaviour is updated.Testing
test/providers/anthropic/transforms_test.rb+test/providers/open_ai/responses/transforms_test.rb: 133 runs, 0 failures.SolidAgentRunsTestpricing failure thatmainalready has (fixed by feat: let the engine run host agent classes, and teach SchemaTools about Rails enums #467).Closes #328
🤖 Generated with Claude Code
https://claude.ai/code/session_01KfFzc97pARf86bj8LNR59B
Generated by Claude Code