[BUG] Running sessions lose all access to ~/Documents (macOS TCC) when a plugin's npx-launched MCP server is replaced on disk by a newer session
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?
Environment: Claude desktop app 2.7032.0 (Code tab), Claude Code 2.1.280, macOS 26.6.2 arm64, plugin azure 1.2.50 from claude-plugins-official.
Symptom: after some hours a session can no longer read anything under ~/Documents. Every open returns EPERM "Operation not permitted" (stat still works), the Read tool fails the same way, disabling the sandbox changes nothing, ~/Desktop and ~/Downloads keep working, and directories the session created itself stay readable (they carry com.apple.macl). New sessions are unaffected. Restarting the session fixes it. It recurs every few days.
Cause, from the tccd and sandboxd logs (sudo log show --info --debug) and live process state:
- The azure plugin's .mcp.json launches its server as: npx -y @azure/mcp@latest server start. When upstream publishes a new version, the first new session's npx reinstalls into ~/.npm/_npx/<hash>/ and replaces the azmcp binary while older sessions' azmcp processes still run from the unlinked file.
- For those processes proc_pidpath() fails with ENOENT (checked for all 17 running azmcp: the 10 started before the reinstall fail, the 7 after resolve).
- When such an azmcp touches a path under ~/Documents (its cwd is the project folder), the kernel sandbox asks tccd, which logs "proc_pidpath_audittoken() failed from PID[n]: No such file or directory" and "Failed to create Attribution Chain from message"; sandboxd logs "kTCCServiceSystemPolicyDocumentsFolder denied by TCC for azmcp". 292 such failures in the hour of the reinstall, the first 9 seconds after it.
- The azmcp's responsible process is the session's main claude process (the disclaimer helper makes it self-responsible), and afterwards every Documents check for that session is answered without consulting tccd: in a seven-minute window the same process reached tccd for kTCCServiceSystemPolicyAllFiles three times and for the Documents service zero times while every Documents read was refused. The TCC.db row for com.anthropic.claude-code (Documents, allowed, csreq matching) was intact throughout.
Suggested fixes: do not launch marketplace MCP servers with a floating @latest through npx (pin, or install once per plugin version), or reject such entries at plugin validation; and surface a TCC attribution failure to the user instead of a silent EPERM.
What Should Happen?
Work correctly....
Error Messages/Logs
Steps to Reproduce
Cause, from the tccd and sandboxd logs (sudo log show --info --debug) and live process state:
- The azure plugin's .mcp.json launches its server as: npx -y @azure/mcp@latest server start. When upstream publishes a new version, the first new session's npx reinstalls into ~/.npm/_npx/<hash>/ and replaces the azmcp binary while older sessions' azmcp processes still run from the unlinked file.
- For those processes proc_pidpath() fails with ENOENT (checked for all 17 running azmcp: the 10 started before the reinstall fail, the 7 after resolve).
- When such an azmcp touches a path under ~/Documents (its cwd is the project folder), the kernel sandbox asks tccd, which logs "proc_pidpath_audittoken() failed from PID[n]: No such file or directory" and "Failed to create Attribution Chain from message"; sandboxd logs "kTCCServiceSystemPolicyDocumentsFolder denied by TCC for azmcp". 292 such failures in the hour of the reinstall, the first 9 seconds after it.
- The azmcp's responsible process is the session's main claude process (the disclaimer helper makes it self-responsible), and afterwards every Documents check for that session is answered without consulting tccd: in a seven-minute window the same process reached tccd for kTCCServiceSystemPolicyAllFiles three times and for the Documents service zero times while every Documents read was refused. The TCC.db row for com.anthropic.claude-code (Documents, allowed, csreq matching) was intact throughout.
Claude Model
None
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.7032.0
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗