-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Description
Description
When running server-filesystem on macOS with /tmp specified as an allowed directory, file operations using /tmp/... paths are incorrectly rejected as being outside allowed directories.
Root Cause
On macOS, /tmp is a symlink to /private/tmp:
$ ls -la /tmp
lrwxr-xr-x@ 1 root wheel 11 Nov 30 2024 /tmp -> private/tmp
The server appears to resolve paths to their canonical (real) form before checking against allowed directories. When a user specifies /tmp as allowed and passes /tmp/foo.txt, the server resolves it to /private/tmp/foo.txt, which doesn't match the allowed path /tmp.
Reproduction Steps
-
Start server-filesystem with
/tmpas allowed directory:npx -y @modelcontextprotocol/server-filesystem /tmp
-
Call
read_filewith a path under/tmp:{"path": "/tmp/test.txt"} -
Observe rejection error indicating path is outside allowed directories
Expected Behavior
Either:
- The server should resolve allowed directories to their canonical paths during initialization, OR
- The server should compare paths consistently (both resolved or both as-specified)
When /tmp is specified as allowed, files under /tmp/... should be accessible.
Actual Behavior
Files under /tmp/ are rejected as being outside allowed directories because the path resolves to /private/tmp/... internally.
Environment
- macOS (any version with /tmp -> /private/tmp symlink)
- @modelcontextprotocol/server-filesystem (current npm version)
Suggested Fix
In the path validation logic, resolve allowed directories to their canonical paths at initialization time using fs.realpathSync(), so that /tmp becomes /private/tmp in the allow list. This ensures consistent comparison with resolved request paths.
Discovery
This bug was discovered using Bellwether, a structural drift detection and behavioral testing tool for MCP servers. Bellwether automatically explores MCP server capabilities and identifies edge cases through systematic testing.