[BUG] Claude Desktop crashes on opening with various MCP Errors after renaming an allowed directory
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?
Summary
When I closed and re-opened the Claude Desktop app, it crashed with several MCP Errors. It was however working all morning.
In the Developer section, under Local MCP Servers and Filesystem, it had a red error.
Using Claude Code, I discovered the reason - a folder that was set as as one of the allowed_directories, no longer existed.
The secure-filesystem-server package (src/filesystem/) terminates the Node process during startup if any path passed in allowed_directories is missing or inaccessible. The exit produces no stderr output, no JSON-RPC error response, and no log line indicating which path was the culprit — only the host (Claude Desktop, in my case) sees an abrupt transport close.
This is a sharp edge for end users: any folder rename, drive disconnect, or stale config entry takes the entire connector offline with no diagnostic to act on.
Environment
- Host: Claude Desktop (Windows UWP, but the bug is in the server itself and is host-agnostic)
- OS: Windows 10
- Filesystem connector extension ID:
ant.dir.ant.anthropic.filesystem - MCP server build: ships with current Claude Desktop (Node-based,
secure-filesystem-serverv0.2.0, per server log line"serverInfo":{"name":"secure-filesystem-server","version":"0.2.0"})
<img width="684" height="316" alt="Image" src="https://github.com/user-attachments/assets/4ce4dc9f-8e40-4d4a-ac92-1d439e4fed47" />
What Should Happen?
Expected behaviour
One of:
- Preferred: the server starts successfully using the valid subset of
allowed_directories, emits a structured warning (stderr or JSON-RPCnotifications/message) naming each invalid path, and continues serving requests scoped to the surviving paths. - Acceptable: the server fails fast but writes a clear stderr line identifying the offending path, e.g.
Allowed directory does not exist: C:\DevBackup — startup aborted, and exits with a non-zero code that the host can surface.
Either makes the failure actionable.
Actual behaviour
The server exits with no stderr output and no JSON-RPC error. From the host's perspective the connector simply disappears mid-handshake.
Verbatim from %APPDATA%\Claude\logs\mcp-server-Filesystem.log (timestamps trimmed):
[Filesystem] [info] Initializing server...
[Filesystem] [info] Using built-in Node.js for MCP server: Filesystem
[Filesystem] [info] Server started and connected successfully
[Filesystem] [info] Message from client: {"method":"initialize", ... "id":0}
[Filesystem] [info] Server transport closed
[Filesystem] [info] Server transport closed unexpectedly, this is likely due to the process exiting early.
If you are developing this MCP server you can add output to stderr ... and it will appear in this log.
[Filesystem] [error] Server disconnected.
The host UI surfaces three opaque toasts: "MCP Filesystem: Server disconnected", "This isn't working right now", "Could not attach to MCP server Filesystem". None mention which path is bad, which makes the issue hard to diagnose without reading server source.
Suspected root cause
During startup the server resolves every entry in allowed_directories via something equivalent to fs.realpathSync(path) to canonicalise it for later path-prefix checks. When a path is missing this throws ENOENT. The throw is not caught at the validation site, so it propagates to top-level and Node terminates with no handler logging it.
Suggested fix
Wrap per-path validation in try/catch and partition the input into "valid" and "invalid" buckets. Pseudocode:
const valid: string[] = [];
const invalid: { path: string; reason: string }[] = [];
for (const raw of allowedDirectories) {
try {
const resolved = fs.realpathSync(raw);
const stat = fs.statSync(resolved);
if (!stat.isDirectory()) {
invalid.push({ path: raw, reason: 'not a directory' });
continue;
}
valid.push(resolved);
} catch (err: any) {
invalid.push({ path: raw, reason: err?.code ?? err?.message ?? 'unknown' });
}
}
for (const { path, reason } of invalid) {
console.error(`[filesystem] Skipping allowed directory "${path}": ${reason}`);
}
if (valid.length === 0) {
console.error('[filesystem] No valid allowed directories — aborting.');
process.exit(1);
}
// continue startup with `valid`
This:
- Names every bad path on stderr, which the host displays in its server log.
- Keeps the connector alive for the valid subset (matches user intent in the common case where only one of several drives is offline).
- Aborts cleanly with a clear message if every path is bad.
An optional follow-up would be to emit a notifications/message MCP event after initialize so the host can render an inline warning in its UI, but the stderr line alone already unlocks 95% of the diagnostic value.
Impact
This silent-failure mode wastes substantial debugging time. In my case I'd renamed a folder hours earlier and forgotten it was in the connector list; the toasts gave no indication that a path was the problem, so I spent ~30 minutes reading mcp.log, main.log, and the Filesystem server log before finally diffing the allowed_directories JSON against the actual filesystem.
I've also filed a corresponding feedback note with Anthropic about the Claude Desktop side of the UX (better host-side dialog when a connector fails). This issue covers only the upstream server-side change.
Additional notes
- The same code path may affect other Node-based MCP servers in this repo that take a directory list as a startup argument — worth checking, though I haven't reproduced there.
Error Messages/Logs
## Error Messages
Top notification (yellow):
⚠ MCP Filesystem: Server disconnected. For troubleshooting guidance, please visit our debugging documentation
[Open developer settings]
Middle notification (yellow):
⚠ This isn't working right now. You can try again later.
Bottom notification (yellow):
⚠ Could not attach to MCP server Filesystem
Steps to Reproduce
Reproduction
- Configure the filesystem MCP server with an
allowed_directorieslist that contains at least one path which does not exist on disk. For example:
``json`
{
"allowed_directories": [
"C:\\PKM",
"C:\\Dev",
"C:\\DevBackup"
]
}
C:\PKM
where and C:\Dev and C:\DevBackup exist.
- Start Claude Desktop - it runs fine. Now exit the app and rename
C:\DevBackupto C:\Dev-Old` after.
- Launch Claude Desktop again so the MCP server is spawned.
- Observe that the server starts, accepts the
initializehandshake, and then exits within 1–2 seconds. Notools/listis ever served.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
Claude 1.7196.0 (2dbd78)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Windows Terminal
Additional Information
Suggestion
- It would have been nice if the app gave a valid reason why it could not start instead of just crashing with an MCP error.
- Offered to remove the faulty folder from the list
- Allowed me to continue anyway, so I could remove or rename the folder myself
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗