A safe, root-scoped filesystem MCP server (FastMCP / MCP 2.0).
Project description
MCP: filesystem
A safe, root-scoped filesystem MCP.
Security model
- The server is started with one or more allowed root directories.
- Tools require absolute paths.
- All paths are resolved (including symlinks) and must be under one of the allowed roots.
- If no roots are provided, the server exits (no implicit default like
cwd).
Run (STDIO)
# Console script
better-mcps-filesystem /absolute/allowed/root1 /absolute/allowed/root2
# Module entrypoint
python -m better_mcps_filesystem /absolute/allowed/root1 /absolute/allowed/root2
Claude Desktop example
{
"mcpServers": {
"filesystem": {
"command": "better-mcps-filesystem",
"args": [
"/absolute/allowed/root1",
"/absolute/allowed/root2"
]
}
}
}
Docker example
When running this MCP in Docker, the server can only access paths inside the container. So you must mount any directories you want this MCP to be able to access (read/list today; edit/write if you add write tools later).
Build
From the filesystem/ directory:
docker build -t better-mcps-filesystem:latest .
Run
Mount the host directories into the container and pass the container paths as allowed roots.
docker run --rm -i \
-v "/Users/erdelyia/Projects/project:/roots/project:rw" \
-v "/Users/erdelyia/Projects/project2:/roots/project2:rw" \
better-mcps-filesystem:latest \
/roots/project /roots/project2
Notes:
-ikeeps STDIN open (needed for MCP over stdio).- Use
:rwif you expect the MCP to modify files; use:roto force read-only.
VS Code example
VS Code supports variable substitution for the current workspace folder (your workdir). You can use that as the allowed root so the MCP is automatically scoped to the open workspace.
Example (conceptually):
{
"mcpServers": {
"filesystem": {
"command": "better-mcps-filesystem",
"args": ["${workspaceFolder}"]
}
}
}
If you use a multi-root workspace, VS Code can target a specific folder (e.g. ${workspaceFolder:my-folder}).
API
Tools
-
list_dir(params: object) -> str | dict- Params object (Pydantic-validated):
path(string, required): absolute directory path under an allowed rootmax(int, default200, max2000)format("text"|"json", default"text")detailed(bool, defaultfalse): includemode(permissions) andsize
- Includes hidden files; sorted by name
- If output is truncated, a hint is included (text mode appends a line; json mode includes
truncated/total/shown)
- Params object (Pydantic-validated):
-
read_text_file(params: object) -> str- Params object:
path(string, required): absolute file path under an allowed root
- file is read as UTF-8
- Params object:
Resources
resource://roots— returnslist[str]of allowed root directories
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file better_mcps_filesystem-0.3.0.tar.gz.
File metadata
- Download URL: better_mcps_filesystem-0.3.0.tar.gz
- Upload date:
- Size: 99.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81a56ddbf24183458605d7f023f590a2a394b10511c1f97a56be8cb114ae2e46
|
|
| MD5 |
f943d7450ec26b140c81280aa960b641
|
|
| BLAKE2b-256 |
8c9e5cc77f7e2bdb010d52fb3fa5670d29f2c66c83ce5d771ff74b732e76ef7e
|
File details
Details for the file better_mcps_filesystem-0.3.0-py3-none-any.whl.
File metadata
- Download URL: better_mcps_filesystem-0.3.0-py3-none-any.whl
- Upload date:
- Size: 5.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af4cd5b64f98717eb25a28a5aee0ce1f2a8196bf6e07e2bbb6bd663a18c69b69
|
|
| MD5 |
c62ef1e5520c2ca95c1fbf92cd4d3026
|
|
| BLAKE2b-256 |
fc2039ea16ac073342ed894f2696bc343b88f232791e36f12c7c83c8a54b56b5
|