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 installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Generate tailored, ATS-optimized resume PDFs and cover letters from a job description, over MCP.
Hosted MCP tools for FFmpeg-style video and audio processing through FFMPEG API.
Resume builder with native MCP — create and edit resumes from your AI assistant.
Public MCP server for discovering open jobs. Search, filter, and get application links.
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 gradedqualityCmaintenanceEnables AI agents to interact with a sandboxed filesystem via MCP tools for reading, writing, searching, and monitoring files, including batch processing and resource discovery for resume management.
- FlicenseNot gradedqualityCmaintenanceProvides 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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/GAVTIN/Resume-Matcher-MCP-Edition'
If you have feedback or need assistance with the MCP directory API, please join our Discord server