MCP filesystem server on Windows: "Access denied" when path casing differs from allowed directory
Using the @modelcontextprotocol/server-filesystem MCP server (local build, issue opened 2025-01-04) on Windows,
read_filereturns "Access denied - path outside allowed directories: C:\source\servers\src\fetch\README.md not in c:\source, C:\Users\mgoodner" even though the file is inside an allowed directory. The configured allowed directory uses a lowercase drive letter while the request uses an uppercase one. How is this resolved?Originally asked on GitHub: https://github.com/modelcontextprotocol/servers/issues/470
3 answers
Status: open. No release with a fix is mentioned in the thread, but a maintainer retested current main (post-#4638/#4631) on Windows 11 and the drive-letter part of the report is fixed there:
normalizePathnow upper-cases the drive letter, and startup keeps both the as-typed spelling and thefs.realpathresult of each allowed directory. A configuredc:\...\casetestnow matches requests such asC:\...\CaseTest\Sub\File.txtandc:\...\casetest\sub\file.txt.What still fails is narrower: a request whose non-drive segments are spelled in a case matching neither the configured nor the on-disk spelling (for example
C:\...\CASETEST\SUB\FILE.TXT) is still rejected, becauseisPathWithinAllowedDirectoriescompares with an exactstartsWithbefore the path is resolved. The maintainer notes clients normally echo a path they were given or obtained fromlist_directory, so in practice this is an edge case.A blanket case-insensitive prefix compare on
win32is not a good fix: NTFS directories can be marked case-sensitive, and a folded check could admit a sibling. The suggested fix shape is a per-segment filesystem check, similar to the existingresolveUnicodeEquivalentPath. Closed PRs #4509 and #4683 predate the v2 refactor and remain readable as prototypes; PR #2111 is described as a step toward a fix.General advice for now: configure allowed directories with the spelling you will actually use. If you build your own client, resolve the real path (
fs.realpath.native) before the containment check — a literal prefix check can also miss symlink/junction escapes.Did this work for you?What a GitHub user tried on GitHub (Didn't work)
Reported running
read_filefrom a local build of the filesystem server on Windows with allowed directoryc:\sourceand requested pathC:\source\servers\src\fetch\README.md; got 'Access denied - path outside allowed directories' with no log errors.Source: https://github.com/modelcontextprotocol/servers/issues/470 (opens external site)
Did this work for you?What @olaservo tried on GitHub (Partly worked)
Maintainer retested current main on Windows 11: configured
c:\...\casetestand requestedC:\...\CaseTest\Sub\File.txt(and lowercase variants, including new files) now pass after drive-letter normalization; a request likeC:\...\CASETEST\SUB\FILE.TXTis still rejected.Did this work for you?
Related questions
- mcp-server-fetch: 'AnyUrl' object has no attribute 'decode' error
- Does the official MCP Postgres example validate SQL before executing it?
- How to fix UTF-8 Japanese text corruption/crash in mcp-server-sqlite with Claude Desktop on Windows?
- MCP Knowledge Graph Memory Server fails with ${workspaceFolder} in MEMORY_FILE_PATH
- npx @modelcontextprotocol/server-filesystem: ERR_MODULE_NOT_FOUND for zod-to-json-schema