Skip to main content
Glama
filesystem-mcp-server

filesystem-mcp-server

by GAVTIN

Resume Matcher — MCP 版

简历匹配代理的直接文件系统工具,被替换为一个独立的 MCP 服务器,外加一个重构为通过真实 MCP 客户端(而非本地函数调用)与该服务器(以及第二个 MCP 服务器)通信的 LangGraph 代理。

学习目标 → 本仓库内容

目标

位置

理解模型上下文协议(Model Context Protocol)

filesystem_mcp_server.py 实现了工具和资源;在 tests/ 中针对真实的 JSON-RPC 2.0 线上协议进行测试(非模拟)

用 MCP 服务器替换自定义工具

里程碑 1 的每个文件系统操作现在都是 @mcp.tool();matching_agent.py 中没有任何直接导入文件系统代码的内容

实现标准化工具接口

每个工具上都有一致的 {"success": bool, ...} 信封;结构化的 JSON-RPC 风格错误码(见下文)

部署生产级系统

基于环境变量的配置、有界并发、部分失败处理、经过测试的环境变量转发修复、跨单元 + 协议层的 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 note

check_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.py

Windows 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():

变量

默认值

RESUME_DIRECTORY

./sample_data/resumes

RESULTS_DIRECTORY

./results

ALLOWED_EXTENSIONS

.txt,.pdf,.docx

MAX_BATCH_CONCURRENCY

5

NOTIFY_SCORE_THRESHOLD

70 (matching_agent.py)

MATCHING_AGENT_MODEL

anthropic:claude-sonnet-5

测试

pytest tests/ -v

14 个测试,分两层:

  • 单元测试(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)

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables file system operations (read, write, list, search, watch, batch process) via MCP over JSON-RPC 2.0, used by a resume matching agent.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides file system tools for resume matching agents, enabling reading, writing, searching, listing, watching, and batch processing of files via the Model Context Protocol.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides MCP tools for reading, listing, writing, searching, watching, and batch-processing files, enabling automated file management and resume matching workflows.
    -