[BUG]

Status Open
Reported on v2.1.201
Maintainer reply ✓ Yes — bcherny
Activity 4 comments · opened Jul 6, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Title: MCP tool permission approval never reaches client — add_repo (and other gated tool calls) fail with “requires approval” indefinitely

Description:

In a Claude Code session (remote/web execution environment), calling a tool that requires interactive approval (add_repo from the claude-code-remote MCP server) consistently fails with:

Streamable HTTP error: Error POSTing to endpoint: MCP tool call requires approval

This happened on every retry (6+ attempts across the session), with no variation in the error. Earlier in the same session, other gated calls (AskUserQuestion, list_repos) intermittently failed with:

Tool permission request failed: Error: Tool permission stream closed before response received

and once with:

Denied by user

despite the user confirming they had not seen or interacted with any approval prompt. This suggests the approval request either never renders client-side, or the stream carrying the approval response closes/times out before the user’s client can respond.

Steps to reproduce:

  1. Start a Claude Code session in the remote/web execution environment.
  2. Have the assistant call a tool that requires interactive approval (e.g. add_repo to add a new GitHub repo to the session).
  3. Observe the approval prompt does not reliably appear in the client, or the response stream closes before an answer is recorded.
  4. Retries of the identical tool call return the same “requires approval” error with no prompt surfaced.

Impact: Session is completely blocked from using any tool gated behind interactive approval — no workaround available from within the chat.

Environment: Claude Code remote execution session (web/mobile client — exact surface unconfirmed by reporter).

What Should Happen?

Claude should be able to access GitHub Repository and continue

Error Messages/Logs

Steps to Reproduce

<img width="590" height="1278" alt="Image" src="https://github.com/user-attachments/assets/e281257a-eabe-4485-a00f-77d3c9cd0656" />
<img width="590" height="1278" alt="Image" src="https://github.com/user-attachments/assets/82d6cf6a-3479-4268-b8f0-7fcb1b6fcf18" />

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.201

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

3 Comments

rpelevin · 1 month ago

I would separate this into a permission-request delivery invariant rather than treating every retry as the same MCP tool failure.

For a gated MCP tool call, the runtime needs to distinguish at least five states:

  1. approval request was never created;
  2. request was created but not delivered to the active client;
  3. request was delivered, but the response stream closed before a decision was recorded;
  4. user explicitly denied the request;
  5. retry superseded or replayed a still-pending request.

Those should not all collapse into "requires approval" or "denied by user." They have different recovery behavior.

The acceptance test I would want is small:

  • emit a pending permission request with request id, tool name, server identity, and run/session id;
  • keep the run in waiting state until that exact request resolves, expires, or is superseded;
  • reject resume with a mismatched request id;
  • on retry, either reuse the pending request or create a new superseding request, but record which happened;
  • never execute the gated tool unless the matching approval decision is bound to the pending request.

That gives the client a debuggable contract: if the prompt never renders, the trace can show whether the failure was request creation, client delivery, response transport, explicit denial, or retry state.

bcherny collaborator · 14 days ago

Thanks for the detailed report — a few findings.

On 2.1.233 (Linux, terminal) I checked the permission-gated MCP tool path directly: a gated tool call is held for approval, is blocked with a clear message when no approval is given, and runs normally once approved. So MCP permission gating itself isn't broken generally.

Your report is about the web/cloud session surface, where the approval prompt has to be relayed to a browser or mobile client. That path can't be driven from a terminal, so we could not reproduce your exact scenario here.

That said, what you describe is a bug: a prompt that never appears, and a call reported as "Denied by user" when you were never shown anything, are both wrong. There is a fix in a release after the 2.1.201 you were on for pending permission prompts not appearing to clients (changelog) — it may or may not cover your case, so we're keeping this open.

To help us pin it down, could you confirm: which client you were on (claude.ai in a browser, or the mobile app), roughly when the session ran, and whether it still happens in a current session?

🤖 Generated with Claude Code

github-actions[bot] · 14 days ago

We weren't able to reproduce this. Could you provide steps to trigger the issue — what you ran, what happened, and what you expected? This issue will be closed automatically if there's no activity within 7 days.

Showing cached comments. Read the full discussion on GitHub ↗