[BUG] Cannot Exit Plan Mode in TypeScript SDK
Resolved 💬 3 comments Opened Jul 23, 2025 by omidmogasemi Closed Aug 19, 2025
Environment
- Platform (select one):
- [x] Anthropic API
- [ ] AWS Bedrock
- [ ] Google Vertex AI
- [ ] Other: <!-- specify -->
- Claude CLI version: 1.0.59
- Operating System: macOS 15.5
- Terminal: iTerm2
Bug Description
When attempting to get plan mode to work with the TypeScript SDK, we ran into the following error.
- We set
permissionModetoplan. - We then pass a custom MCP server to
mcpServersalong with a specific tool name topermissionPromptToolNameto handle permissions. This tool is a custom built HTTP server to communicate via our app's frontend for users to accept/deny tools. - This tool works for all tools _except_ allowing the
exit_plan_modetool. Denyingexit_plan_modeworks perfectly fine, but allowing it immediately kicks Claude Code off to implement the plan without changing thepermissionsModeaway fromplanmode, which gets it stuck in an infinite loop of requestingexit_plan_mode.
Steps to Reproduce
- Use the TypeScript SDK in
planmode - Setup a local
MCPserver for handling tool permissions - Approve a tool call to
exit_plan_modefrom Claude Code
Expected Behavior
Claude Code should either:
- Not fake a message on the user's behalf, and return control to the user after the user approves
exit_plan_mode. - More reasonably, change the
permissionsModeto something other thanplan(ideally this would be customizable via anoptionin the SDK).
Actual Behavior
- Claude fakes a message on the user's behalf approving the
exit_plan_modetool to the AI, but doesn't actually change thepermissionsModeso Claude Code gets stuck in an endless loop.
Additional Context
See the relevant logs from our process running Claude Code and the MCP server. Notice how there is a user message that our application never sent. The Claude Code SDK clearly creates this message on our behalf (which is fine), but it doesn't change the permissionsMode.
[2025-07-23T21:16:22.762Z] MCPServer: Sending manual approval response: {
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "{\"behavior\":\"allow\",\"updatedInput\":{\"plan\":\"...\"}}"
}
]
}
}
[2025-07-23T21:16:22.762Z] MCPServer: Response text content: {"behavior":"allow","updatedInput":{"plan":"..."}}
[2025-07-23T21:16:22.765Z] Received message 7: user [object Object]
[2025-07-23T21:16:22.765Z] Message 7 details: {
"type": "user",
"message": {
"role": "user",
"content": [
{
"type": "tool_result",
"content": "User has approved your plan. You can now start coding. Start with updating your todo list if applicable",
"tool_use_id": ...
}
]
},
"parent_tool_use_id": null,
"session_id": ...
}This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗