modelcontextprotocol / modelcontextprotocol/servers

Filesystem server: Restrict access: Configure a base directory and allowed directories inside that.

Open
#3,133 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
TypeScript
Stars
90.5k
Forks
11.7k
Avg merge
2d 2h
Merged PRs (30d)
5

Description

Is your feature request related to a problem? Please describe.
I want to host a public filesystem MCP via HTTPS, by installing it into a docker container, together with other stuff that users won't be interested in. I'd like a way to specify which directories users can see and access.

docs/docs/learn/client-concepts.mdx says that roots are mere hints:

Roots work best when […] users understand their advisory nature, and the goal is preventing accidents rather than stopping malicious behavior.

In my case it wouldn't even necessarily be malicious, but when users would want to see "all files on that MCP" they'd probably give / as the root, and would be confused to see the entire docker container. Also their AI might be confused about the vast amount of unexpected boring files. They'd have expected to only see the directories with my actual intended content, which would be /pubfiles/ in my docker container.

src/filesystem/README.md says about "Roots Protocol Handling":

Server replaces ALL allowed directories with client's roots

Note it says "allowed". That sounds like a mixup of the concepts of a client's declaration of intent about what to use, vs. a server operator's intent about what to share. In a similar manner, the

Note: The server will only allow operations within directories specified either via args or via Roots.

lacks explanation why something that the server operator can decide (command arguments) should be handled equivalent to something that arbitrary users can send (roots).

Describe the solution you'd like

  • Server operators can configure a base directory that will become the top level for all roots, i.e. it would be file:/// in the root URLs namespace.
  • Inside that, server operators can configure "allowed" directories, and only those (and their parent directories) will be visible and accessible.
    • In the trivial case, this is a single entry / for the top level.
    • Default is still the empty list = no access at all, to avoid accidents when people comment-out the last entry in their config.
    • The idea behind this feature is so I can easily expose the photos, books, and videos subdirectories of my /pubfiles, but not confuse users' AI with all the stuff in /pubfiles/.git and /pubfiles/.cache.
  • When a client has no roots support, assume it wants to see everything, i.e. act as if it had specified a single root with URI file:///
  • When roots are received, track them as "intended" directories, i.e. a voluntary additional restriction of the "allowed" directories. Any roots outside of the "allowed" directories is simply ignored, pretending the directory doesn't exist.
  • There should be an option about which kinds of symlinks to accept along the way: none = none (default), same-owner = symlink must be owned by the same user and group as its target, trust-all = yolo. For unacceptable symlinks, pretend they don't exist. (Not sure if that should be its own feature request issue.)

Describe alternatives you've considered

Additional context
I'm hosting the server publicly because parts of my audience won't be able to install their own MCP-related software. We have a web-based AI chat assistant for them, so my hope is that with a few screenshots of how to navigate the config, they can find the "MCP URL" field, paste my URL there, and it just works for them.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/filesystem/README.md, especially the “Roots Protocol Handling” section, and review the referenced docs/docs/learn/client-concepts.mdx explanation of roots. Map the requested base directory, allowed-directory, client-roots, and no-roots cases before locating the filesystem server entry points. Done should cover the listed access scenarios; symlink policy remains an explicitly unresolved part of the request.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.