filesystem-mcp-server
Resume Matcher — MCP Edition
Die direkten Dateisystem-Tools des Resume-Matching-Agenten wurden durch einen eigenständigen MCP-Server ersetzt, plus ein LangGraph-Agent, der so umgestaltet wurde, dass er über einen echten MCP-Client mit ihm (und einem zweiten MCP-Server) kommuniziert, anstatt über lokale Funktionsaufrufe.
Lernziele → was in diesem Repo ist
Ziel | Wo |
Model Context Protocol verstehen |
|
Eigene Tools durch MCP-Server ersetzen | Jede Dateisystemoperation aus Meilenstein 1 ist jetzt ein |
Standardisierte Tool-Schnittstellen implementieren | Einheitlicher |
Produktionsreife Systeme bereitstellen | Umgebungsbasierte Konfiguration, begrenzte Nebenläufigkeit, Behandlung von Teilfehlern, ein getesteter Fix für die Umgebungsweitergabe, 14 bestandene Tests über Unit- und Protokollebenen |
Related MCP server: Filesystem MCP Server
Architektur
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")]Zwei unabhängige MCP-Server, jeweils ein eigener OS-Prozess, ohne Kenntnis voneinander oder von LangGraph. Der Agent entdeckt ihre Tools beim Start (client.get_tools()) und ruft sie beim Namen auf – das ist der ganze Sinn des Refactorings: filesystem_mcp_server.py könnte morgen ein neues Tool bekommen und matching_agent.py bräuchte keine Codeänderung.
Zustandsmaschine (Agent ↔ MCP-Interaktion)
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 noteDass check_new_resumes zuerst watch_directory aufruft – bevor irgendetwas anderes angefasst wird – ist beabsichtigt: Ein Lauf ohne Neues führt direkt zu [*], ohne einen LLM-Aufruf zu verbrauchen, und der --watch-Modus (siehe unten) verarbeitet nur das, was sich tatsächlich geändert hat, statt jedes Mal das gesamte Verzeichnis.
Lokal ausführen
Erstellen Sie vom Repo-Root aus die virtuelle Umgebung und installieren Sie die Abhängigkeiten.
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.pyWenn Sie den Posteingang von Grund auf neu scannen möchten
Der Watcher führt eine kleine Statusdatei, sodass er nur neu hinzugefügte Lebensläufe bewertet. Wenn Sie den aktuellen Ordner erneut verarbeiten möchten, löschen Sie zuerst den Watcher-Status:
python matching_agent.py --reset-watchHäufige Verwendungsmuster
# 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 15Verwenden Sie beim Ausführen des Agenten das Python der Projekt-Venv, nicht das System-Python. In diesem Repo lautet der funktionierende Befehl typischerweise
./.venv/Scripts/python.exe matching_agent.pyunter Windows odersource .venv/bin/activate && python matching_agent.pyunter Unix-ähnlichen Shells.
Führen Sie einen der Server eigenständig aus, um direkt daran herumzutesten (praktisch mit dem MCP Inspector):
python filesystem_mcp_server.py
python notifications_mcp_server.pyDie Konfiguration erfolgt über Umgebungsvariablen – siehe ServerConfig.from_env() in filesystem_mcp_server.py:
Variable | Standard |
|
|
|
|
|
|
|
|
|
|
|
|
Testen
pytest tests/ -v14 Tests, zwei Ebenen:
Unit (
test_filesystem_mcp_server.py, größtenteils): Ruft Tool-Funktionen direkt gegen einetmp_path-Fixture auf – schnell, ohne Subprozess. Abgedeckt werden Erfolgspfade, die FehlercodesRESUME_NOT_FOUND/INVALID_PARAMSund die Teilfehlerberichterstattung vonbatch_process.Protokoll (
test_server_speaks_mcp_protocol_over_stdio): Startet den echten Server als Subprozess und steuert ihn mit dem offiziellenmcp-Client-SDK –tools/list,tools/call,resources/read– über echtes JSON-RPC 2.0, beweist also die Protokollebene, nicht nur das darunterliegende Python.Agent (
test_matching_agent.py): Der LLM-Aufruf wird durch einen deterministischen Fake (FakeStructuredModel) ersetzt, sodass diese keinen API-Schlüssel benötigen – sie prüfen die Graph-Verdrahtung, die Tool-Erkennung über mehrere Server, den Kurzschluss-Pfad bei keinen neuen Dateien und dass ein zweiter Durchlauf im--watch-Stil nur die neu eingetroffene Datei erneut verarbeitet, nicht das gesamte Verzeichnis.
Designentscheidungen
MCP-SDK auf mcp>=1.28,<2.0 festgelegt. Die v2-Linie des Python-SDKs wurde zusammen mit der MCP-Spezifikationsrevision vom 2026-07-28 veröffentlicht und benennt FastMCP in MCPServer um (jetzt unter mcp.server.mcpserver). v1.x ist das, wofür das aktuelle LangChain/LangGraph-MCP-Ökosystem gebaut und dokumentiert ist, daher pinnt dieses Projekt bewusst darauf – nicht zufällig. Es lohnt sich, dies zu überdenken, sobald langchain-mcp-adapters und die breitere Tutorial-Basis auf v2 aufholen.
stdio statt HTTP. Keine Netzwerkoberfläche, die abgesichert werden muss, keine Authentifizierung einzurichten, und es ist das, was MultiServerMCPClient für einen lokalen „Command"-Server erwartet. Der Kompromiss, der beim Bau bestätigt wurde: Jeder Tool-Aufruf öffnet eine neue Subprozess-Sitzung, anstatt eine wiederzuverwenden – in Ordnung für einen Demo-/CLI-Agenten, und der ehrliche Grund, warum eine latenzempfindliche Produktionsversion stattdessen auf einen langlebigen streamable-http-Server umsteigen würde.
Fehler sind strukturiertes JSON, kein Prosa. Jeder Fehler wirft ToolError mit einem JSON-Payload, das einen code im JSON-RPC-„Serverfehler"-Bereich (-32000..-32099) sowie ein maschinenlesbares error-Label trägt (RESUME_NOT_FOUND, DIRECTORY_NOT_FOUND, UNSUPPORTED_FILE_TYPE, EXTRACTION_FAILED, INVALID_PARAMS). Ende-zu-Ende gegen eine Live-Client-Sitzung bestätigt: Es erscheint als CallToolResult(isError=True, ...), und _call_tool() von matching_agent.py wirft es als MCPToolCallError mit intaktem Code erneut, anstatt dass ein Aufrufer eine Nachricht per String-Vergleich abgleichen muss.
watch_directory pollt; es pusht nicht. MCP-Tools sind Request/Response, daher ist dies ein Poll (eine JSON-Statusdatei mit Dateiname→mtime, die bei jedem Aufruf verglichen wird) und kein inotify/watchdog-Listener. Der --watch-Modus von matching_agent.py macht daraus etwas, das sich live anfühlt – ein Hintergrund-Listener, der über MCP-Ressourcen-Abonnements pusht, wäre der natürliche nächste Schritt und wird vom Protokoll unterstützt, ist hier aber außerhalb des Rahmens.
batch_process nimmt eine explizite Dateiliste, nicht nur ein Verzeichnis. Dadurch kann check_new_resumes → batch_extract nur das erneut verarbeiten, was watch_directory gerade gemeldet hat, statt jedes Mal den gesamten Ordner – die Nebenläufigkeit (asyncio.Semaphore(MAX_BATCH_CONCURRENCY)) macht „effizient" aus der Spezifikation tatsächlich wahr, wenn die Liste lang ist.
Die Umgebungsweitergabe ist explizit und kein Standard, den man überspringen kann. Ein echter Stolperstein beim Bau: Der stdio-Client von mcp erbt nicht die Umgebung des Elternprozesses – er startet Kind-Server mit einer minimalen Standardumgebung (nur PATH/HOME/TERM), direkt bestätigt gegen mcp.client.stdio.get_default_environment(). Ohne explizites env=dict(os.environ) in der Serverkonfiguration von matching_agent.py erreichen RESUME_DIRECTORY und Co. stillschweigend nie filesystem_mcp_server.py – der Agent läuft, findet die Tools problemlos und arbeitet einfach leise im falschen Verzeichnis. Wissenswert, bevor es Sie eine Debugging-Sitzung kostet.
Repo-Struktur
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