MCP approval for a project-scoped HTTP MCP server never persists across sessions
Approval for a .mcp.json-registered HTTP MCP server never persists across sessions
Environment
- Claude Code version: 2.1.204 (confirmed latest via
claude install latest) - OS: macOS 26.5.1 (BuildVersion 25F80), Darwin 25.5.0, arm64
Summary
After adding a remote HTTP MCP server via claude mcp add --transport http <name> <url> --scope project, approving it interactively at startup ("Use this and all future MCP servers in this project") and exiting cleanly, the server reverts to "⏸ Pending approval" on the very next session. This happens every time, with no configuration change in between.
Steps to reproduce
- In a project directory:
claude mcp add robinhood-trading --transport http --scope project https://agent.robinhood.com/mcp/trading
- This writes
.mcp.json:
``json``
{"mcpServers":{"robinhood-trading":{"type":"http","url":"https://agent.robinhood.com/mcp/trading"}}}
claude mcp listshows:robinhood-trading: ... (HTTP) - ⏸ Pending approval (run 'claude' to approve)- Run
claudein that directory. A prompt appears:
```
New MCP server found in this project: robinhood-trading
MCP servers may execute code or access system resources. All tool calls require approval.
- Use this MCP server
- Use this and all future MCP servers in this project
- Continue without using this MCP server
```
- Select option 2. The server connects and works normally for the rest of the session (verified: it can answer requests using the server's tools with no further login/auth prompt — the underlying OAuth credential for the remote server clearly is being stored/reused correctly).
- Exit cleanly with
/exit. - Run
claude mcp listagain (either from the same shell or a fresh one) → still shows⏸ Pending approval (run 'claude' to approve). - Run
claudeagain → same approval prompt reappears, as if step 3–5 never happened.
Expected behavior
After approving a project-scoped .mcp.json server once (option 2, "use this and all future MCP servers"), it should stay approved on subsequent claude invocations in that directory, the same way it does for stdio-based .mcp.json servers in our experience.
Actual behavior
The approval never sticks. Confirmed via ~/.claude.json's projects["<path>"] entry:
enabledMcpjsonServersstays[](ornullafterclaude mcp reset-project-choices) across every attempt.disabledMcpjsonServerslikewise never gets populated.- This is true even though
lastStartTimeandlastSessionIdfor that project do update each run (confirming the session itself, and its config writes in general, are working) andlastGracefulShutdownistrue(so it's not an abrupt-exit/flush issue).
Things ruled out while diagnosing this
- Not an ungraceful-exit issue — reproduced with confirmed
lastGracefulShutdown: trueand a clean/exit. - Not a wrong-working-directory issue — confirmed
pwdmatched exactly, confirmed via a distinctprojects[]key update each time. - Not a stale/corrupted local state issue — reproduced immediately after
claude mcp reset-project-choices, from a clean slate (enabledMcpjsonServers: null). - Not a stale binary/version issue — confirmed same resolved binary path (
~/.local/bin/claude→~/.local/share/claude/versions/2.1.204) in both the interactive shell and the shell running these checks, and confirmed already on the latest version viaclaude install latest. - Not a general
hasTrustDialogAcceptedgate issue — that flag isfalsethroughout (no folder-trust prompt appears at all in this project, separately from the MCP approval prompt), so it doesn't appear to be blocking the MCP approval write specifically, but is included here in case it's a related symptom.
Separately observed (may be related, may be a distinct issue): a headless claude -p ... invocation using an ad-hoc --mcp-config (either an inline JSON string or a path to the same .mcp.json) for this same server, with --strict-mcp-config, does not connect to it at all — the model reports no MCP tools are available. This is despite the server's OAuth credential clearly being valid and cached (interactive sessions never re-prompt for login). This may indicate that OAuth-authenticated remote HTTP MCP servers are not currently usable from -p/headless mode at all, independent of the approval-persistence bug above.
Impact
This blocks any workflow that depends on a project-scoped remote/OAuth MCP server surviving across sessions without re-approving every time, and separately blocks using such a server from a headless/scripted claude -p invocation at all.