🚀 Files MCP Server
Stdio MCP服務器,用於沙盒化文件訪問 — 可瀏覽目錄、讀取文件、搜索內容,並通過校驗和驗證安全地編輯文件。
作者:overment
⚠️ 重要提示
此服務器為AI代理提供文件系統訪問權限。儘管它被沙盒化到特定目錄,但請始終:
- 在確認更改之前,仔細審查工具輸出
- 使用
dryRun=true 預覽破壞性操作
- 對重要文件進行備份
- 將
FS_ROOTS 設置為僅允許代理訪問的目錄
🚀 快速開始
1. 安裝
cd files-mcp
bun install
2. 配置
創建 .env 文件:
# 代理可以訪問的目錄,用逗號分隔
FS_ROOTS=/path/to/vault,/path/to/docs
# 或者只指定單個目錄
# FS_ROOT=/path/to/vault
# 可選配置
LOG_LEVEL=info
MAX_FILE_SIZE=1048576
3. 運行
bun dev
4. 連接到客戶端
Claude Desktop / Cursor:
{
"mcpServers": {
"filesystem": {
"command": "bun",
"args": ["run", "/absolute/path/to/files-mcp/src/index.ts"],
"env": {
"FS_ROOTS": "/Users/you/vault,/Users/you/docs"
}
}
}
}
✨ 主要特性
- ✅ 目錄瀏覽 — 以樹狀視圖顯示文件數量、大小和時間戳
- ✅ 文件讀取 — 帶行號的文件內容,並提供校驗和以確保安全編輯
- ✅ 文件查找 — 按文件名模式(
*.md、config.json)進行遞歸搜索
- ✅ 內容搜索 — 支持字面量、正則表達式、模糊模式匹配,可選擇忽略大小寫
- ✅ 預設模式 — 內置Obsidian模式(維基鏈接、標籤、任務、標題)
- ✅ 安全編輯 — 校驗和驗證、預運行預覽、統一差異顯示
- ✅ 批量操作 — 支持
replaceAll 對文件進行批量重命名
- ✅ 多掛載支持 — 可將多個目錄作為虛擬掛載點進行訪問
- ✅ 沙盒化 — 無法訪問配置掛載點之外的路徑
設計原則
- 先瀏覽再編輯:代理在修改文件之前必須先讀取文件(獲取校驗和和行號)
- 先預覽再應用:
dryRun=true 可精確顯示即將發生的更改
- 清晰反饋:每個響應都包含下一步操作提示和錯誤恢復建議
- 默認精簡顯示:僅當
details=true 時才顯示文件詳細信息(大小、修改時間)
- 單掛載優化:當只配置一個掛載點時,
fs_read(".") 直接顯示內容
📚 詳細文檔
動機
傳統的文件操作需要精確的路徑和確切的內容,而大語言模型(LLMs)在這方面存在困難。此服務器旨在讓AI代理能夠:
- 先探索 — 在執行操作之前瞭解目錄結構
- 按名稱或內容查找 — 無需知道確切路徑即可定位文件
- 安全編輯 — 校驗和驗證可防止過時的覆蓋操作
- 預覽更改 — 預運行模式可在應用更改之前顯示差異
- 從錯誤中恢復 — 提示信息可引導代理糾正錯誤
結果是,代理可以可靠地管理你的Obsidian庫、文檔、筆記或任何基於文本的文件集合。
MCP Bundle (MCPB)
此服務器也可以作為 MCP Bundle (.mcpb) 使用,可在Claude Desktop、Alice和其他支持MCPB的應用程序中一鍵安裝。
什麼是MCPB?
MCP Bundles 是一種zip存檔,包含本地MCP服務器和描述服務器及其功能的 manifest.json 文件。這種格式使最終用戶可以一鍵安裝本地MCP服務器,無需手動配置。
從MCPB安裝
- 下載
files-mcp.mcpb 文件
- 使用兼容的應用程序(Claude Desktop、Alice等)打開它
- 在提示時配置 根目錄 — 這是代理可以訪問的目錄
- 完成!服務器已安裝並可以使用
manifest.json
該清單定義了:
- 服務器配置 — 命令、參數、環境變量
- 工具 —
fs_read 和 fs_write 及其描述
- 用戶配置 — 在安裝過程中提示用戶配置
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} 語法會在運行時將用戶選擇的目錄注入到服務器的環境中。
服務器說明(模型可見內容)
🔒 沙盒化文件系統 — 此工具只能訪問特定的掛載目錄。
您不能訪問任意系統路徑,如 /Users 或 C:\。
始終先使用 fs_read(".") 查看可用的掛載點。
⚠️ 在回答有關文件內容的問題之前,務必先讀取文件。
⚠️ 在修改文件之前,務必先讀取文件(您需要校驗和)。
強制工作流程:
1. fs_read(".") → 查看可用的掛載點
2. fs_read("path/file.md") → 獲取內容和校驗和
3. 使用 dryRun=true 調用 fs_write → 預覽差異
4. 使用 dryRun=false 和校驗和調用 fs_write → 應用更改
5. 驗證響應中的差異是否符合您的預期
工具
fs_read
瀏覽目錄、讀取文件、按名稱查找文件或搜索內容。
輸入:
{
path: string;
find?: string;
pattern?: string;
patternMode?: "literal" | "regex" | "fuzzy";
caseInsensitive?: boolean;
preset?: "wikilinks" | "tags" | "tasks" | "tasks_open" | "tasks_done"
| "headings" | "codeblocks" | "frontmatter";
depth?: number;
details?: boolean;
lines?: string;
context?: number;
maxFiles?: number;
maxMatches?: number;
}
輸出:
{
success: boolean;
path: string;
type: "directory" | "file" | "search";
tree?: {
entries: Array<{ path, kind, children?, size?, modified? }>;
summary: string;
};
content?: {
text: string;
checksum: string;
totalLines: number;
};
matches?: Array<{ file, line, column, text, context }>;
matchCount?: number;
hint: string;
}
fs_write
創建、修改或刪除文件,並具備安全特性。
輸入:
{
path: string;
operation: "create" | "update" | "delete";
content?: string;
lines?: string;
pattern?: string;
patternMode?: "literal" | "regex" | "fuzzy";
caseInsensitive?: boolean;
action?: "replace" | "insert_before" | "insert_after" | "delete_lines";
content?: string;
replaceAll?: boolean;
checksum?: string;
dryRun?: boolean;
}
輸出:
{
success: boolean;
path: string;
operation: "create" | "update" | "delete";
applied: boolean;
result?: {
action: string;
linesAffected?: number;
newChecksum?: string;
diff?: string;
};
error?: {
code: string;
message: string;
recoveryHint?: string;
};
hint: string;
}
預設模式(Obsidian/Markdown)
內置用於常見搜索的模式:
| 預設模式 |
查找內容 |
wikilinks |
[[Note]] 和 [[Note|Display]] |
tags |
#tag 和 #nested/tag |
tasks |
- [ ] 和 - [x](所有任務) |
tasks_open |
- [ ](未完成任務) |
tasks_done |
- [x](已完成任務) |
headings |
# 到 ###### 標題 |
codeblocks |
``` 代碼塊 |
frontmatter |
YAML --- 塊 |
示例:
{ "path": ".", "preset": "tasks_open" }
示例
1. 瀏覽庫
{ "path": "." }
響應:
18 項(15 個文件,3 個目錄)
- Core/
- Projects/
- Books/
- map.md
- inbox.md
...
提示:"顯示 'vault' 的內容。對任何路徑使用 fs_read 以深入探索。"
2. 查找文件
{ "path": ".", "find": "*.md" }
響應:
找到 42 個匹配 "*.md" 的項
- Core/Values.md
- Core/Process.md
- Projects/Alice.md
...
提示:"找到 42 個匹配的文件。對特定路徑使用 fs_read 以查看其內容。"
3. 讀取文件
{ "path": "Core/Values.md" }
響應:
文件讀取完成。校驗和:a1b2c3d4e5f6。
1| # Values
2|
3| ## Integrity
4| Be honest, even when it's hard.
5|
6| ## Growth
7| Learn something new every day.
...
提示:"要編輯此文件,請使用帶校驗和 a1b2c3d4e5f6 的 fs_write。"
4. 查找所有未完成任務
{ "path": ".", "preset": "tasks_open" }
響應:
在所有掛載點的 42 個文件中找到 7 個匹配項。
- Projects/Alice.md:12 — "- [ ] Implement search"
- Projects/Alice.md:15 — "- [ ] Add tests"
- inbox.md:3 — "- [ ] Review PR"
...
5. 替換文本(先預覽)
{
"path": "Core/Values.md",
"operation": "update",
"pattern": "Be honest",
"action": "replace",
"content": "Act with integrity",
"checksum": "a1b2c3d4e5f6",
"dryRun": true
}
響應:
預運行 — 未應用任何更改。
--- 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.
提示:"查看上述差異。使用 dryRun=false 運行以應用更改。"
6. 批量重命名維基鏈接
{
"path": "Projects/Alice.md",
"operation": "update",
"pattern": "[[Old Name]]",
"action": "replace",
"content": "[[New Name]]",
"replaceAll": true,
"dryRun": true
}
響應:
預運行 — 將在第 5、12、28 行替換 3 處。
7. 將任務標記為已完成
{
"path": "inbox.md",
"operation": "update",
"pattern": "- [ ] Review PR",
"action": "replace",
"content": "- [x] Review PR",
"checksum": "xyz789"
}
響應:
替換了 1 行。新校驗和:abc123。
提示:"上述差異顯示了更改內容。"
配置
| 變量 |
默認值 |
描述 |
FS_ROOTS |
. |
代理可以訪問的目錄,用逗號分隔 |
FS_ROOT |
. |
單個路徑(向後兼容) |
MCP_NAME |
files-mcp |
服務器名稱 |
MCP_VERSION |
1.0.0 |
服務器版本 |
LOG_LEVEL |
info |
日誌級別:debug、info、warning、error |
MAX_FILE_SIZE |
1048576 |
最大文件大小(字節)(1MB) |
多掛載設置
訪問多個目錄:
FS_ROOTS=/Users/me/vault,/Users/me/projects,/Users/me/notes
每個路徑將成為一個以文件夾名稱命名的掛載點:
vault/ → /Users/me/vault
projects/ → /Users/me/projects
notes/ → /Users/me/notes
客戶端配置
Claude Desktop
{
"mcpServers": {
"filesystem": {
"command": "bun",
"args": ["run", "/path/to/files-mcp/src/index.ts"],
"env": {
"FS_ROOTS": "/Users/me/vault"
}
}
}
}
Cursor
{
"filesystem": {
"command": "bun",
"args": ["run", "/path/to/files-mcp/src/index.ts"],
"env": {
"FS_ROOTS": "/Users/me/vault"
}
}
}
開發
bun dev
bun test
bun run typecheck
bun run lint
bun run build
bun run inspector
架構
src/
├── index.ts # 入口點:標準輸入輸出傳輸
├── config/
│ ├── env.ts # 環境配置和掛載解析
│ └── metadata.ts # 工具描述
├── core/
│ ├── capabilities.ts # 服務器功能
│ └── mcp.ts # McpServer構建器
├── tools/
│ ├── index.ts # 工具註冊
│ ├── fs-read.tool.ts # 讀取、瀏覽、搜索
│ └── fs-write.tool.ts # 創建、更新、刪除
├── lib/
│ ├── checksum.ts # SHA256校驗和
│ ├── diff.ts # 統一差異生成
│ ├── filetypes.ts # 文本/二進制文件檢測
│ ├── ignore.ts # .gitignore支持
│ ├── lines.ts # 行操作
│ ├── paths.ts # 多掛載路徑解析
│ └── patterns.ts # 模式匹配和預設
└── utils/
├── errors.ts # 錯誤處理工具
└── logger.ts # 日誌記錄
故障排除
| 問題 |
解決方案 |
| "SANDBOXED FILESYSTEM: Absolute paths not allowed" |
使用掛載點內的相對路徑。先使用 fs_read(".") 查看可用的掛載點。 |
| "Path does not match any mount" |
檢查 FS_ROOTS 是否設置正確。路徑必須以掛載點名稱開頭(例如,vault/notes.md)。 |
| "CHECKSUM_MISMATCH" |
自讀取文件後,文件已更改。使用 fs_read 重新讀取以獲取最新內容。 |
| "PATTERN_NOT_FOUND" |
模式在文件中不存在。嘗試 patternMode="fuzzy" 或先讀取文件。 |
| "MULTIPLE_MATCHES" |
模式匹配到多個位置。使用 replaceAll=true 或更具體的模式。 |
| 二進制文件錯誤 |
只能讀取和寫入文本文件。檢查文件擴展名。 |
| 單掛載仍顯示 "docs" |
更改 FS_ROOTS 後,重啟MCP服務器。 |
📄 許可證
MIT