📰 来源:Towards Data Science | 📅 翻译日期:2026年6月6日
🔗 原文:查看原文
🤖 翻译:DeepSeek AI · 仅供参考
问题:AI无法直接访问文件,手动复制效率低下
我正在重构一个爬虫。函数变得太长,变量名也毫无意义了。每当我需要反馈某个文件时,我都得停下工作,打开聊天窗口,把整个文件复制进去,然后等待。之后回到编辑器,应用修改,再打开下一个文件,重复上述过程。
到了某个时刻我数了一下:六个文件,十一次粘贴,二十分钟的切换,还没写一行新代码。
明显的解决方法是让AI工具直接访问我的项目文件夹。这时我遇到了MCP(Model Context Protocol)——它正是为此而设计的。一个本地运行的服务器暴露工具,AI客户端直接调用这些工具,而不是等我粘贴内容。
于是我查看了现有的实现。大多数需要 FastAPI、uvicorn、LangChain 或官方MCP SDK。在写一行业务逻辑之前,我的requirements文件中已经有了五个包,而且这个服务器在Windows上能否顺利运行我心里也没底。
我退一步,阅读了实际的MCP规范 [1]。该协议是基于传输层的 JSON-RPC 2.0 [2]。每行一个JSON对象。客户端发送,服务器响应。规范明确定义了两种传输方式:stdio 用于本地单客户端连接,以及带 Server-Sent Events 的HTTP用于并发客户端。
这就是整个协议。
我问了一个不同的问题:Python标准库已经提供了什么?sys.stdin、sys.stdout、http.server、threading、queue、pathlib、json。就这些。没有一个需要 pip install。
本文就是这种实现——两种传输方式、一个生产级安全模型、50 个测试以及运行后的数据。
TL;DR
大多数MCP实现比它们本应有的要重。规范只定义了两种传输方式:stdio 和 HTTP/SSE,但在实践中它们通常被包装在框架和额外依赖中。
我仅使用Python标准库从头构建了这两种传输方式。
它以单个文件运行,带一个运行时标志。无需安装,无需配置。
对于本地工作,它使用带有单个客户端的stdio。当需要并发时,它切换到HTTP/SSE并处理多个客户端,无需更改其他任何内容。
在底层,一切保持一致。相同的分发器、相同的工具、相同的安全模型。
由于它涉及文件系统,我早期就添加了严格的路径检查。常见的逃逸模式如 ../../、符号链接技巧和Windows UNC路径都被阻止。
5 个并发客户端,总耗时低于 50ms。在Windows 11、Python 3.12.6、仅CPU上验证。
完整代码:https://github.com/Emmimal/local-mcp-server/
决定设计的关键错误
在架构之前,我想告诉你一件差点让我放弃整个事情的事。
在开发早期,我正在测试搜索工具。我将服务器指向 C:\Users\Admin 并运行它查找Python文件。服务器启动,演示开始运行。然后它一直运行。
三十秒。一分钟。五分钟。我以为是某个地方出现了无限循环。我检查了三次代码,一切看起来都正确。我终止进程并重启,结果相同。
十分钟后我终于明白了发生了什么。搜索工具默认使用 rglob()。我把它指向了整个用户目录,它正在扫描所有内容——虚拟环境、AppData、机器上的每个缓存文件。成千上万个文件,一次一个。
我终止进程并修改了一行代码:
# 之前——默认递归,扫描所有内容
for match in target.rglob(pattern):
# 之后——默认浅层,选择递归
for match in target.glob(pattern):并使 recursive=False 成为默认参数。客户端必须显式传递 recursive=True。服务器绝不对自己进行递归扫描。
这一改动使得现在搜索在一个真实项目文件夹上在 30ms 内完成,而不是永远运行下去。这成了我处处应用的规则:任何破坏性能的行为都不应该是默认的。
MCP到底是什么
Model Context Protocol [1] 是一种标准化的方式,让AI客户端调用外部服务器上的工具。它使用 JSON-RPC 2.0 [2] 作为消息格式。
在实践中,这意味着像 Claude 或 ChatGPT 这样的AI客户端可以直接访问并推理本地文件,而不是依赖复制粘贴。
握手有三个阶段。首先客户端初始化,然后询问有哪些可用工具,接着开始调用它们:
The Model Context Protocol (MCP) message lifecycle. A clean architectural overview showing the sequential, bi-directional JSON-RPC exchange between Client and Server during the Initialization, Discovery, and Execution stages. Image by Author
之后的一切都是传输层来回传递消息。
规范定义了两种传输方式。stdio 通过标准输入输出运行——每行一个JSON对象,立即刷新。HTTP/SSE 通过HTTP POST发送请求,响应通过持久的Server-Sent Events连接流回 [3]。
大多数实现只选择一种。这个实现两者都支持,使用相同的分发器和相同的四个工具。
以下是演示启动时显示的内容——两种传输方式都注册了相同的工具:
[2] Available tools
[list_directory ] List files and directories. Returns name, type, size...
[read_file ] Read a file's contents. Max 1 MB. Binary files returned...
[search_files ] Search files by glob pattern. Use recursive=true for...
[get_file_info ] Get metadata for a file or directory: size, type, ext...架构:四层结构
系统有四层。
The Model Context Protocol (MCP) decoupled architectural stack. A structural breakdown highlighting how raw client messages are securely transported, routed, validated, and executed within a strictly sandboxed local file system environment. Image by Author
- 安全层 —— 在任何文件系统操作之前验证每个路径。它运行在沙盒中,阻止所有已知的路径逃逸。
- 传输层 —— 处理消息的序列化和反序列化,对stdio和HTTP/SSE使用相同的内部接口。
- 分发层 —— 将传入的RPC调用路由到正确的工具处理程序。
- 工具层 —— 实际执行文件系统操作的工具,如
list_directory、read_file、search_files和get_file_info。
安全性和性能
安全性是所有设计的核心。路径验证在每次调用之前运行,包括解析真实路径、检查是否在允许的根目录内、以及阻止符号链接和UNC路径。
性能优化包括:默认浅层扫描、限制文件大小为 1 MB、以及使用 asyncio 进行并发处理。在 5 个并发客户端下,总耗时低于 50ms。
评论已关闭