filesystem_mcp_server
by RAJPUTDEE
README.md
# MCP Integration
Converts the file system tools from the **LLM-Powered File System Assistant**
milestone into a standards-compliant **MCP server**, and refactors the
**Agentic Profile Matching** LangGraph agent to use those tools through an
MCP client instead of a direct Python import.
See [`state_diagram.md`](state_diagram.md) for the full process topology and
LangGraph flow.
## Part A — `filesystem_mcp_server.py`
Built on the official MCP Python SDK (`FastMCP`), so JSON-RPC 2.0 framing,
capability negotiation, and request/response dispatch come from the SDK; this
file supplies the tool logic, validation, and error semantics.
**Tools** (the original four, ported from `fs_tools.py`, plus two new ones):
| Tool | Purpose |
|---|---|
| `read_file(filepath)` | Extract text from `.txt` / `.pdf` / `.docx` |
| `list_files(directory, extension=None)` | List files, optional extension filter |
| `write_file(filepath, content)` | Write text, creating parent directories |
| `search_in_file(filepath, keyword)` | Case-insensitive keyword search with line context |
| `watch_directory(directory)` | **New.** Polls a directory; first call baselines it, every later call reports files new/modified since the previous call |
| `batch_process(filepaths, operation, keyword=None)` | **New.** Runs `read` / `search` / `metadata` over many files in a single MCP round trip, capped at `MCP_BATCH_MAX_FILES` |
**Resources** (discoverable without invoking a tool first):
| Resource URI | Returns |
|---|---|
| `roots://list` | Every directory the server is allowed to touch |
| `files://{root_alias}` | Files inside one allowed root |
| `file://{root_alias}/{filename}` | One file's content |
**Error handling**: every tool returns `{"success": false, "error_code": "...", "error": "..."}` on failure (`NOT_FOUND`, `PERMISSION_DENIED`, `EMPTY_FILE`, `FILE_TOO_LARGE`, `UNSUPPORTED_TYPE`, `MISSING_DEPENDENCY`, `INVALID_PATH`, `INTERNAL_ERROR`) instead of a bare exception, so a client can branch on failure type.
**Configuration** (`mcp_config.py`, overridable via env vars):
`MCP_MAX_FILE_SIZE_BYTES` (100 KB), `MCP_CONTENT_CHAR_LIMIT` (3000),
`MCP_SEARCH_MATCH_CAP` (10), `MCP_BATCH_MAX_FILES` (50). Every path a tool
touches is resolved and confined to `CONFIG.allowed_roots` (this project's
`resumes/`/`data/` plus the sibling milestone projects' resume folders) —
new relative to the original `fs_tools.py`, which trusted its caller; it
matters more once any MCP client can reach the server.
## Part B — `matching_agent.py`
Same LangGraph pipeline as the earlier milestone
(`parse_jd → extract_requirements → search_resumes → rank_candidates → generate_report → human_feedback`),
but it no longer imports file tools directly. It opens a `MultiServerMCPClient`
(`mcp_client.py`) that spawns `filesystem_mcp_server.py` as a stdio subprocess
and calls its tools for every file operation — loading the resume corpus via
`list_files` + `batch_process`, and saving reports via `write_file`.
Everything else — skill/requirement extraction, scoring, comparison,
explanation, interview questions, multi-round screening — is unchanged
in-memory logic and needed no MCP involvement.
### Bonus: multi-MCP integration
The agent also connects to `candidate_db_mcp_server.py`, a second MCP server
(SQLite-backed) that persists every ranked candidate's verdict after each
report. Ask the agent `history for <candidate name>` to query it back through
`get_candidate_history`. This is deliberately a *separate* server rather than
more tools on the filesystem server — it owns a different kind of resource
(database rows, not files), and in a real deployment could run on a different
host entirely.
## Setup
```bash
python -m venv .venv
.venv\Scripts\activate # Windows
pip install -r requirements.txt
```
Optional environment variables (same as the earlier milestone):
```powershell
$env:USE_EXTERNAL_RAG = "1" # use the ChromaDB index from RAG-Based-Profile-Matching instead of the built-in fallback
$env:USE_GROQ = "1" # Groq-generated interview questions
$env:GROQ_API_KEY = "your_key_here"
```
## Running
```bash
python matching_agent.py
```
Paste a job description (blank line to submit). Follow-up queries: compare
candidates, explain rankings, generate interview questions, `history for
<name>`, add must-haves, next round.
You can also run either MCP server standalone for manual inspection:
```bash
python filesystem_mcp_server.py
python candidate_db_mcp_server.py
# or, with the MCP Inspector:
mcp dev filesystem_mcp_server.py
```
## Tests
```bash
python test_scenarios.py
```
9/9 scenarios: the original 7 conversation flows (basic match, natural
language skill filter, compare, explain, refine requirements, multi-round,
interview questions) plus 2 new ones exercising MCP resource discovery /
`watch_directory()`, and `batch_process()` combined with the multi-MCP
screening-history round trip.
## Project structure
```
MCP Integration/
├── filesystem_mcp_server.py # Part A — MCP server
├── mcp_config.py # Server configuration (allowed roots, limits)
├── candidate_db_mcp_server.py # Bonus — second MCP server (SQLite)
├── mcp_client.py # MultiServerMCPClient used by the agent
├── matching_agent.py # Part B — LangGraph agent, MCP client
├── test_scenarios.py # 9 test scenarios
├── state_diagram.md # Process topology + LangGraph flow
├── resumes/ # Sample resumes for standalone server testing
├── data/ # Generated: latest_match_report.txt, screening_history.db
└── requirements.txt
```
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues