Skip to content

fix(agents): gate skill-folded external MCP tools behind the approval prompt#478

Merged
philmerrell merged 1 commit into
developfrom
fix/skills-tool-approval-fold
Jun 12, 2026
Merged

fix(agents): gate skill-folded external MCP tools behind the approval prompt#478
philmerrell merged 1 commit into
developfrom
fix/skills-tool-approval-fold

Conversation

@philmerrell

Copy link
Copy Markdown
Contributor

Summary

Closes the skills-mode counterpart of the approval gate the same way #477 closed the OAuth consent gap.

MCPExternalApprovalHook gates needs_approval=True external MCP tools via approval_names_lookup(event.selected_tool), which only resolves when the selected tool is a Strands MCPAgentTool. In skills mode (the server default), a skill-bound external MCP tool executes through the skill_executor meta-tool — so the lookup returned an empty set, tool_use["name"] was "skill_executor" so the name match could never fire either, and an admin's needs_approval=True flag was silently bypassed: the tool ran with no user approval prompt.

How

Mirrors the fold-aware second-chance lookup from #477:

  • tool_approval.py — optional tool_use_approval_lookup on the hook; when the direct path doesn't fire, it resolves the folded target from the raw tool_use and raises the same tool_approval_required interrupt. The interrupt's toolName/toolInput describe the inner tool (e.g. gmail_send and its args from tool_use.input.tool_input), not the executor, so the frontend dialog is meaningful; toolUseId stays the executor's so the frontend correlates it with the streamed tool_use block. Decline cancels with the inner tool's name.
  • mcp_binding.py — shared _resolve_folded_tool extracted from the provider lookup; new make_folded_tool_approval_lookup checks the folded tool's agent-facing name against approval_names_for_client(client) (same name the direct path matches when the tool is enabled outside a skill).
  • base_agent.py / skill_agent.py_build_tool_use_approval_lookup extension point (None in base, registry-backed in SkillAgent), mirroring _build_tool_use_provider_lookup.

Stacked on #477

Base is fix/skills-oauth-consent-fold so the diff shows only this change (it reuses that PR's fold-resolution infrastructure). Retargets to develop when #477 merges.

Test plan

🤖 Generated with Claude Code

Base automatically changed from fix/skills-oauth-consent-fold to develop June 12, 2026 15:59
… prompt

An admin's needs_approval=True flag was silently bypassed in skills mode:
the flagged tool runs behind the skill_executor meta-tool, so the approval
hook's selected_tool lookup resolved nothing and the tool_use name never
matched. Mirror the OAuth consent fold fix — an optional tool_use-based
second-chance lookup resolves the folded target via the SkillRegistry,
checks it against the owning client's needs_approval set, and raises the
same tool_approval_required interrupt with the inner tool's name + args so
the dialog describes the real tool, not the executor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@philmerrell philmerrell force-pushed the fix/skills-tool-approval-fold branch from 3b872ca to a37504a Compare June 12, 2026 16:05
@philmerrell philmerrell merged commit 5373d00 into develop Jun 12, 2026
1 check passed
@philmerrell philmerrell deleted the fix/skills-tool-approval-fold branch June 12, 2026 16:20
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