This is the second post in my Claude Code Tools Deep Dive series. The previous post unpacked AskUserQuestion, a structured tool that lets users choose from concrete options. This time, we're looking at its sibling: EnterPlanMode.
Before reading this post, it may help to read the series prelude on how Claude Code's tool mechanism works. This article follows the same four-layer framework introduced there.
EnterPlanMode
Like AskUserQuestion, EnterPlanMode is a tool you may encounter almost every day. But its design is much heavier. It does not merely ask a question; it switches Claude into an entirely different mode of operation.
What It Does
EnterPlanMode is Claude Code's built-in entry point into planning mode. Its job is simple but forceful: move Claude from the default "think while writing" workflow into a planning workflow built around read-only exploration and solution design. Claude returns to implementation only after the user explicitly approves the plan.
The core problem it solves is alignment between the AI and the user:
- Prevent work from drifting in the wrong direction — Claude aligns on the approach before modifying a single file.
- Enforce read-only exploration — once plan mode is active, Edit, Write, and NotebookEdit are disabled. Claude cannot quietly make changes while it explores.
- Create an explicit decision boundary — the user can approve, reject, or request changes to a complete proposal instead of discovering a wrong direction only after seeing the pull request.
- Produce a traceable planning artifact — plan mode creates a written plan that can be referenced and revised, rather than a paragraph that disappears into the chat history.
A Concrete Example
Scenario: the user tells Claude, "Refactor this authentication module and replace JWT with session cookies."
The request sounds clear, but it actually spans login routes, token-generation middleware, frontend storage, session-expiration policy, database schema decisions, and backward compatibility for existing API consumers. It is a multi-file, multi-decision, dependency-heavy change.
The Anti-Pattern: Working Without EnterPlanMode
Without a planning boundary, Claude has to infer an approach from the available context and start editing immediately:
- Open
auth/middleware.tsand switch it to reading a session cookie. - Open
auth/routes.ts, remove JWT issuance, and replace it withreq.session. - Open
frontend/api.tsand remove theAuthorizationheader logic. - Open
models/user.tsand add asessionIdfield. - Halfway through the refactor, discover that three other services authenticate against the same API with JWTs.
The user sees the diff and says: "I only wanted sessions for the web app. The backend services still need JWT. Why did you replace authentication for the entire API?"
Several things went wrong:
- The directional error surfaced five steps too late — four files have already changed, so rollback is painful.
- The decision boundary was unclear — "replace all authentication or only the web flow?" was a critical fork, but Claude guessed without asking.
- The user never saw the whole picture — they received a pile of diffs and had to reverse-engineer the intended design.
- Important side effects were never surfaced — should the system create a sessions table? Should session state live in memory, Redis, or the database? Claude may have considered these questions, but never turned them into an explicit proposal.
- Rollback is expensive — every edit consumes tokens and attention; discarding the implementation wastes both.
The core pain: "think while writing" lets Claude generate diffs before the approach is stable, while the user cannot see the full design until the end.
How EnterPlanMode Fixes It
Claude first declares that it wants to enter plan mode and asks for the user's approval. That transition is itself an interactive confirmation. If the user declines, Claude remains in the default mode.
Step 1: Enter Read-Only Exploration
Claude's toolset becomes narrower:
- ✅ Available: Read, Glob, Grep, Agent, AskUserQuestion, and ExitPlanMode
- ❌ Disabled: Edit, Write, and NotebookEdit
Claude physically cannot modify project files. Every exploration action is read-only.
Step 2: Understand the Current System
- Use Grep to find every JWT reference and discover the three internal services.
- Use Read to inspect the current validation logic in
auth/middleware.ts. - Use Glob to locate authentication-related tests.
- Use Agent to assign a general-purpose subagent to investigate whether the project already has a session-store convention.
Step 3: Clarify Critical Forks with AskUserQuestion
For example:
- Replace JWT only for the web app, or everywhere?
- Store sessions in memory, Redis, or the database?
This is exactly the clarification pattern discussed in the previous post. AskUserQuestion and EnterPlanMode are natural partners.
Step 4: Write the Plan
Claude writes the complete proposal to a plan file: scope, affected files, migration steps, risks, and rollback strategy. This is a revisable, referenceable artifact—not a transient chat message.
Step 5: Request Approval with ExitPlanMode
The user sees the complete plan and chooses what happens next:
- ✅ Approve → Claude returns to implementation mode and executes the plan.
- ✏️ Request changes → Claude revises the plan using the feedback.
- ❌ Reject → Claude changes direction.
Not a single project file is modified before approval. The user's tokens, time, and attention are not spent implementing the wrong approach.
Side-by-Side Comparison
| Anti-pattern pain | EnterPlanMode's solution |
|---|---|
| Directional error discovered five steps too late | No project files can be changed before ExitPlanMode approval |
| Unclear decision boundaries | AskUserQuestion clarifies critical forks inside plan mode |
| User cannot see the big picture | The plan file presents a complete proposal instead of scattered diffs |
| Important side effects are not surfaced | The enforced explore → design → present sequence gives Claude time to reason through them |
| High rollback cost | Exploration is read-only, so rejecting a plan requires no code rollback |
When to Use It
The tool's official description contains an interesting rule: non-trivial implementation tasks should default to planning. This is a deliberately conservative bias.
Seven Situations That Call for Plan Mode
- Implementing a new feature — even small features hide decisions: where should the code live, what should the button do, and how should errors be handled?
- Multiple reasonable approaches — "add caching" may mean Redis, memory, or files; "real-time updates" may mean WebSockets, SSE, or polling. The choice itself is design work.
- Changing existing behavior — "update the login flow" is ambiguous. Define the change before touching the code.
- Making architectural decisions — patterns, dependencies, and data-flow direction should be agreed upon.
- Changes spanning more than two or three files — the impact is large enough that a diff no longer communicates the whole design.
- Unclear requirements — "make the app faster" requires profiling and a discussion of optimization priorities first.
- Implementation shaped by user preferences — if you need AskUserQuestion to clarify the approach, you probably need EnterPlanMode to develop it.
Four Situations That Do Not
- A one-line fix — correcting a typo or an obvious off-by-one error.
- Adding one clearly specified function — implement it directly; there is no need for ceremony.
- The user already supplied precise, detailed instructions — the user has already done the planning, so repeating it adds friction.
- Pure research or exploration — use the Agent tool with an explore agent when no implementation will follow.
One phrase in the original description is especially revealing: "err on the side of planning." When uncertain, plan first. The default itself exposes the designers' preference: bias toward alignment over speed.
Technical Design
1. Naming
EnterPlanMode
AskUserQuestion carries signals across all four design layers. EnterPlanMode distributes them very differently: the name performs work that a schema might otherwise do.
-
Enteris a verb that implies moving into a state—not fetching data or performing a one-off action. -
PlanModenames that state and forms a natural pair withExitPlanMode.
Consider a counterfactual design: SetMode(mode: "plan"). The model might interpret that as setting a property and switch modes casually. The current name encodes a ceremonial state transition: entering is explicit, and exiting is explicit. Its semantics are much stronger than a parameterized SetMode.
That is why the schema can be empty. The name has already locked down the meaning, so the schema does not need to rescue it.
2. Tool-Level Description
EnterPlanMode's description revolves around four questions: when to use it, when not to use it, how it divides work with neighboring tools, and what happens at runtime.
A Conservative Opening Bias
Prefer using EnterPlanMode for implementation tasks unless they're simple.
One sentence reshapes Claude's behavior. When uncertain, plan instead of immediately acting. The tool starts by moving the default setting toward caution.
Quantified Thresholds for Seven Use Cases
The "When to Use This Tool" section lists seven numbered cases, each with concrete signals. A representative example is:
Multi-File Changes: The task will likely touch more than 2-3 files
This supplies a quantified threshold instead of asking Claude to trust a subjective feeling. Intuition becomes an operational rule, reducing inconsistency around whether plan mode is warranted.
The Boundary with AskUserQuestion
If you would use AskUserQuestion to clarify the approach, use EnterPlanMode instead
This turns a fuzzy boundary into a direct rule: AskUserQuestion handles isolated clarification, while approach-level forks call for plan mode. It prevents the anti-pattern of repeatedly asking disconnected questions and trying to assemble the answers into a plan afterward.
The Boundary with Agent
Pure research/exploration tasks (use the Agent tool with explore agent instead)
This defines another boundary: do not use EnterPlanMode for research that will not lead to implementation. Plan mode exists for planning before implementation. If implementation is not the goal, entering it is wasted motion; delegate the investigation to an explore agent instead.
User Approval Is Mandatory
This tool REQUIRES user approval - they must consent to entering plan mode
The AI cannot unilaterally change the workflow. The user guards the transition. This also explains why the tool accepts no arguments: the call itself is a request, not the execution of a parameterized operation.
The Default Under Uncertainty
If unsure whether to use it, err on the side of planning - it's better to get alignment upfront than to redo work
This is the description's statement of values: a round of alignment is cheaper than an incorrect implementation and rollback. The same philosophy appeared in AskUserQuestion. Claude Code's tool ecosystem consistently favors alignment.
Planning as Collaboration Etiquette
Users appreciate being consulted before significant changes are made to their codebase
This sentence trains Claude's social intuition. Planning is not merely an efficiency mechanism; it respects the user's ownership of the codebase. The framing encourages Claude to treat consultation as good collaboration rather than an interruption.
3. Field-Level Descriptions
None.
EnterPlanMode has no input fields. Its schema is the empty object {}, so this layer does not exist. Every behavioral signal moves up into the tool-level description.
4. Schema Validation Rules
None.
The input_schema is empty: no fields, no types, and no constraints. Calling the tool is itself the intention to change state; there is no data to pass.
That absence is a design signal in its own right: permission is enforced at the tool and runtime layers, not the parameter layer. Claude does not need to request individual permissions or specify a target mode. After Claude calls EnterPlanMode, the runtime automatically:
- Requires user approval, just as AskUserQuestion requires user interaction.
- Narrows the tool allowlist by disabling Edit, Write, and NotebookEdit.
- Refreshes CWD-dependent caches, including system-prompt sections, memory files, and the plans directory, so plan mode starts with clean context.
- Keeps the state active until Claude explicitly calls ExitPlanMode.
Unlike AskUserQuestion, which ends after the answer arrives, plan mode is a persistent state.
Division of Responsibility with Neighboring Tools
- AskUserQuestion — clarify one decision: "A or B?"
- EnterPlanMode — develop the complete proposal; AskUserQuestion remains available while planning.
- ExitPlanMode — submit the proposal for user approval.
Together, the three tools form a complete decision pipeline:
Encounter an unclear fork
↓
AskUserQuestion: clarify A vs. B
↓
EnterPlanMode: enter planning mode
├─ Explore with Grep / Read / Glob / Agent
├─ Clarify sub-decisions with AskUserQuestion as needed
└─ Write the plan file
↓
ExitPlanMode: submit the plan
├─ User approves → return to default mode and implement
├─ User requests changes → revise in plan mode
└─ User rejects → stop or change direction
As discussed in the AskUserQuestion post, Claude should not use AskUserQuestion inside plan mode for the meta-question, "Is this plan OK?" The reason is temporal: the user cannot see the plan until ExitPlanMode presents it for approval. Asking whether an invisible plan is acceptable is meaningless.
Takeaway
EnterPlanMode's elegance is not simply that it "makes the AI think before acting." It comes from an extremely uneven distribution of design signals:
- The name carries the core semantics through the Enter/Exit pairing.
- The tool-level description carries a dense set of behavioral constraints: seven use cases, a conservative default, neighboring-tool boundaries, and collaboration etiquette.
- The field-description and schema-validation layers are empty.
That reveals a deeper principle: an empty schema is itself a design choice. When a tool's meaning is "transition into a state," parameterizing it can weaken the meaning. SetMode invites casual switching. A zero-argument EnterPlanMode is a deliberate, ceremonial request.
The next post will examine ExitPlanMode, the final stage of this three-tool decision pipeline, and unpack how "submit a plan for approval" is designed.
Top comments (1)
The empty schema point is interesting because it turns the tool into a mode boundary instead of a data request. In practice that matters: the user is not answering a field, they are changing the contract of the session from execution to planning. That should feel heavier than a normal tool call.