Auto mode refuses a function-hook plugin's own $.mcp.call, though the API says the plugin's call is the grant

Status Open
Reported on v2.1.288
Maintainer reply None cached
Activity 0 comments · opened Oct 8, 2026

Version: 2.1.288, desktop app (Code tab), macOS

What happens

A function-hook plugin draws a Button in the AbovePrompt band. Its press handler calls $.mcp.call('Claude_Browser', 'preview_start', { url }).

  • Permission mode default: the call runs with no prompt and the Browser pane opens.
  • Permission mode auto: the call is refused:
$.mcp.call(Claude_Browser, preview_start) refused: The server-side auto mode classifier gave no verdict for mcp__Claude_Browser__preview_start: the request that produced this action did not ask for one.

$.tool.check({ tool: 'mcp__Claude_Browser__preview_start', input: { url } }) returns { decision: 'ask', reason: 'Claude Browser requires permission.' } in both modes. A permissions.allow entry for mcp__Claude_Browser__preview_start does not change the decision.

Expected

The plugin API declaration of $.mcp.call says: "No permission prompt: the plugin's call, seen by the hooks above it, is the grant." Default mode behaves that way. Auto mode sends the call to the classifier instead, and the classifier looks for a user request in the transcript. A UI button press never produces one, so the call can never succeed in auto mode.

Impact

Any mod that calls an MCP tool from a UI interaction (Button, Input, Select) works in default mode and is always refused in auto mode.

Repro

  1. Write a mod with this hooks/register.tsx, enable hot reloading for the session:
import type { Register } from 'claude-code'

export const register: Register = on => {
  on('ui.render', { component: 'AbovePrompt' }, ($, e, next) => {
    if (e.surface !== 'desktop') return next(e)
    const { Button } = $.ui.resolve(e)
    return (
      <Button
        key="open"
        label="Open"
        onPress={() =>
          $.mcp.call('Claude_Browser', 'preview_start', { url: 'http://localhost:8000/' })
            .catch(error => $.ui.toast(String(error)))
        }
      />
    )
  })
}
  1. Set the session's permission mode to auto and press Open: the toast shows the refusal above.
  2. Switch to default and press Open: the Browser pane opens.

View original on GitHub ↗