mcpField
E
emperor-folder

emperor-folder

本地服务
github.com文件与存储05 天前更新

关于 emperor-folder

emperor-folder 是供 Agent 和客户端操作指定文件夹的 MCP 服务。默认只读,并将文件操作限制在配置的根目录内;启用后可修改文件。

主要功能

  1. 01列出、读取、搜索和查看文件信息
  2. 02可选的写入、编辑和移动操作
  3. 03将访问限制在配置的文件夹根目录
  4. 04通过 Streamable HTTP 或 stdio 连接
  5. 05筛选隐藏文件和忽略文件

适用场景

  1. 01让 Agent 搜索项目文件而不开放其他目录
  2. 02启用写入后允许受控地编辑文件
  3. 03向 MCP 客户端提供多个命名文件夹

MCP 相关

向 MCP 客户端提供文件夹列表、读取、搜索和元数据工具;只有启动时启用写入功能,才会提供写入、编辑和移动工具。支持 Streamable HTTP 和 stdio。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库
安装包
cargoemperor-folder0.1.3

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

emperor-folder

CI license Glama

一个仅限于单个文件夹的 MCP 服务。 指定一个或几个目录后,模型便可以列出、读取、搜索,以及(如果你允许)写入、编辑和移动其中的文件;它无法访问目录之外的任何内容:无论是通过绝对路径、..,还是符号链接。

emperor-folder serve --root ~/notes            # read-only, Streamable HTTP on 127.0.0.1:8031/mcp
emperor-folder serve --root ~/notes --writable # also write, edit and move
emperor-folder serve --root ~/notes --stdio    # for desktop clients
emperor-folder serve --root notes=~/notes --root code=~/src/app   # two roots: notes/..., code/...

原因

把“文件系统”交给 Agent,是让它拿到你的 SSH 密钥最快的方式。大多数文件工具都会用字符串前缀检查路径,然后以进程的完整权限打开文件;一个符号链接、一个检查漏掉的 ..,或检查与打开之间的一次竞态,就足以让模型越界。

emperor-folder 不会先检查再打开。它会将根目录一次性打开为一个 cap-std 目录句柄,并通过该句柄使用相对路径执行所有文件操作,因此路径解析会遵循操作系统(或 cap-std)的根目录范围规则。代码中不存在通过绝对路径打开文件的路径。

它基于 emperor-mcp 构建:无状态的 Streamable HTTP(无会话 ID,适合负载均衡器),输出采用封装格式,使文件内容以数据而非指令的形式传递给模型,并提供 doctor 子命令。它遵循 Emperor Profile P1.1:除非操作员在启动时启用写入,否则不会提供写入工具;工具定义也精简(描述简短、输入架构紧凑),从而减少每个请求携带的内容。

安装

Linux(x86_64)、macOS(Apple Silicon 和 Intel)以及 Windows 的发布二进制文件均附在每个 GitHub 发布版本中,并附有 SHA256SUMS 文件和构建来源证明 attestations:使用 sha256sum -c SHA256SUMS --ignore-missing 检查下载文件,并使用 gh attestation verify <file> --repo yarenty/emperor-folder 验证。从源代码构建(Rust 1.88 或更高版本):

cargo install emperor-folder

也可以作为容器运行(stdio,将文件夹挂载到 /data,默认只读,除非添加 --writable):

docker build -t emperor-folder https://github.com/yarenty/emperor-folder.git
docker run -i --rm -v ~/notes:/data emperor-folder                            # read-only
docker run -i --rm -v ~/notes:/data emperor-folder --root /data --writable    # also write, edit, move
docker run -i --rm -v ~/notes:/data -e FOLDER_WRITABLE=true emperor-folder     # the same, from the environment

运行

emperor-folder doctor --root ~/notes   # check first: exits 1 if something is wrong
emperor-folder serve  --root ~/notes
标志默认值含义
--root [NAME=]DIR(必填)服务可以访问的文件夹。可重复指定多个根目录;NAME= 用于命名根目录(默认值:文件夹自身的名称)。参见多个根目录。
--bind ADDR127.0.0.1:8031Streamable HTTP 地址;MCP 端点为 /mcp,存活状态端点为 /health。
--writable关闭提供 write、edit 和 move。关闭时,这些工具不会列出。也可通过环境变量 FOLDER_WRITABLE 设置:true、1 或 yes(以及 on)会启用;未设置、为空、false、0 或 no(以及 off)会保持关闭;其他值将被拒绝。
--stdio关闭通过 stdin/stdout 而非 HTTP 使用 MCP。日志输出到 stderr。
--hidden关闭在 list 和 search 中包含隐藏文件和目录。
--no-ignore关闭不遵循 .gitignore、.ignore 和 git exclude 文件。
--max-file-bytes N1048576read 完整返回、search 打开、stat 统计行数以及 write 接受的文件大小上限。
--max-results N200list 返回的条目数以及 search 返回的匹配数上限。
--max-chars N50000单次 read 返回的文本字符数上限(最高为 200 000);超出时会在行边界处停止,并说明从何处继续。
--allowed-host HOST见下文接受的 Host 标头,可重复指定。
--allowed-origin ORIGIN无接受的 Origin 标头,需包含 scheme(https://app.example.com),可重复指定。没有 Origin 的请求(非浏览器客户端)仍会通过。

RUST_LOG 设置日志级别(默认值为 info)。

连接

Claude Code

claude mcp add --transport http folder http://127.0.0.1:8031/mcp     # server already running
claude mcp add folder -- emperor-folder serve --stdio --root ~/notes  # or let Claude Code start it

使用 --writable(以及多个根目录)的 stdio 形式:

claude mcp add folder -- emperor-folder serve --stdio --writable --root notes=$HOME/notes --root code=$HOME/src/app

Claude Desktop(claude_desktop_config.json,stdio):

{
  "mcpServers": {
    "folder": {
      "command": "/usr/local/bin/emperor-folder",
      "args": ["serve", "--stdio", "--root", "/Users/me/notes"]
    }
  }
}

kowalski(config.toml):

[[mcp.servers]]
name = "folder"
transport = "http"
url = "http://127.0.0.1:8031/mcp"

或通过 stdio:

[[mcp.servers]]
name = "folder"
transport = "stdio"
command = ["emperor-folder", "serve", "--stdio", "--root", "/home/me/notes"]

其他任何支持 Streamable HTTP 或 stdio 的 MCP 客户端也可采用相同方式。

工具

共有七种工具,每种都是一个动词。所有路径均相对于根目录(. 或省略表示根目录)。 只有使用 --writable 时才会提供三个会修改文件的工具;只读服务会列出四个工具。

工具参数返回内容注释
listpath?、glob?、recursive?(false)、max_entries?包含路径、类型(file/dir/symlink)和大小的条目;超出限制时会包含 truncated。只读、幂等
readpath、start_line?、end_line?(从 1 开始,含首尾)文本,带有 path lines A-B of N 标头。大小不超过 5 MiB(且不超过 --max-file-bytes)的 PNG、JPEG、GIF 和 WebP 图片会作为 MCP 图片内容返回;其他二进制文件会报告其信息(binary: true、大小),不会输出文件内容。只读、幂等
searchpattern(正则表达式)、path?、glob?、ignore_case?(false)匹配结果,包含路径、行号和行内容(截断至 240 个字符);以及已搜索文件数、因二进制而跳过的文件数、因文件过大而跳过的文件数。只读、幂等
statpath类型、大小、修改时间(RFC 3339、UTC)、只读标记;对于大小在限制内的文本文件,还会返回行数;对于图片,还会返回图片类型。只读、幂等
writepath、content、mode?(create | overwrite | append,默认为 create)路径和写入的字节数。会创建父目录。create 模式下,如果文件已存在则会拒绝写入。具有破坏性,仅限 --writable
editpath、old_text、new_text、replace_all?(false)路径、完成的替换次数、写入的字节数。除非设置 replace_all,否则 old_text 必须恰好出现一次(否则错误信息会说明出现次数)。仅支持文本文件。具有破坏性,仅限 --writable
movefrom、to、overwrite?(false)新路径。在根目录内重命名或移动(也可以在根目录之间移动);除非设置 overwrite,否则不会替换已存在的目标。具有破坏性,仅限 --writable

每个工具都会设置 openWorldHint: false:它只会操作指定的文件夹,不会涉及其他内容。

list 和 search 使用 ripgrep 的遍历器 ignore: 除非另行指定 --no-ignore / --hidden,否则会跳过 .gitignore(即使不在 git 工作区内)、.ignore 和隐藏文件,并且绝不会跟随符号链接。正则表达式使用 regex crate:匹配时间为线性,不会发生灾难性回溯,编译后的大小上限为 1 MiB。Glob 会匹配工具显示的路径(*.rs 可匹配 src/main.rs)。

输出。 read 返回的文件内容会被框定为作者身份未知的文档(FrameKind::Document);列表、匹配结果和元数据会作为计算结果以 JSON 格式框定(FrameKind::Computed)。每次调用的帧 nonce 都不同,因此,即使文件中包含伪造的数据结束标记,也无法跳出代码块。拒绝操作时会返回工具错误(isError: true),并说明应如何处理。

多个根目录

--root 可以指定多次。只有一个根目录时,行为不变:路径相对于该根目录。 指定多个根目录时,每个路径都以根目录名称开头,而 . 是一个虚拟文件夹,其条目为各个根目录:

emperor-folder serve --root notes=~/notes --root code=~/src/app
list .                      -> notes, code
read notes/todo.md
search pattern=TODO         -> matches in notes/... and code/...
move  notes/a.md -> code/docs/a.md   (with --writable)

未命名的根目录会以其文件夹名命名(--root ~/notes 的名称为 notes);如果两个根目录名称相同,启动时会拒绝运行。在 NAME=DIR 中,名称不能包含 / 或 \,因此 ./a=b 表示一个名为 a=b 的文件夹。每个根目录都有独立的 cap-std 句柄:路径、.. 或符号链接都无法在根目录之间跳转,除非通过同时指定两端的 move 操作。

安全模型

模型可以执行的操作:查看和读取根目录下未被忽略规则屏蔽的文件;使用 --writable 时,可在根目录下创建、编辑和重命名文件。

模型无法执行的操作:

  • 离开根目录。 绝对路径(/etc/passwd、Windows 上的 C:\)会被拒绝,包含 .. 组件的路径也会被拒绝,即使该路径仍在根目录内(a/../b)。此检查会给出明确的错误;底层的强制措施由 cap-std 实现:它会将每个路径解析到根句柄之下(Linux 上使用 openat2(RESOLVE_BENEATH),其他平台则逐个组件解析),并拒绝任何会越出根目录的解析结果。
  • 通过符号链接逃逸。 根目录内指向根目录外部(包括指向另一个根目录)的符号链接,在 read、write、edit、move、list 和 search 中都会被拒绝;指向根目录内部的符号链接则可正常使用。遍历器绝不会跟随链接,且会通过根句柄重新打开返回的每个路径,因此,遍历过程中被替换为逃逸链接的目录会被跳过,而不会被读取。
  • 默认写入。 服务启动时为只读模式:write、edit 和 move 会从工具列表中移除,文件操作也会拒绝写入,除非操作人员传入 --writable(或设置 FOLDER_WRITABLE),这是 Emperor Profile P1.1 的要求。工具注释(readOnlyHint、destructiveHint)会告知客户端哪些工具会更改文件,以便客户端在运行前征求确认。
  • 耗尽主机资源或上下文。 整个文件的读取会受 --max-file-bytes 限制(按行范围读取会以流式方式进行,且返回内容不超过该限制),并受 --max-chars 字符数限制;search 会跳过较大的文件,list 和 search 会在达到 --max-results 后停止;除较小的图像外,不会返回二进制文件。
  • 被网页访问。 绑定到环回地址时,Host 标头必须为 localhost、127.0.0.1 或 ::1(用于防止 DNS 重绑定)。绑定到非环回地址时,此检查会关闭,因为 Emperor Profile 要求前置一个会进行验证的入口;--allowed-host 可对指定主机重新启用此检查,而 --allowed-origin 会拒绝来自任何其他源的浏览器请求。

不在范围内:身份验证(请将 HTTP 端点置于网关之后,或让其仅绑定到环回地址)和硬链接(根目录内指向外部文件的硬链接与该文件是同一个文件;请勿将服务指向不受信任的用户能够创建硬链接的文件夹)。服务运行期间,其他本地进程仍可能更改文件夹;由于每次操作都会重新解析路径,确保路径位于根目录之下,因此无论如何都能保持隔离。

doctor

$ emperor-folder doctor --root ~/notes --writable
emperor-folder 0.1.3 doctor
  [ok  ] dir /Users/me/notes  readable (42 entries)
  [ok  ] dir /Users/me/notes  writable
  [ok  ] write access         on: write, edit and move are offered
  [ok  ] roots                notes = /Users/me/notes
  [ok  ] listen address       127.0.0.1:8031 is free
  [ok  ] tool budget          7 of at most 8 tools
  [ok  ] files                1234 visible files under the roots
all good (0 warning(s))

它会检查每个根目录是否存在且可列出;设置 --writable 时是否可写(会创建并删除一个探测文件);报告写入是否已启用;检查根目录能否打开且名称各不相同;检查监听地址是否空闲(使用 --stdio 时跳过);检查工具数量是否在 emperor-mcp 预算范围内;并统计遍历器可见的文件数量(超过 100 000 个时会发出警告:列出和搜索会变慢)。无失败时退出代码为 0,否则为 1,因此脚本和容器健康检查可以使用它。

构建

cargo fmt --all --check
cargo clippy --all-targets -- -D warnings
cargo test          # unit tests + every tool over real HTTP and stdio, escape attempts included
cargo deny check

链接

贡献

请参阅 CONTRIBUTING.md:运行检查,保持文档同步更新,并为提交签署贡献者声明(DCO,git commit -s)。

许可证

可选择以下任一许可证:

除非你明确另行说明,否则你有意提交以纳入 emperor-folder 的任何贡献,均按上述双重许可进行授权,不附加任何条款或条件。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。