[Bug] MCP tools with requiresUserInteraction not suppressing "don't ask again" option
Bug Description
Claude Code still offers "Yes, and don't ask again" for an MCP tool whose
tools/list entry sets _meta["anthropic/requiresUserInteraction"]: true.
Choosing it writes an allow rule into .claude/settings.local.json that the
tool then permanently ignores — the prompt still appears on every call.
Verified on 2.1.241 against a local Spring AI MCP server (tools/list confirmed
to emit the _meta on the tool entry).
Repro:
- MCP server exposes tool
writewith _meta["anthropic/requiresUserInteraction"]: true - Call it; the dialog shows "Yes, and don't ask again for <server> — Write commands in <dir>"
- Select that row -> {"permissions":{"allow":["mcp__<server>__write"]}} is written
- Call the tool again -> still prompted (correct per docs, but the rule is now dead)
But the prompt should not include:
2. Yes, and don't ask again for mcprui — Write commands in /repo/folder
only
1. Yes
Should be shown because the idea is that the user must answer that every time due to _meta["anthropic/requiresUserInteraction"]: true.
Expected: per the docs,
Claude Code shows that tool’s permission prompt on every call, even in acceptEdits, auto, and bypassPermissions permission modes, and _doesn’t offer a “don’t ask again” option for it._
Cause (from the 2.1.241 bundle): the meta is read as
U = M._meta?.["anthropic/requiresUserInteraction"] === true
and used for behavior: U ? "ask" : "passthrough" and suggestions: U ? [] : [...],
but checkPermissions never sets suppressAlwaysAllowRule on the returned ask result.
The row is gated on a different predicate:
!(permissionResult.behavior === "ask" && permissionResult.suppressAlwaysAllowRule === true)
&& tool.suppressesAlwaysAllowRule?.(input) !== true
For MCP tools the latter is anl(kLf(config), name) — driven by server config, not _meta.
Empty suggestions doesn't prevent persistence either, because handleUserAllow
synthesizes the whole-tool rule from the tool name.
Impact: the dead rule becomes silently live if the server ever stops sending the
_meta — a permission the user was shown as inapplicable, later granted for real.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗