Skip to content

[Plugins] Prototype: auto-approve run_tool under HITL via PreToolUse hook (flag-gated)#23

Open
swarup-padhi-glean wants to merge 1 commit into
mainfrom
auto-approve-run-tool-hook
Open

[Plugins] Prototype: auto-approve run_tool under HITL via PreToolUse hook (flag-gated)#23
swarup-padhi-glean wants to merge 1 commit into
mainfrom
auto-approve-run-tool-hook

Conversation

@swarup-padhi-glean

Copy link
Copy Markdown
Contributor

Problem

When HITL is on, a run_tool call draws two prompts: Claude Code's native "allow this tool?" gate and the plugin's own HITL elicitation. The intended suppressor — marking run_tool readOnlyHint — is advisory, and Claude Code's permission system doesn't auto-approve on it, so the double-prompt remains. A plugin also can't write to permissions.allow.

Prototype (flag-gated, default off)

A plugin-bundled PreToolUse hook that returns permissionDecision: allow for run_tool, so Claude Code's native prompt is suppressed and the HITL elicitation becomes the single gate.

Two gates, both required to auto-approve:

  • new flag HITL_AUTO_APPROVE (default "false"), and
  • ENABLE_HITL=true — if HITL isn't gating, the hook does nothing (never auto-approves an ungated write).

The hook reads both flags from the plugin's .mcp.json (the hook process doesn't inherit the MCP server's env).

Scope

  • plugins/glean/hooks/hooks.jsonPreToolUse matcher on run_tool.
  • plugins/glean/hooks/auto-approve-run-tool.mjs — the decision script.
  • plugins/glean/.claude-plugin/plugin.jsonhooks field (+ version).
  • plugins/glean/.mcp.jsonHITL_AUTO_APPROVE: "false".
  • Claude Code onlyPreToolUse hooks are Claude-Code-specific; Cursor/Codex are unaffected.

Safety / review notes

  • Default off; opt-in via the flag.
  • Never suppresses a prompt unless HITL is actually gating (ENABLE_HITL=true).
  • Composes with other PreToolUse hooks — a stricter deny/ask from another hook (e.g. a security policy) still wins.
  • This is a plugin self-exempting its own tool from the native prompt — flagged for explicit review. Pairs with raising the readOnlyHint gap upstream as the longer-term fix.
  • The matcher (mcp__.*run_tool) may need tuning to Claude Code's exact tool-name format; live testing will confirm.

Tests

4 hook tests: allow when flag+HITL on; no-op when flag off; no-op when HITL off (safety); ignores non-run_tool. Build + typecheck + tests green.

…HITL

When HITL is on, run_tool draws two prompts: Claude Code's native
allow-this-tool gate AND the plugin's own HITL elicitation. readOnlyHint
(the intended suppressor) is advisory and Claude Code doesn't honor it,
and a plugin can't write to permissions.allow. This ships a plugin
PreToolUse hook that returns permissionDecision:allow for run_tool so the
native prompt is suppressed and HITL is the single gate.

Gated behind HITL_AUTO_APPROVE (default false) AND only when
ENABLE_HITL=true — never auto-approves an ungated write. Hook reads both
flags from the plugin .mcp.json (it doesn't inherit the server env).
Claude Code only; Cursor/Codex unaffected.
swarup-padhi-glean added a commit that referenced this pull request Jun 22, 2026
Three open PRs (#21/#22/#23) were stacked on 0.2.31; move this one to the
next version so it stays strictly above main and mergeable regardless of
order against a single 0.2.31 PR.
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