Writing a Path Allowlist for the Filesystem Model Context Protocol Server
A filesystem MCP server path allowlist should name the narrowest set of directories the task requires, compare only canonical paths after symlinks and relative segments are resolved, and keep read access separate from write access. Run a server version at or above 0.6.4 / 2025.7.01, test the allowlist with hostile paths and with no configuration at all, and treat the server-side list as one layer. Runtime policy on each tool call adds enforcement and evidence that a static list cannot provide.
Test that the allowlist matches what the agent can reach
- Request a file inside each allowed directory and confirm success for the intended tools only.
- Request paths that climb out with relative segments, such as a parent-directory sequence from an allowed folder, and confirm each is refused.
- Create a symlink inside an allowed directory that points to a file outside it, then attempt to read, write and list through it.
- Request sibling directories that share a name prefix with an allowed directory, and case variants of allowed and protected paths.
- Start the server with no directories configured and with an empty value, and confirm it refuses access rather than defaulting to broad reach.
- For move and copy-style operations, test an in-scope source with an out-of-scope destination and the reverse.
Start with the threat model
The Filesystem MCP server gives an AI agent or coding assistant read and write access to local directories. The allowlist is the boundary that decides which of those directories the agent can touch. The agent's inputs are not fully trusted: a prompt, a retrieved document or a tool result can all influence which path the model requests, so the allowlist has to hold when the request is wrong or hostile.
Three failure patterns recur. The first is breadth: an allowlist that names a home directory or repository root exposes credentials, configuration and unrelated projects. The second is ambiguity: a path that looks inside the allowed area but resolves outside it through relative segments, symlinks or case differences. The third is silent misconfiguration, where a missing setting leaves nothing confining the tools.
OWASP guidance on MCP security points the same way: sanitize file paths rather than passing them through raw, allowlist filesystem roots and tool arguments, and grant the minimum tools a task needs. It also states that tool annotations are hints, not enforcement, so a read-only or destructive label on a tool is not access control.
Design the allowlist: scope, then read versus write
Write the allowlist from the task backward. For each agent workflow, list the directories it must read and the directories it must change. Anything not on that list stays out. The OWASP AI Agent Security guidance shows the target granularity with a single reports directory as the allowed path, not a broad parent such as an application root.
Then classify the file tools exposed by your server version by effect. Tools that read content, tools that list or search, tools that create or edit, and tools that move or delete carry different risk. Search and listing reveal file names and structure even when contents are not read. Move and delete can affect files outside the intended working set if either end of the operation is not confined.
Do not assume one allowlist can express different permissions for reads and writes. Where the server configuration cannot separate them, enforce the split around it:
- Separate instances: Run one server instance for read-only needs and another, with a smaller directory set, for the few locations that need writes. Expose only the tools each instance needs.
- Operating system permissions: Run the server under a dedicated account and mount read-only locations read-only, so the OS refuses writes the server would otherwise attempt.
- Isolation: Sandbox the server process and keep host credentials out of its environment, in line with OWASP guidance on isolating MCP servers.
- Package and version hygiene: Verify the package name exactly before installing, since look-alike names such as mcp-server-filesytem are a documented typosquatting risk. Keep the server at or above 0.6.4 / 2025.7.01.
Handle normalization, symlinks and traversal
A path allowlist is only as strong as the comparison behind it. The safe order is: take the requested path, resolve it to an absolute path, collapse relative segments, resolve symlinks to the real target, and only then check that the result sits inside an allowed directory. Compare on directory boundaries, not raw string prefixes, so that an allowed directory named reports does not also admit a sibling named reports-archive.
Symlinks are the best-documented gap for the Filesystem server. CVE-2025-53109 records that versions before 0.6.4 or 2025.7.01 could allow access to unintended files through symlinks within allowed directories. A link placed inside an allowed folder can point anywhere the process can read, so the check must apply to the resolved target. Where possible, keep allowed directories free of symlinks you did not create.
Case handling is a second trap. A path guard in SiYuan, another MCP implementation, used case-sensitive matching on Linux and was bypassed with case-variant paths that reached a protected file (CWE-22). The lesson is general: string-level comparison can be evaded, and the correct rules depend on the underlying filesystem.
Missing configuration is the third. In excel-mcp-server, an unset path variable in stdio mode left read and write tools unconfined, so any file accessible to the process was reachable. That is a different implementation, but it justifies a design rule: the server should fail closed when no directories are configured, and you should verify that it does.
OWASP notes that allowlist validation with canonicalization is recommended but not a complete defense. Treat it as the base layer, not the whole control.
Where server restrictions end and runtime enforcement begins
Server-level directory restrictions are a static list evaluated by the server. They answer one question: is this path inside a configured directory? They do not evaluate each tool call in context, they do not distinguish an agent's routine read from an unusual bulk read inside the same directory, and they do not by themselves produce a record that an auditor can use. A flaw in the server's path handling, as with the symlink advisory, also weakens the only control in place.
Runtime policy enforcement adds a second layer in the execution path. Each tool call is evaluated before it runs and receives a decision: allow, redact, block, or escalate for human approval. OWASP third-party MCP guidance recommends human-in-the-loop oversight and authorization controls, and escalation is where that oversight sits for operations such as writes outside a working directory.
Whatever mechanism you use, decide what each decision must record. Useful per-call fields include the calling agent or user, the tool, the requested path and its resolved path, the policy that applied, the decision, and the time. These fields are an internal design choice rather than a standard, so define them and set retention to match your own requirements.
Trussed enforces policy in the execution path across agents, tools, MCP servers and coding assistants, at the level of individual tool calls. Enforcement is at runtime, not reviewed after the fact, and each decision produces audit-ready evidence. This complements the server allowlist and does not replace it: keep the allowlist narrow, and use runtime policy to enforce and evidence what actually happens on each call.
Layers of a filesystem MCP allowlist
Directory scope
Only the paths the task needs
Read/write separation
Distinct instances and OS permissions
Path resolution
Canonical paths, symlinks, case, traversal
Verification
Hostile-path tests, including the unconfigured state
Runtime enforcement
Policy and evidence on each tool call
Add per-call enforcement to your allowlist
See how policy is enforced on individual MCP tool calls in the execution path, and how each allow, redact, block or escalate decision becomes audit-ready evidence.
Explore Agent and Tool-Call Enforcement