filesystem-mcp-server
Resume Matcher — MCP 版
简历匹配代理的直接文件系统工具,被替换为一个独立的 MCP 服务器,外加一个重构为通过真实 MCP 客户端(而非本地函数调用)与该服务器(以及第二个 MCP 服务器)通信的 LangGraph 代理。
学习目标 → 本仓库内容
目标 | 位置 |
理解模型上下文协议(Model Context Protocol) |
|
用 MCP 服务器替换自定义工具 | 里程碑 1 的每个文件系统操作现在都是 |
实现标准化工具接口 | 每个工具上都有一致的 |
部署生产级系统 | 基于环境变量的配置、有界并发、部分失败处理、经过测试的环境变量转发修复、跨单元 + 协议层的 14 个通过测试 |
Related MCP server: Filesystem MCP Server
架构
flowchart LR
subgraph "Agent process (matching_agent.py)"
A["LangGraph StateGraph"] --> B["MultiServerMCPClient"]
A --> L["Claude (LLM)\nstructured scoring"]
end
B <-->|"JSON-RPC 2.0 / stdio"| C["filesystem_mcp_server.py"]
B <-->|"JSON-RPC 2.0 / stdio"| D["notifications_mcp_server.py"]
C --> E[("sample_data/resumes/\nresults/")]
D --> F[("results/notifications.log")]两个独立的 MCP 服务器,各自作为独立的操作系统进程,彼此之间以及和 LangGraph 之间互不知晓。代理在启动时发现它们的工具(client.get_tools())并按名称调用——这正是重构的全部意义:filesystem_mcp_server.py 明天可以新增一个工具,而 matching_agent.py 无需任何代码更改。
状态机(代理 ↔ MCP 交互)
stateDiagram-v2
[*] --> check_new_resumes
check_new_resumes --> batch_extract: new files found
check_new_resumes --> [*]: nothing new — short-circuit
batch_extract --> match: text extracted
match --> rank_and_save: LLM structured scoring
rank_and_save --> notify: results persisted
notify --> [*]: done
note right of check_new_resumes
filesystem server
tool: watch_directory
end note
note right of batch_extract
filesystem server
tool: batch_process
end note
note right of rank_and_save
filesystem server
tool: save_match_result (per match)
end note
note right of notify
notifications server
tool: send_match_notification
(only matches scoring >= 70)
end notecheck_new_resumes 首先调用 watch_directory——在接触任何其他内容之前——这是有意为之:如果一次运行没有新内容,就会直接短路到 [*],不消耗一次 LLM 调用;而 --watch 模式(见下文)只重新处理实际发生变化的内容,而不是每次都处理整个目录。
本地运行
从仓库根目录创建虚拟环境并安装依赖。
Bash / Git Bash / Linux / macOS
cd [Path To Files]
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
export ANTHROPIC_API_KEY="<your-anthropic-api-key>"
python matching_agent.pyWindows PowerShell
cd [Path To Files]
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
$env:ANTHROPIC_API_KEY = "<your-anthropic-api-key>"
python .\matching_agent.py如果你想从头重新扫描收件箱
监视器会维护一个小型状态文件,因此它只对新添加的简历进行评分。如果你想再次处理当前文件夹,请先清除监视器状态:
python matching_agent.py --reset-watch常见用法模式
# one pass over the bundled sample data
python matching_agent.py
# run against your own job description and resume folder
python matching_agent.py --job-description path/to/jd.txt --resume-dir path/to/resumes
# keep polling for newly added resumes every 15s (Ctrl+C to stop)
python matching_agent.py --watch --interval 15运行代理时,请使用项目虚拟环境的 Python,而不是系统 Python。在本仓库中,有效的命令通常是 Windows 上的
./.venv/Scripts/python.exe matching_agent.py,或 Unix 类 shell 上的source .venv/bin/activate && python matching_agent.py。
可以单独运行任一服务器来直接测试(配合 MCP Inspector 很方便):
python filesystem_mcp_server.py
python notifications_mcp_server.py配置由环境变量驱动——参见 filesystem_mcp_server.py 中的 ServerConfig.from_env():
变量 | 默认值 |
|
|
|
|
|
|
|
|
|
|
|
|
测试
pytest tests/ -v14 个测试,分两层:
单元测试(
test_filesystem_mcp_server.py,大部分内容):直接针对tmp_path夹具调用工具函数——快速,无子进程。涵盖成功路径、RESUME_NOT_FOUND/INVALID_PARAMS错误码,以及batch_process的部分失败报告。协议测试(
test_server_speaks_mcp_protocol_over_stdio):将真实服务器作为子进程启动,并使用官方mcp客户端 SDK 驱动它——tools/list、tools/call、resources/read——通过真实的 JSON-RPC 2.0,因此它验证的是协议层,而不仅仅是其下的 Python。代理测试(
test_matching_agent.py):LLM 调用被替换为确定性的假实现(FakeStructuredModel),因此这些测试不需要 API 密钥——它们检查的是图接线、多服务器工具发现、无新文件时的短路路径,以及第二次--watch风格的传递只重新处理新到达的文件,而不是整个目录。
设计决策
MCP SDK 固定为 mcp>=1.28,<2.0。 Python SDK 的 v2 系列随 2026-07-28 MCP 规范修订版一起发布,并将 FastMCP 重命名为 MCPServer(现在位于 mcp.server.mcpserver 下)。v1.x 是当前 LangChain/LangGraph MCP 生态系统所构建和文档化的版本,因此本项目有意固定在该版本,而不是偶然——一旦 langchain-mcp-adapters 和更广泛的教程基础跟上 v2,值得重新审视。
stdio 而非 HTTP。 没有需要保护的网络面,没有需要接线的认证,而且这正是 MultiServerMCPClient 对本地“命令”服务器所期望的。构建时确认的权衡:每次工具调用都会打开一个新的子进程会话,而不是复用——对于演示/CLI 代理来说没问题,这也是对延迟敏感的生产版本会转向长期存在的 streamable-http 服务器的真实原因。
错误是结构化 JSON,而不是散文。 每次失败都会抛出 ToolError,其 JSON 载荷携带 JSON-RPC“服务器错误”范围内的 code(-32000..-32099),外加机器可读的 error 标签(RESUME_NOT_FOUND、DIRECTORY_NOT_FOUND、UNSUPPORTED_FILE_TYPE、EXTRACTION_FAILED、INVALID_PARAMS)。已针对实时客户端会话端到端确认:它以 CallToolResult(isError=True, ...) 的形式出现,而 matching_agent.py 的 _call_tool() 会将其重新抛出为 MCPToolCallError,并保留代码,而不是让调用者去字符串匹配消息。
watch_directory 是轮询,不是推送。 MCP 工具是请求/响应式的,因此这是一个轮询(一个文件名→mtime 的 JSON 状态文件,每次调用时进行差异比较),而不是 inotify/watchdog 监听器。matching_agent.py 的 --watch 模式才是让它看起来像实时的东西——通过 MCP 资源订阅推送的后台监听器将是自然的下一步,并且协议支持,只是不在本项目的范围内。
batch_process 接受显式文件列表,而不仅仅是目录。 这正是让 check_new_resumes → batch_extract 只重新处理 watch_directory 刚报告的内容,而不是每次都处理整个文件夹的原因——并发(asyncio.Semaphore(MAX_BATCH_CONCURRENCY))使得规范中的“高效”在列表很长时真正成立。
环境变量转发是显式的,而且不是可以跳过的默认值。 构建时遇到的一个真实陷阱:mcp 的 stdio 客户端不会继承父进程的环境变量——它用最小的默认值(仅 PATH/HOME/TERM)启动子服务器,这一点已直接针对 mcp.client.stdio.get_default_environment() 确认。如果在 matching_agent.py 的服务器配置中没有显式传递 env=dict(os.environ),RESUME_DIRECTORY 等变量就永远不会到达 filesystem_mcp_server.py——代理运行正常,工具发现正常,只是静默地在错误的目录上操作。在它让你浪费一次调试会话之前,值得了解。
仓库结构
resume-matcher-mcp/
├── filesystem_mcp_server.py # Part A
├── notifications_mcp_server.py # Part B bonus: 2nd MCP server
├── matching_agent.py # Part B
├── requirements.txt
├── pytest.ini
├── tests/
│ ├── test_filesystem_mcp_server.py
│ └── test_matching_agent.py
├── sample_data/
│ ├── job_description.txt
│ └── resumes/ # 21 resumes, deliberately strong/partial/weak fit
└── results/ # match_results.jsonl + notifications.log (gitignored)This server cannot be deployed
Maintenance
Related MCP Connectors
Document processing over MCP: merge, split and compress PDFs, run OCR, extract document text.
Build, version and render resumes as PDFs from Claude or any MCP client.
Hosted MCP tools for FFmpeg-style video and audio processing through FFMPEG API.
Patents MCP — wraps the USPTO Open Data Portal (ODP) Patent File Wrapper API
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables file system operations (read, write, list, search, watch, batch process) via MCP over JSON-RPC 2.0, used by a resume matching agent.-
- FlicenseNot gradedqualityDmaintenanceProvides file system tools for resume matching agents, enabling reading, writing, searching, listing, watching, and batch processing of files via the Model Context Protocol.-
- FlicenseNot gradedqualityCmaintenanceProvides MCP tools for reading, listing, writing, searching, watching, and batch-processing files, enabling automated file management and resume matching workflows.-
- FlicenseNot gradedqualityCmaintenanceEnables MCP clients to interact with a filesystem by listing, reading, writing, and monitoring files, as well as extracting resume text and batch processing files.-