Skip to content

filesystem: Incorrect Path resolution causes "Error: Access denied - path outside allowed directories" #2526

@stefanpolenz-neurawork

Description

@stefanpolenz-neurawork

Describe the bug
Since my last update of the Fileserver MCP I see basically every first call to the MCP fail with "Error: Access denied - path outside allowed directories". Which is really annoying because it means many tool calls instead of the first one succeeding.

To Reproduce
Steps to reproduce the behavior:

  1. configure the fileserver MCP with one path that doesn't include the execution dir of the server (or c:\windows\system32 apparently)
  2. Have Claude try to open a relative path directly in his root path, e.g.
    {
    path: make-automation-audit-20250807/message.log
    }
  3. see Error instead of success
    Error: Access denied - path outside allowed directories: C:\Windows\system32\make-automation-audit-20250807\message.log not in C:\Users\Stefan Polenz\Documents\claude

Expected behavior
Until recently giving the current project dir to Claude would allow it to open it right away.

Logs
from mcp-server-Filesystem.log
2025-08-11T17:57:20.223Z [Filesystem] [info] Message from server: {"result":{"content":[{"type":"text","text":"Error: Access denied - path outside allowed directories: C:\Windows\system32\make-automation-audit-20250807\message.log not in C:\Users\Stefan Polenz\Documents\claude"}],"isError":true},"jsonrpc":"2.0","id":15} { metadata: undefined }

Additional context
Working with Claude on the issue we are fairly confident that the issue is that in
servers\src\filesystem\index.ts
in lines 77+, so

// Security utilities

sync function validatePath(requestedPath: string): Promise {
const expandedPath = expandHome(requestedPath);
const absolute = path.isAbsolute(expandedPath)
? path.resolve(expandedPath)
: path.resolve(process.cwd(), expandedPath);
causes issues as the current working dir at the time of calling the functions isn't in any of the permitted paths.

A possible solution (that I can't test as I can't seem to see building information):
sync function validatePath(requestedPath: string): Promise {
const expandedPath = expandHome(requestedPath);
const absolute = path.isAbsolute(expandedPath)
? path.resolve(expandedPath)
: (() => {
// Try to resolve relative path against all allowed directories
for (const allowedDir of allowedDirectories) {
const candidate = path.resolve(allowedDir, expandedPath);
// Check if the resulting path lies within an allowed directory
if (allowedDirectories.some(dir => candidate.startsWith(dir))) {
return candidate;
}
}
// Fallback: use first allowed directory as base
return path.resolve(allowedDirectories[0], expandedPath);
})();

I could try to push this change - but seeing as I can't test currently I think this bug ticket might be a better option.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions