File access in Claude Desktop's chat mode had been flaky for a while: sometimes there, sometimes not, no obvious pattern. The standard fix, the one Claude itself gives you in a plain chat, is to hand-edit claude_desktop_config.json. I did that, and before I'd even confirmed it worked on its own, found something else: the same Filesystem settings, filed under two completely different sidebar labels, with nothing anywhere saying they're the same page. I only noticed because I'd enabled an unrelated extension that gives Claude direct control of the Mac, and used it to go audit the settings properly.
I run a personal ops wiki, mostly read and written by Claude, across two Macs. File access from Claude Desktop's plain chat mode never felt fully trustworthy. It would work fine one session and fail the next, with no config change I was aware of in between. The easy answer is "just use Cowork mode instead," and that's fine advice, but it's a workaround, not a diagnosis. I wanted to know what was actually configured before deciding the lighter chat-mode access wasn't worth fixing.
Ask Claude in a plain chat how to set this up, and it points you at claude_desktop_config.json
: the classic mcpServers
JSON block, hand-edited, one entry per server. That's the answer in most guides.
I wrote a scoped filesystem entry and restarted. What I didn't do, and should have, was check whether that entry was actually controlling access, versus something already running underneath it. I never isolated a clean test of "JSON entry alone, nothing else present." Going to check what was actually granting access, I found a second settings screen already live and already configured, with no idea how long it had been running or how it related to what I'd just written.
Finding a settings screen I didn't know existed was reason enough to stop guessing. I had Claude use a separate extension, enabled earlier for unrelated automation and giving it direct AppleScript and shell control of the Mac, to read every settings file involved rather than trust what any single screen claimed.
What that turned up wasn't three independent systems fighting each other. It was more specifically annoying than that: the same Filesystem settings screen, reachable from two entirely different places in the sidebar, styled identically, with no cross-reference telling you they're the same page. Navigate in via Desktop app β Extensions β Filesystem
and you land on a page. Navigate in via Customize β Connectors β Filesystem
and you land on the exact same page: same toggle, same two allowed directories, same tool-permission list, pixel for pixel. Two doors, one room, and nothing on either door mentions the other.
Underneath that is a genuinely separate second thing: the raw claude_desktop_config.json
mcpServers
block, which is the old way of doing this and is still correct for anything Anthropic hasn't folded into the unified screen (a third-party server like GitHub's, for instance).
So the real shape isn't three settings surfaces. It's one legacy JSON method and one current GUI system that Anthropic's own navigation apparently can't decide whether to call "Extensions" or "Connectors," filing the identical screen under both mid-rename, with nothing explaining the overlap. If you've used Claude Desktop across months of incremental UI changes, that's exactly the setup for believing you configured two different things when you configured one thing twice, through two different-looking menus, at two different points in time.
Filesystem access was already being controlled by the GUI screen before I ever wrote the JSON entry, set at some earlier point I don't have a clean memory of, to a longer list of folders than the two I actually wanted. Old folders from old projects, added one at a time over months and never reviewed as a whole. Nothing dramatic in the contents. Just more than intended, with no memory of deliberately choosing all of it.
The part that actually mattered: the JSON entry I'd just written was now sitting live in mcpServers
at the same time as the GUI screen's own config, and I had no idea whether the JSON one was doing anything, doing something partial, or fully inert. I didn't want to find out by trial and error what two separate filesystem MCP servers both claiming the same job actually produces. Best guess: duplicate tools in the picker, maybe ambiguous tool selection if both register something like read_file
. That's a guess, not a confirmed failure mode. So I removed the uncertainty instead of resolving it: reverted the JSON entry back to an empty mcpServers: {}
, and let the GUI screen be the only thing live.
The real risk here isn't that the JSON method is dead, which I can't claim to have proven either way. It's that if the Extensions-labeled view and the Connectors-labeled view of the same feature ever show different folder lists, not just two doors to one room but two doors that have genuinely drifted apart, nothing in the UI tells you which one is real, or that they've diverged at all. That's worth actually checking side by side rather than assuming they're in sync.
Separately, I wanted GitHub push access. Anthropic has a native GitHub Integration connector: Settings β Connectors, click, authorize, done. The obvious path.
Except as of late July 2026, there's an open, unresolved bug where that connector's OAuth grants read access fine, but every write operation fails with 403 Resource not accessible by integration
, including git push
. Confirmed, reported, still open when I checked. Flip that toggle without checking, and you get a connector that looks connected and silently fails the one thing you needed it for.
The workaround: GitHub's own official MCP server, run locally via Docker, authenticated with a fine-grained personal access token instead of Anthropic's GitHub App.
{
"mcpServers": {
"github": {
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "<fine-grained PAT>" }
}
}
}
This one genuinely belongs in mcpServers
. GitHub isn't shipped as a Claude Extension, so the old method is the correct method here, which is its own small trap: the right place to configure something depends entirely on whether Anthropic happened to ship it as an Extension, and nothing tells you that up front either.
Given how wrong "it looks configured" turned out to be for filesystem access, GitHub got three separate checks before I trusted it.
Does the token actually authenticate:
curl -s -H "Authorization: Bearer $TOKEN" https://api.github.com/user
Does it have write permission on a real repo, not just a valid token:
curl -s -H "Authorization: Bearer $TOKEN" https://api.github.com/repos/me/my-repo
I checked the permissions
object for "push": true
specifically.
Did the actual Claude Desktop process connect cleanly, not just a manual test, by tailing:
~/Library/Logs/Claude/mcp-server-github.log
Looking for readOnly=false
, lockdownEnabled=false
, and a clean Server started and connected successfully
after a real restart.
If you're running Claude Desktop and think you know what has file access right now, here's the actual answer, not the guide's answer.
Check both Desktop app β Extensions β Filesystem
and Customize β Connectors β Filesystem
, and compare what each one shows. For me, after correcting the folder list, they matched, consistent with one underlying screen filed under two labels. I haven't verified that's guaranteed across every install, so check your own rather than take my word for it. If yours show different folders on each, that's the version of this that actually bites: two settings both plausibly "the real one," disagreeing, with nothing telling you which one Claude is using.
Then check the JSON method isn't also quietly in the mix:
cat ~/Library/Application\ Support/Claude/claude_desktop_config.json
If a filesystem
key shows up under mcpServers
, that's a third thing potentially live at once. I don't know what happens when it and the GUI screen are both active, and I chose not to find out. I'd remove it rather than test it.
For anything Anthropic hasn't folded into the unified screen, a third-party MCP server without its own Extension, the JSON file is the correct, current place, since there's no GUI card for it at all.
Whether Extensions and Connectors are one data store behind two doors, two stores kept in sync, or two stores that can silently drift, I only have direct evidence for my own case, and it settled into consistent once corrected. What I can say with more confidence: nothing in the product tells you which of those it is, and that's worth checking for yourself rather than taking on faith.
Everything sorted here is local-Mac config. The bigger, still-untouched piece is a custom MCP server meant to run on a home Proxmox LXC: a small TypeScript service exposing read-only search and lint tools over the network, reached via an mcp-remote
stdio bridge rather than Anthropic's Custom Connectors, which require public internet reachability and aren't a fit for a home LAN. That's a design doc right now, zero code written. Whether that setup turns out to have two doors as well feels like a safe bet.
If you've dug into your own Claude Desktop settings and found something that didn't match what you thought was configured, I'd like to hear what it was.