← Claude Code Hub
Jun 28, 2026 · 3 min read ✦ Tip #117

Stop approving every plan in Claude Code (without opening the floodgates)

You kick off a plan, step away, and come back to find it idle, waiting for your OK. A hook scoped to one permission auto-approves the plan while bash, edits and MCP keep asking.

From plan ready to approved: the "proceed with the plan?" prompt is answered by a PermissionRequest hook with matcher ExitPlanMode, while Bash, Edit and MCP keep asking for permission

TL;DR A PermissionRequest hook with "matcher": "ExitPlanMode" that returns {"behavior":"allow"} approves only the "proceed with the plan?" prompt. Bash, edits, and MCP keep asking as usual. The narrow matcher is the whole point: you automate one permission, not all of them. Built for the interactive session: in a claude -p run with no permission host, ExitPlanMode isn't even available, so there is no plan to approve.

You kick off a big plan. You get up for a coffee, or move to another task. You come back ten minutes later and Claude hasn't touched a thing: it's been sitting there the whole time, waiting for you to hit "yes, proceed." Dead time, for a permission you were going to grant anyway.

The good part: that one permission can be automated. And only that one.

How it works

When Claude leaves plan mode it calls a tool, ExitPlanMode, which requires permission. The PermissionRequest event fires right when the approval dialog would appear. A hook can answer it for you with behavior: allow. Scoped with "matcher": "ExitPlanMode", it touches only that permission, nothing else.

Result:

Here's my plan:
  1. ...
  2. ...

✓ Allowed by PermissionRequest hook

No waiting on your click.

How to set it up

1. The hook in settings.json

In ~/.claude/settings.json (or the project's .claude/settings.json):

{
  "hooks": {
    "PermissionRequest": [
      {
        "matcher": "ExitPlanMode",
        "hooks": [
          {
            "type": "command",
            "command": "echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PermissionRequest\",\"decision\":{\"behavior\":\"allow\"}}}'"
          }
        ]
      }
    ]
  }
}

The command writes the decision to stdout. That's all: the plan approves itself.

2. The narrow matcher is the safety

"matcher": "ExitPlanMode" makes the hook answer only that permission. An rm, an edit, an MCP call still prompt you like always. You automate one specific thing without dropping your guard on the rest.

When the tool name alone isn't narrow enough, the entry also takes an if field holding a permission rule, which scopes by what that tool is about to do: conditional hooks.

3. Built for the interactive session

In claude -p, PermissionRequest hooks do run, but ExitPlanMode is only available when the run has a permission host (an Agent SDK canUseTool callback or a --permission-prompt-tool). With no host there is no plan to approve; with one, the hook runs alongside it and whichever answers first decides. And if a permission is denied in -p, nothing warns you: in headless the run still ends green. On approval, Claude Code restores the permission mode you had before entering plan.

What NOT to do

A variant going around also flips to bypassPermissions after approving the plan, so nothing prompts again. That's the opposite of the idea: it opens the floodgates. If you want to keep reviewing bash and edits, skip it. The value is precisely the narrow matcher.

Reference

Piece Value
Event PermissionRequest (interactive, or -p with a permission host)
Matcher ExitPlanMode (bare name, no specifier)
Output {"hookSpecificOutput":{...,"decision":{"behavior":"allow"}}}
Scope Only the exit-plan-mode permission

Official docs: Automate actions with hooks

It pairs with plan mode, where the permission comes from, and with the /permissions system (deny/allow/ask), the programmable layer of which this hook is part. And the plan you approve is a .md file you can keep in your repo with one setting.

Requirements

  • Claude Code v2.1.x. The hook fires when Claude Code is about to ask you to approve the plan: in the interactive session, or in -p with a permission host.
  • ExitPlanMode requires permission, which is why it can be intercepted.

This hook automates a single permission. To cut the rest without opening the floodgates, the permissions guide ranks the five levers by risk.

Found this useful? See more of wmedia.es in your Google results.

Add wmedia.es as a preferred source on Google
FREE GUIDE

You don't need Opus every time.

Model and effort are two settings, not one. 8 pages with the settings that actually move your bill, a three-question diagnostic for when something fails, and the price ladder.

  • 1. What "better" means capability, time and money
  • 2. Model who you send
  • 3. Effort how much rope you give
  • 4. Diagnostic three questions when something fails
  • 5. The bill where it comes from
Are you a professional Web developer?

You'll receive the guide by email · You join the Gravitas newsletter · Unsubscribe anytime

of 8
#

Wmedia · 8 pages
FREE GUIDE · 8 pages · 2 dials

You don't need Opus every time.

Model and effort are two settings, not one. 8 pages with the settings that actually move your bill, a three-question diagnostic for when something fails, and the price ladder.

Are you a professional Web developer? · Unsubscribe anytime
How I use AI

My Claude Code workflow.

The skills, agents and instructions I use as a professional Software Engineer. It's called Craft, and it's a plugin you can install.

See the skills

Using Opus for everything? See when you don't need it.