浏览 MCP与Skills教程与资源
Filesystem MCP 配置:读一个测试文件,查清目录边界与只读限制
使用 @modelcontextprotocol/server-filesystem 完成一次可核对的读取,并解释为什么目录白名单、工具白名单和操作系统只读权限是三件事。
文件目录限制不会自动禁止写入
本例固定使用 MCP 官方 servers 仓库中的 Filesystem Server,在 Windows 的 Codex CLI 中连接;需要已安装的 Node.js/npm 和支持 MCP 的 Codex。它提供读写工具,命令后面的目录参数控制访问范围,并不把这个目录变成只读。要求 AI“只读”也不等于建立了权限边界。
我们只做三个可观察动作:回读允许目录、读取已知文本、请求一个目录外的无敏感样本。工具名、路径和预期内容保持一致。本文没有替读者安装该包或运行这些测试。
用两个全新的目录,避免碰到现有文件
下面脚本遇到已存在的 C:\mcp-lab 会停止;请选择一个未使用的位置并同步替换后文路径。它创建的两个文本都是教学数据。
创建允许目录与拒绝样本
$labRoot = 'C:\mcp-lab'
if (Test-Path -LiteralPath $labRoot) { throw '目录已存在,请换一个新的教学目录' }
New-Item -ItemType Directory -Path "$labRoot\allowed","$labRoot\outside" | Out-Null
Set-Content -LiteralPath "$labRoot\allowed\policy.txt" -Encoding UTF8 -Value 'LAB-ONLY: cancellation notice = 7 days.'
Set-Content -LiteralPath "$labRoot\outside\dummy.txt" -Encoding UTF8 -Value 'OUTSIDE-LAB: harmless boundary sample.'
Get-Content -LiteralPath "$labRoot\allowed\policy.txt"最后一行应显示 LAB-ONLY 开头的完整文本。这是之后核对工具结果的基线,不是搜索引擎摘要或 AI 推测。
Codex 只暴露这次需要的四个工具
把下列段落合并到用户级 ~/.codex/config.toml;已有同名项时修改原项,不要重复追加。Windows 用 cmd /c 启动 npx;macOS/Linux 改为 command = "npx",并删除 args 前两项。首次 npx 可能下载并执行该包;需要可重复环境时,先核对发布版本,再把包名固定到选定版本。
Windows / Codex CLI
[mcp_servers.filesystem_lab] command = "cmd" args = ["/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "C:/mcp-lab/allowed"] enabled_tools = ["list_allowed_directories", "list_directory", "read_text_file", "search_files"]
核对登记与当前会话
codex mcp get filesystem_lab # 重新打开 Codex 后,在交互界面输入: /mcp
enabled_tools 限制的是此 Codex 连接可调用的工具,不能约束同一操作系统账户下的其他进程,也不能代替容器只读挂载或文件 ACL。
先看实际允许目录,再读取 policy.txt
| 顺序与工具 | 参数 | 预期与解释 |
|---|---|---|
| 1. list_allowed_directories | {} | 只应包含 C:/mcp-lab/allowed;如果出现整个项目或用户目录,先停止后续读取 |
| 2. list_directory | {"path":"C:/mcp-lab/allowed"} | 应看到 policy.txt;本工具列文件名,不读取文件正文 |
| 3. read_text_file | {"path":"C:/mcp-lab/allowed/policy.txt"} | 正文与准备阶段一致:LAB-ONLY: cancellation notice = 7 days. |
| 4. search_files | {"path":"C:/mcp-lab/allowed","pattern":"*.txt"} | 匹配文件路径;这不是按正文检索‘7 days’的全文搜索接口 |
| 5. read_text_file | {"path":"C:/mcp-lab/outside/dummy.txt"} | 预期拒绝访问,不应返回 OUTSIDE-LAB 文本;这里测试的是无敏感教学文件 |
表中的 JSON 是工具参数,应由客户端对应工具传递;不要把它当终端命令。若客户端只接受自然语言,就要求它逐项显示实际工具名、参数与返回值。
为什么 args 很窄,运行时目录却变宽了
该 Server 支持 MCP Roots。如果客户端提供 Roots,Server 会以客户端给出的目录替换命令行允许目录;后续 Roots 变更也可能更新范围。因此,只截图 args 不能证明最终范围。list_allowed_directories 的结果才是本次连接实际生效范围的直接线索。
如果回读出现 C:/mcp-lab 而非 C:/mcp-lab/allowed,先检查客户端提供的工作区 Roots,再调整连接。不要通过读取真实私人文件来证明越界。对于符号链接、junction 或网络盘,另建一个无敏感测试链接核对解析后的范围;一次普通路径测试不能证明所有路径形式都安全。
只读任务完成以后,哪些结论仍不能写
读取成功,但列表里仍有 write_file 或 edit_file
- 原因
- 当前会话未应用工具过滤,或连到了另一个同名 Server。
- 怎么改
- 回读配置并重开会话,核对 Server 身份和工具清单。本例不通过尝试覆盖文件来补救。
目录外 dummy.txt 居然能读到
- 原因
- 运行时允许根目录可能被 Roots 扩大;也可能使用了 Codex 内置文件工具,而非本例 MCP。
- 怎么改
- 先检查调用记录中的 Server 与工具名,再回读 list_allowed_directories。分别检查这两个变量,不能直接归咎于 Server 漏洞。
要求‘只读’,却想据此证明写入必定失败
- 原因
- 自然语言要求与客户端工具过滤都不是底层文件系统权限。
- 怎么改
- 如果业务要求强制不可写,需使用专用低权限账户或容器只读挂载,随后在另一个可丢弃样本验证写入拒绝。没有这层配置,就只报告‘本次未执行写入’。
