Back to MCP directory
publicPublicdnsLocal runtime

files-stdio-mcp-server

一个提供沙盒化文件访问的MCP服务器,支持目录探索、文件读取、内容搜索和安全编辑,适用于AI代理管理文本文件集合。

article

README

🚀 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"
      }
    }
  }
}

✨ 主要特性

  • 目录浏览 — 以树状视图显示文件数量、大小和时间戳
  • 文件读取 — 带行号的文件内容,并提供校验和以确保安全编辑
  • 文件查找 — 按文件名模式(*.mdconfig.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安装

  1. 下载 files-mcp.mcpb 文件
  2. 使用兼容的应用程序(Claude Desktop、Alice等)打开它
  3. 在提示时配置 根目录 — 这是代理可以访问的目录
  4. 完成!服务器已安装并可以使用

manifest.json

该清单定义了:

  • 服务器配置 — 命令、参数、环境变量
  • 工具fs_readfs_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;                    // "." 表示根目录,"docs/"、"notes/todo.md"
  
  // 按名称查找文件
  find?: string;                   // "*.md"、"config.json"
  
  // 搜索内容
  pattern?: string;                // 要搜索的文本
  patternMode?: "literal" | "regex" | "fuzzy";
  caseInsensitive?: boolean;        // 匹配时忽略大小写
  preset?: "wikilinks" | "tags" | "tasks" | "tasks_open" | "tasks_done" 
         | "headings" | "codeblocks" | "frontmatter";
  
  // 选项
  depth?: number;                  // 目录遍历深度(默认 3)
  details?: boolean;               // 是否包含文件大小和修改时间(默认 false)
  lines?: string;                  // "10-50" 表示部分读取
  context?: number;                // 匹配项周围的行数(默认 3)
  maxFiles?: number;               // 返回匹配文件的最大数量(默认无限制)
  maxMatches?: number;             // 限制匹配数量(默认 100)
}

输出

{
  success: boolean;
  path: string;
  type: "directory" | "file" | "search";
  
  // 对于目录
  tree?: {
    entries: Array<{ path, kind, children?, size?, modified? }>;
    summary: string;
  };
  
  // 对于文件
  content?: {
    text: string;        // 带行号的文本
    checksum: string;    // 传递给 fs_write
    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;                  // "10-15" — 推荐方式
  pattern?: string;                // 要查找的文本
  patternMode?: "literal" | "regex" | "fuzzy";
  caseInsensitive?: boolean;       // 匹配时忽略大小写
  
  // 对于更新操作 — 操作类型
  action?: "replace" | "insert_before" | "insert_after" | "delete_lines";
  content?: string;                // 新内容
  
  // 批量替换
  replaceAll?: boolean;            // 替换所有匹配项
  
  // 安全特性
  checksum?: string;               // 从 fs_read 获取 — 推荐使用
  dryRun?: boolean;                // 仅预览(默认 false)
}

输出

{
  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 # 进行TypeScript检查
bun run lint      # 代码检查
bun run build     # 生产环境构建
bun run inspector # 使用MCP 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

help

Runtime guide

cloud

Hosted runtime

Hosted servers run from a provider-managed environment. You usually connect the MCP client to the hosted endpoint or follow the provider's authorization flow, without keeping a local process alive

  1. Open provider connection page
  2. Authorize or copy endpoint
  3. Connect from your MCP client
terminal

Local runtime / other methods

Local servers run on your own machine or infrastructure. You normally copy the server_config into your MCP client, install the required package, and provide env variables from env_schema when needed

  1. Copy server_config
  2. Install required package
  3. Fill env variables and restart client