Desktop app: worktree sessions reload every claude.ai connector; per-project disable list does not follow worktrees and deniedMcpServers cannot suppress app-injected connectors
Summary
In the Claude desktop app (Code tab), each session starts in a freshly created git worktree under <repo>/.claude/worktrees/<name>. Every claude.ai connector the account has is loaded into that session even though they were disabled for the repository in the app, and no settings-file key we could find suppresses them. The result is roughly 430 deferred tool names (about 10k tokens) in the system prompt on every turn of every coding session, with no way to opt out per repository.
Environment
- Claude Code 2.1.263 (also reproduced on 2.1.260), launched from the Claude desktop app's Code tab
- macOS (Darwin 25.6)
- Account has ~20 claude.ai connectors connected
Steps to reproduce
- In the desktop app, open a git repository and disable a set of connectors for it. This writes
projects["<repo path>"].disabledMcpServers = ["claude.ai Notion", …]into~/.claude.json. - Start a new session on that repository with the app's worktree mode, which creates
<repo>/.claude/worktrees/<name>and starts the session there. - Ask the session which MCP tools it has.
Expected
The worktree session inherits the repository's connector selection; the disabled connectors are absent.
Actual
Every connector loads. ~/.claude.json keys the disable list by absolute project path, and the worktree is a new path, so the list never applies. Each new worktree therefore starts with the full connector set, and worktrees are created per session.
What we tried in settings files (all ineffective for app-injected connectors)
deniedMcpServers entries in the repository's .claude/settings.json and in .claude/settings.local.json (which the app copies into each new worktree), tested in fresh worktree sessions:
{ "serverName": "claude.ai Notion" }— the display name the docs give as the example for connectors{ "serverName": "Notion" }— the barenamethe app uses in its session config{ "serverName": "<connector uuid>" }— the identifier the tools are registered under (mcp__<uuid>__…)
In every case all connectors still loaded. The app appears to hand connectors to Claude Code through its own session config (remoteMcpServersConfig, entries of {uuid, name, tools}) rather than through the CLI's own connector fetch, which would make them exempt from deniedMcpServers per the documented in-process exemption. disableClaudeAiConnectors was not tested because it would also remove connectors we want.
Other project-scope settings are read in these sessions (the sandbox block from settings.local.json is in force), so this is specific to connector handling, not a wholesale ignore of project settings.
Why it matters
The deferred tool list is paid on every turn. For a long coding session (median ~190 turns here) that is ~2M cache-read tokens per session of connector names that the repository explicitly opted out of, and it also lowers the usable room under any autoCompactWindow.
Suggested fixes (any one would resolve it)
- Resolve a linked worktree to its parent repository when looking up
projects[...].disabledMcpServersin~/.claude.json(the.gitfile in a worktree points at<repo>/.git/worktrees/<name>), so worktrees inherit the repository's connector selection. - Honor
deniedMcpServersfor connectors the desktop app injects, matching on the connector display name the docs already describe. - Failing both, document that connector selection in the desktop app is per absolute path and does not follow worktrees.
Related observation
In the same sessions, a project-scope effortLevel in .claude/settings.json never took effect: transcripts show the effort the app chose for the session (it varied between sessions with no settings change), while the docs describe the highest-precedence settings file as deciding. Happy to file that separately if useful.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗