Hi — thanks for maintaining the filesystem server.
I'm filing this against @modelcontextprotocol/server-filesystem after several weeks of production use on macOS with provider-backed directories in allowedDirectories,
especially:
~/Library/CloudStorage/GoogleDrive-.../...
~/Library/Mobile Documents/com~apple~CloudDocs/...
Symptom
When allowedDirectories includes macOS CloudStorage / lazy provider paths, search_files and other operations that call validatePath() can intermittently hang for minutes.
Claude Desktop eventually reports the MCP server as unresponsive after roughly 4 minutes. The subprocess remains alive, but subsequent filesystem calls may continue to hang until
the server is restarted.
This may overlap with reports like #3281, but I'm filing separately because this issue points to specific filesystem code paths.
Code paths
In src/filesystem/lib.ts, validatePath() calls:
const realPath = await fs.realpath(absolute);
and, in the ENOENT branch:
const realParentPath = await fs.realpath(parentDir);
These calls have no timeout. On macOS provider-backed paths that are not locally materialized, realpath can block while the provider fetches metadata.
searchFilesWithValidation() then recursively does:
const entries = await fs.readdir(currentPath, { withFileTypes: true });
...
await validatePath(fullPath);
...
if (entry.isDirectory()) {
await search(fullPath);
}
As far as I can tell, recursive search currently has no upper bound on visited entries, no timeout around readdir, and no abort path. A large or lazy-materialized tree can
therefore keep the server busy for a long time.
Why this matters
This is especially visible with CloudStorage / FileProvider-backed folders such as Google Drive and iCloud Drive, where metadata for subdirectories may be fetched lazily. It can
also affect very large local trees.
The libuv threadpool angle may make the symptom worse: filesystem operations use libuv's threadpool, whose default size is 4. A small number of slow filesystem calls can
therefore degrade unrelated filesystem operations in the same process. I mention this as a contributing factor, not necessarily as the main fix.
Suggested mitigations
The two minimal mitigations I'd suggest are:
-
Add a timeout wrapper around fs.realpath in validatePath() and around fs.readdir in recursive search.
-
Add a configurable maximum visited-entry count for search_files, returning a clear error such as:
Search aborted after visiting N entries. Please refine the pattern or narrow the search path.
Optional follow-ups:
- Document how to exclude / avoid recursive search over CloudStorage-style folders.
- Consider an opt-in exclude-prefix configuration for recursive search.
- Document
UV_THREADPOOL_SIZE tuning for users who intentionally expose large / slow provider-backed trees.
I have tested equivalent mitigations locally in a patched installed build for several weeks with Google Drive and iCloud Drive paths in allowedDirectories. I'm not opening a PR
because the exact configuration surface — env vars vs config object, defaults, and docs placement — seems like a maintainer policy decision, but I'd be happy to test any
proposed fix.
Hi — thanks for maintaining the filesystem server.
I'm filing this against
@modelcontextprotocol/server-filesystemafter several weeks of production use on macOS with provider-backed directories inallowedDirectories,especially:
~/Library/CloudStorage/GoogleDrive-.../...~/Library/Mobile Documents/com~apple~CloudDocs/...Symptom
When
allowedDirectoriesincludes macOS CloudStorage / lazy provider paths,search_filesand other operations that callvalidatePath()can intermittently hang for minutes.Claude Desktop eventually reports the MCP server as unresponsive after roughly 4 minutes. The subprocess remains alive, but subsequent filesystem calls may continue to hang until
the server is restarted.
This may overlap with reports like #3281, but I'm filing separately because this issue points to specific filesystem code paths.
Code paths
In
src/filesystem/lib.ts,validatePath()calls:and, in the ENOENT branch:
These calls have no timeout. On macOS provider-backed paths that are not locally materialized,
realpathcan block while the provider fetches metadata.searchFilesWithValidation()then recursively does:As far as I can tell, recursive search currently has no upper bound on visited entries, no timeout around
readdir, and no abort path. A large or lazy-materialized tree cantherefore keep the server busy for a long time.
Why this matters
This is especially visible with CloudStorage / FileProvider-backed folders such as Google Drive and iCloud Drive, where metadata for subdirectories may be fetched lazily. It can
also affect very large local trees.
The libuv threadpool angle may make the symptom worse: filesystem operations use libuv's threadpool, whose default size is 4. A small number of slow filesystem calls can
therefore degrade unrelated filesystem operations in the same process. I mention this as a contributing factor, not necessarily as the main fix.
Suggested mitigations
The two minimal mitigations I'd suggest are:
Add a timeout wrapper around
fs.realpathinvalidatePath()and aroundfs.readdirin recursive search.Add a configurable maximum visited-entry count for
search_files, returning a clear error such as:Optional follow-ups:
UV_THREADPOOL_SIZEtuning for users who intentionally expose large / slow provider-backed trees.I have tested equivalent mitigations locally in a patched installed build for several weeks with Google Drive and iCloud Drive paths in
allowedDirectories. I'm not opening a PRbecause the exact configuration surface — env vars vs config object, defaults, and docs placement — seems like a maintainer policy decision, but I'd be happy to test any
proposed fix.