文件MCP服务器
用于沙盒文件访问的Stdio MCP服务器——读取文件、搜索内容、使用校验和安全编辑以及管理文件结构。
作者 过度
\[!警告\] 此服务器提供对AI代理的文件系统访问。虽然它被沙盒到特定的目录中,但始终: - 在确认更改之前,审查工具输出 - 使用dryRun=true预览破坏性操作 - 保留重要文件的备份 - 集FS_ROOTS仅访问您希望代理访问的目录
动机
传统的文件操作需要精确的路径和精确的内容——LLM很难做到这一点。此服务器的设计使AI代理可以:
- 先探索 --在采取行动之前了解目录结构
- 按名称或内容查找 --在不知道确切路径的情况下定位文件
- 安全编辑 --校验和验证可防止过时覆盖
- 预览更改 --干运行模式在应用前显示差异
- 从错误中恢复 --提示引导代理人纠正错误
结果:一个可以可靠地管理您的黑曜石保管库、文档、笔记或任何基于文本的文件集的代理。
特性
- ✅ 目录探索 --包含文件计数、大小和时间戳的树状视图
- ✅ 文件读取 --带有校验和的行号内容,用于安全编辑
- ✅ 文件和内容搜索 --文件名搜索+文字/正则表达式/模糊内容搜索
- ✅ 安全编辑 --校验和验证、模拟运行预览、统一差异
- ✅ 结构操作 --删除、重命名、移动、复制、mkdir、stat
- ✅ 多安装支架 --将多个目录作为虚拟装载点进行访问
- ✅ 沙盒化的 --无法访问已配置装载之外的路径
设计原则
- 编辑前浏览:代理必须在修改文件之前读取它(获取校验和+行号)
- 应用前预览:
dryRun=true确切地显示了会发生什么变化 - 清晰的反馈:每个响应都包含下一步和错误恢复的提示
- 默认情况下为紧凑型:文件详细信息(大小、已修改)仅在以下情况下显示
details=true - 单安装优化:当配置一个支架时,
fs_read(".")直接显示内容
______________________________________________________________________
快速开始
1.安装
cd files-mcp
bun install2.配置
创建 .env:
# Directories the agent can access (comma-separated)
FS_ROOTS=/path/to/vault,/path/to/docs
# Or for a single directory:
# FS_ROOT=/path/to/vault
# Optional
LOG_LEVEL=info
MAX_FILE_SIZE=1048576
# Force-include ignored folders (comma-separated relative paths)
# These folders will be visible even if matched by .gitignore
# FS_INCLUDE=data,build/output3.跑步
bun dev4.连接到客户端
克劳德桌面/光标:
{
"mcpServers": {
"filesystem": {
"command": "bun",
"args": ["run", "/absolute/path/to/files-mcp/src/index.ts"],
"env": {
"FS_ROOTS": "/Users/you/vault,/Users/you/docs"
}
}
}
}______________________________________________________________________
MCP束(MCPB)
此服务器也可用作 MCP捆绑包 (.mcpb)在支持的应用程序(如Claude Desktop、Alice和其他MCPB兼容应用程序)中一键安装。
什么是MCPB?
MCP捆绑包 是包含本地MCP服务器和 manifest.json 它描述了服务器及其功能。该格式使最终用户能够一键安装本地MCP服务器,无需手动配置。
从MCPB安装
- 下载
files-mcp.mcpb文件 - 使用兼容的应用程序(Claude Desktop、Alice等)打开它
- 配置 根目录 当系统提示时,这是代理可以访问的目录
- 完成!服务器已安装并准备好使用
manifest.json
清单定义了:
- 服务器配置 --命令、参数、环境变量
- 工具 —
fs_read,fs_search,fs_write,fs_manage附描述 - 用户配置 --提示
FS_ROOT安装过程中的目录
{
"manifest_version": "0.2",
"name": "files-mcp",
"version": "1.0.0",
"server": {
"type": "node",
"entry_point": "dist/index.js",
"mcp_config": {
"command": "node",
"args": ["${__dirname}/dist/index.js"],
"env": {
"FS_ROOT": "${user_config.FS_ROOT}"
}
}
},
"user_config": {
"FS_ROOT": {
"type": "directory",
"title": "Root Directory",
"description": "The directory the agent will have access to.",
"required": true
}
}
}这 ${user_config.FS_ROOT} 语法在运行时将用户选择的目录注入服务器的环境中。
______________________________________________________________________
服务器说明(模型看到的内容)
🔒 SANDBOXED FILESYSTEM — This tool can ONLY access specific mounted directories.
You CANNOT access arbitrary system paths like /Users or C:\.
Always start with fs_read(".") to see available mounts.
⚠️ ALWAYS read a file BEFORE answering questions about its content.
⚠️ ALWAYS read a file BEFORE modifying it (you need the checksum).
MANDATORY WORKFLOW:
1. fs_read(".") → see available mounts
2. fs_search(...) → locate files or content
3. fs_read("path/file.md") → get content + checksum
4. fs_write with dryRun=true → preview diff
5. fs_write with dryRun=false + checksum → apply change
6. fs_manage for structural changes (delete/rename/move/copy/mkdir)______________________________________________________________________
工具
fs_read
读取文件或列出目录。
输入:
{
path: string; // "." for root, "docs/", "notes/todo.md"
// Options
depth?: number; // Directory traversal depth (default 1)
details?: boolean; // Include size/modified (default false)
lines?: string; // "10-50" for partial read
types?: string[]; // Filter directory listing by type
glob?: string; // Glob filter for listing
exclude?: string[]; // Exclude patterns
respectIgnore?: boolean; // Honor .gitignore (default true)
}输出:
{
success: boolean;
path: string;
type: "directory" | "file";
// For directories
entries?: Array;
summary?: string;
// For files
content?: {
text: string; // With line numbers
checksum: string; // Pass to fs_write
totalLines: number;
range?: { start: number; end: number };
truncated: boolean;
};
hint: string; // Next action suggestion
}fs_search
按名称查找文件并在文件中搜索内容。
输入:
{
path: string; // "." for all mounts
query: string; // Search term
target?: "all" | "filename" | "content";
patternMode?: "literal" | "regex" | "fuzzy";
caseInsensitive?: boolean;
wholeWord?: boolean;
multiline?: boolean;
types?: string[];
glob?: string;
exclude?: string[];
depth?: number; // Default 5
maxResults?: number; // Default 100, max 1000
respectIgnore?: boolean;
}输出:
{
success: boolean;
query: string;
files: Array; // Filename matches
content?: Array; // Content matches
totalCount: number;
truncated: boolean; // True if maxResults cap was hit
error?: { code: string; message: string };
hint: string; // Actionable guidance
}fs_write
创建或更新具有安全功能的文件。
输入:
{
path: string;
operation: "create" | "update";
// For create
content?: string;
// For update — target by lines
lines?: string; // "10-15" — PREFERRED
// For update — action
action?: "replace" | "insert_before" | "insert_after" | "delete_lines";
content?: string; // New content
// Safety
checksum?: string; // From fs_read — RECOMMENDED
dryRun?: boolean; // Preview only (default false)
createDirs?: boolean; // Auto-create parent dirs (default true)
}输出:
{
status: "applied" | "preview" | "error";
path: string;
operation: "create" | "update";
result?: {
action: string; // "created", "would_create", "replaced", etc.
targetRange?: { start: number; end: number }; // For updates
newChecksum?: string; // After apply
diff?: string; // Unified diff
};
error?: {
code: string;
message: string;
recoveryHint: string; // Always present on errors
};
hint: string; // Actionable guidance
}fs_manage
结构化文件系统操作。
输入:
{
operation: "delete" | "rename" | "move" | "copy" | "mkdir" | "stat";
path: string;
target?: string; // rename/move/copy
recursive?: boolean; // mkdir/copy/move only (default false)
force?: boolean; // overwrite (default false)
}注: Delete仅适用于单个文件或空目录(为了安全起见,没有递归删除)。
**Output:**{ success: boolean; operation: string; path: string; target?: string; stat?: { size, modified, created, isDirectory }; hint: string; }
______________________________________________________________________
## 例子
### 1.探索金库
{ "path": "." }
**答复:**
18 items (15 files, 3 directories)
- Core/
- Projects/
- Books/
- map.md
- inbox.md
...
hint: "Showing contents of 'vault'. Use fs_read on any path to explore deeper."
### 2.按名称搜索文件
{ "path": ".", "query": "todo", "target": "filename" }
**答复:**
Found 3 filename match(es)
- Core/Todo.md
- Projects/Todo.md
- inbox.md
...
hint: "Found 3 filename match(es)."
### 3.读取文件
{ "path": "Core/Values.md" }
**答复:**
File read complete. Checksum: a1b2c3d4e5f6.
1| # Values 2| 3| ## Integrity 4| Be honest, even when it's hard. 5| 6| ## Growth 7| Learn something new every day. ...
hint: "To edit this file, use fs_write with checksum a1b2c3d4e5f6."
### 4.查找所有未完成的任务
{ "path": ".", "query": "- \\[ \\] ", "patternMode": "regex", "target": "content" }
**答复:**
Found 7 content match(es) in 4 file(s).
- Projects/Alice.md:12 — "- [ ] Implement search"
- Projects/Alice.md:15 — "- [ ] Add tests"
- inbox.md:3 — "- [ ] Review PR"
...
### 5.替换文本(先预览,基于行)
{ "path": "Core/Values.md", "operation": "update", "action": "replace", "lines": "3", "content": "Act with integrity", "checksum": "a1b2c3d4e5f6", "dryRun": true }
**答复:**
DRY RUN — no changes applied.
--- a/Core/Values.md +++ b/Core/Values.md @@ -3,1 +3,1 @@ -Be honest, even when it's hard. +Act with integrity, even when it's hard.
hint: "Review the diff above. Run with dryRun=false to apply."
### 6.将文件移动到存档
{ "operation": "move", "path": "Projects/Alice.md", "target": "Archive/Alice.md", "force": true }
**答复:**
Move completed successfully.
### 7.将任务标记为已完成
{ "path": "inbox.md", "operation": "update", "action": "replace", "lines": "3", "content": "- [x] Review PR", "checksum": "xyz789" }
**答复:**
replaced 1 line(s). New checksum: abc123.
hint: "The diff above shows what changed."
______________________________________________________________________
## 配置
|变量|默认值|描述|
|----------|---------|-------------|
| `FS_ROOTS` | `.` |代理可以访问的逗号分隔路径|
| `FS_ROOT` | `.` |单路径(向后兼容性)|
| `MCP_NAME` | `files-mcp` |服务器名称|
| `MCP_VERSION` | `1.0.0` |服务器版本|
| `LOG_LEVEL` | `info` |日志级别:调试、信息、警告、错误|
| `MAX_FILE_SIZE` | `1048576` |最大文件大小(以字节为单位)(1MB)|
| `FS_INCLUDE` | _(无)_ |逗号分隔的强制包含的相对路径,即使被忽略(递归)|
### 强制包含忽略的文件夹
某些文件夹可能位于 `.gitignore` 但仍然需要被代理搜索(例如,生成的数据、构建输出)。使用 `FS_INCLUDE` 将它们列入白名单:
FS_INCLUDE=docs,workspaces,data/embeddings
路径是相对于挂载根的,并且是递归的-- `data` 包括 `data/`, `data/sub/`, `data/sub/deep/`等等。这将覆盖 `.gitignore`, `.ignore`,以及所有默认忽略模式。
### 多安装设置
访问多个目录:
FS_ROOTS=/Users/me/vault,/Users/me/projects,/Users/me/notes
每个路径都会变成一个以其文件夹命名的挂载:
- `vault/` → `/Users/me/vault`
- `projects/` → `/Users/me/projects`
- `notes/` → `/Users/me/notes`
______________________________________________________________________
## 客户端配置
**克劳德桌面:**
{ "mcpServers": { "filesystem": { "command": "bun", "args": ["run", "/path/to/files-mcp/src/index.ts"], "env": { "FS_ROOTS": "/Users/me/vault" } } } }
**光标:**
{ "filesystem": { "command": "bun", "args": ["run", "/path/to/files-mcp/src/index.ts"], "env": { "FS_ROOTS": "/Users/me/vault" } } }
______________________________________________________________________
## 发展
bun dev # Start with hot reload bun test # Run tests bun run typecheck # TypeScript check bun run lint # Lint code bun run build # Production build bun run inspector # Test with MCP Inspector
______________________________________________________________________
## 建筑
src/ ├── index.ts # Entry point: stdio transport ├── config/ │ ├── env.ts # Environment config & mount parsing │ └── metadata.ts # Tool descriptions ├── core/ │ ├── capabilities.ts # Server capabilities │ └── mcp.ts # McpServer builder ├── tools/ │ ├── index.ts # Tool registration │ ├── fs-read.tool.ts # Read and explore │ ├── fs-search.tool.ts # Filename + content search │ ├── fs-write.tool.ts # Create and update │ └── fs-manage.tool.ts # Structural operations ├── lib/ │ ├── checksum.ts # SHA256 checksums │ ├── diff.ts # Unified diff generation │ ├── filetypes.ts # Text/binary detection │ ├── ignore.ts # .gitignore support │ ├── lines.ts # Line manipulation │ ├── paths.ts # Multi-mount path resolution │ └── patterns.ts # Pattern matching utilities └── utils/ ├── errors.ts # Error utilities └── logger.ts # Logging
______________________________________________________________________
## 故障排除
|问题|解决方案|
|-------|----------|
|“沙盒文件系统:不允许绝对路径”|在挂载中使用相对路径。从开始 `fs_read(".")` 查看可用的支架。 |
|“路径与任何装载都不匹配”|检查 `FS_ROOTS` 设置正确。路径必须以装载名称开头(例如。, `vault/notes.md`). |
|“CHECKSUM_MISCMATCH”|文件在您读取后已更改。请使用重新读取 `fs_read` 获取新鲜内容。 |
|“DIRECTORY_NOT_EMPTY”| Delete仅适用于空目录。对于移动/复制,请使用 `recursive=true`. |
|“ALREADY_EXISTS”|目标已存在。使用 `force=true` 在支持的地方。 |
|二进制文件错误|只能读取/写入文本文件。检查文件扩展名。 |
|单次挂载仍显示“docs”|更改后重新启动MCP服务器 `FS_ROOTS`. |
______________________________________________________________________
## 许可证
麻省理工学院