filesystem-mcp-server
Resume Matcher — MCP Edition
Las herramientas directas del sistema de archivos del agente de coincidencia de currículos, reemplazadas por un servidor MCP independiente, además de un agente LangGraph refactorizado para comunicarse con él (y un segundo servidor MCP) a través de un cliente MCP real en lugar de llamadas a funciones locales.
Objetivos de aprendizaje → qué hay en este repositorio
Objetivo | Dónde |
Entender el Protocolo de Contexto de Modelo |
|
Reemplazar herramientas personalizadas con servidores MCP | Cada operación de sistema de archivos del Hito 1 es ahora un |
Implementar interfaces de herramientas estandarizadas | Envoltura consistente |
Desplegar sistemas listos para producción | Configuración basada en variables de entorno, concurrencia limitada, manejo de fallos parciales, una corrección probada de reenvío de entorno, 14 pruebas que pasan en capas de unidad y protocolo |
Related MCP server: Filesystem MCP Server
Arquitectura
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")]Dos servidores MCP independientes, cada uno un proceso de sistema operativo separado, cada uno sin conocimiento del otro ni de LangGraph. El agente descubre sus herramientas al inicio (client.get_tools()) y las llama por nombre — ese es el punto central de la refactorización: filesystem_mcp_server.py podría ganar una nueva herramienta mañana y matching_agent.py no necesitaría un cambio de código.
Máquina de estados (interacción agente ↔ 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 llamando a watch_directory primero — antes de tocar cualquier otra cosa — es deliberado: una ejecución sin nada nuevo corta directamente a [*] sin gastar una llamada de LLM, y el modo --watch (ver más abajo) reprocesa solo lo que realmente cambió en lugar de todo el directorio cada vez.
Ejecutar localmente
Desde la raíz del repositorio, crea el entorno virtual e instala las dependencias.
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.pySi quieres volver a escanear la bandeja de entrada desde cero
El observador mantiene un pequeño archivo de estado para que solo puntúe currículos recién añadidos. Si quieres procesar la carpeta actual de nuevo, limpia primero el estado del observador:
python matching_agent.py --reset-watchPatrones de uso comunes
# 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 15Usa el Python del venv del proyecto, no el Python del sistema, al ejecutar el agente. En este repositorio, el comando que funciona es típicamente
./.venv/Scripts/python.exe matching_agent.pyen Windows osource .venv/bin/activate && python matching_agent.pyen shells tipo Unix.
Ejecuta cualquiera de los servidores de forma independiente para probarlo directamente (útil con el MCP Inspector):
python filesystem_mcp_server.py
python notifications_mcp_server.pyLa configuración está impulsada por variables de entorno — consulta ServerConfig.from_env() en filesystem_mcp_server.py:
Variable | Predeterminado |
|
|
|
|
|
|
|
|
|
|
|
|
Pruebas
pytest tests/ -v14 pruebas, dos capas:
Unidad (
test_filesystem_mcp_server.py, la mayor parte): llama a las funciones de herramienta directamente contra un fixturetmp_path— rápido, sin subproceso. Cubre rutas de éxito, los códigos de errorRESUME_NOT_FOUND/INVALID_PARAMS, y el informe de fallos parciales debatch_process.Protocolo (
test_server_speaks_mcp_protocol_over_stdio): lanza el servidor real como subproceso y lo maneja con el SDK oficial de clientemcp—tools/list,tools/call,resources/read— sobre JSON-RPC 2.0 real, por lo que demuestra la capa de protocolo, no solo el Python subyacente.Agente (
test_matching_agent.py): la llamada al LLM se reemplaza por un simulacro determinista (FakeStructuredModel) para que no necesiten clave API — están comprobando el cableado del grafo, el descubrimiento de herramientas de múltiples servidores, la ruta de cortocircuito cuando no hay archivos nuevos, y que una segunda pasada estilo--watchsolo reprocesa el archivo recién llegado, no todo el directorio.
Decisiones de diseño
SDK de MCP fijado a mcp>=1.28,<2.0. La línea v2 del SDK de Python se lanzó junto con la revisión de la especificación MCP del 2026-07-28 y renombra FastMCP a MCPServer (ahora en mcp.server.mcpserver). v1.x es sobre lo que está construido y documentado el ecosistema MCP actual de LangChain/LangGraph, así que este proyecto lo fija a propósito, no por accidente — vale la pena revisarlo una vez que langchain-mcp-adapters y la base de tutoriales más amplia se pongan al día con v2.
stdio sobre HTTP. Sin superficie de red que asegurar, sin autenticación que configurar, y es lo que MultiServerMCPClient espera para un servidor "comando" local. La compensación, confirmada al construir esto: cada llamada de herramienta abre una sesión de subproceso nueva en lugar de reutilizar una — está bien para un agente de demostración/CLI, y es la razón honesta por la que una versión de producción sensible a la latencia se movería a un servidor streamable-http de larga duración.
Los errores son JSON estructurado, no prosa. Cada fallo lanza ToolError con un payload JSON que lleva un code en el rango de "error de servidor" de JSON-RPC (-32000..-32099) más una etiqueta error legible por máquina (RESUME_NOT_FOUND, DIRECTORY_NOT_FOUND, UNSUPPORTED_FILE_TYPE, EXTRACTION_FAILED, INVALID_PARAMS). Confirmado de extremo a extremo contra una sesión de cliente en vivo: aparece como CallToolResult(isError=True, ...), y _call_tool() de matching_agent.py lo relanza como MCPToolCallError con el código intacto en lugar de que un llamador tenga que hacer coincidir cadenas en un mensaje.
watch_directory sondea; no empuja. Las herramientas MCP son de solicitud/respuesta, así que esto es un sondeo (un archivo de estado JSON de nombre de archivo→mtime, comparado en cada llamada) en lugar de un listener inotify/watchdog. El modo --watch de matching_agent.py es lo que convierte eso en algo que se siente en vivo — un listener en segundo plano que empuje a través de suscripciones de recursos MCP sería el siguiente paso natural y está soportado por el protocolo, solo que fuera del alcance aquí.
batch_process toma una lista de archivos explícita, no solo un directorio. Esto es lo que permite que check_new_resumes → batch_extract reprocese solo lo que watch_directory acaba de informar en lugar de toda la carpeta cada vez — la concurrencia (asyncio.Semaphore(MAX_BATCH_CONCURRENCY)) es lo que hace que "eficiente" en la especificación sea realmente cierto cuando esa lista es larga.
El reenvío de entorno es explícito, y no es un valor predeterminado que puedas omitir. Un problema real encontrado al construir esto: el cliente stdio de mcp no hereda el entorno del proceso padre — inicia servidores hijos con un entorno mínimo predeterminado (solo PATH/HOME/TERM), confirmado directamente contra mcp.client.stdio.get_default_environment(). Sin pasar env=dict(os.environ) explícitamente en la configuración del servidor de matching_agent.py, RESUME_DIRECTORY y compañía nunca llegan silenciosamente a filesystem_mcp_server.py — el agente se ejecuta, descubre herramientas correctamente, y simplemente opera en el directorio equivocado. Vale la pena saberlo antes de que te cueste una sesión de depuración.
Estructura del repositorio
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