Filesystem MCP Server
README.md
# mcp-integration
MCP integration
> This repository **implements the assignment described below**. For build, run, and
> design details of the implementation, jump to the
> **[Implementation & Usage Guide](#implementation--usage-guide)** further down this file
> — all documentation lives in **[docs/](docs/)** (start at **[docs/README.md](docs/README.md)**):
> [docs/design/ARCHITECTURE.md](docs/design/ARCHITECTURE.md), [docs/design/HLD.md](docs/design/HLD.md),
> [docs/design/LLD.md](docs/design/LLD.md), [docs/project/PROJECT_STRUCTURE.md](docs/project/PROJECT_STRUCTURE.md),
> [docs/guides/DEMO_SCRIPT.md](docs/guides/DEMO_SCRIPT.md).
## Brief
### Learning Objectives
- Understand Model Context Protocol
- Replace custom tools with MCP servers
- Implement standardized tool interfaces
- Deploy production-ready systems
## Assignment Requirements
### Part A: MCP Server Implementation (50%)
Create `filesystem_mcp_server.py`:
- Convert File System Tools to MCP
- Implement MCP protocol specification
- Expose all Milestone 1 tools as MCP resources
- Add new MCP-specific capabilities:
- `watch_directory()` - Monitor for new resumes
- `batch_process()` - Handle multiple files efficiently
**MCP Server Features**
- JSON-RPC 2.0 compliant interface
- Proper error handling and status codes
- Resource discovery endpoints
- Configuration management
### Part B: Agent Refactoring (30%)
Update `matching_agent.py`:
- **Replace Custom Tools**
- Remove direct file system tools
- Connect to MCP server via client
- Maintain same functionality with cleaner architecture
**Multi-MCP Integration (Bonus)**
- Connect to additional MCP servers (e.g., web search, database)
- Demonstrate agent using multiple MCP resources
## Submission Guidelines
### Deliverables
- MCP-based filesystem server implementation (`filesystem_mcp_server.py`)
- Refactored LangGraph agent with MCP client integration (`matching_agent.py`)
- JSON-RPC 2.0 compliant MCP server with resource discovery
- Implementation of `watch_directory()` and `batch_process()` capabilities
- State machine/workflow diagram of agent ↔ MCP interaction
- Test scenarios demonstrating MCP resource usage and agent workflow
- Demo video (5–6 minutes) showing MCP server, agent integration, and end-to-end execution
---
---
# Implementation & Usage Guide
> Everything below documents **how this repository fulfils the assignment above** —
> architecture, how to install/run, the MCP surface, configuration, testing, and how
> prior feedback was incorporated.
An **enterprise, production-oriented** implementation of an MCP-based resume/profile
matching system, delivered in two parts:
- **Part A — MCP Server** (`filesystem_mcp_server.py`): a JSON-RPC 2.0 **Model Context
Protocol** server that exposes the Milestone-1 filesystem tools as MCP tools, adds the
MCP-specific `watch_directory` and `batch_process` capabilities, and publishes resume
documents as discoverable MCP **resources**.
- **Part B — Matching Agent** (`matching_agent.py`): a **LangGraph** agent that connects
to the MCP server(s) **as a client** (no direct filesystem access), retrieves candidate
evidence through a **RAG** pipeline, and produces a ranked, justified shortlist using
**Claude** — with durable state, retries, and full observability.
> **Domain.** This continues the resume/profile-matching line from the prior milestones
> (File System Tools → RAG Profile Matching → Agentic Profile Matching). Resumes land in a
> directory; the agent matches candidates to a job description.
---
## Architecture at a glance
```
┌──────────────────────────────────────────────┐
│ Matching Agent (Part B) │
Job description ─────▶ │ LangGraph state machine │
Resumes dir │ load_job → discover → ingest → retrieve → │
│ rank(Claude) → report │
│ │
│ RAG pipeline ┌──────────────┐ │
│ (extract → │ Vector store │ (external, │
│ chunk → │ Chroma/disk │ on-disk) │
│ embed) ──────▶└──────────────┘ │
│ ▲ │
│ │ MCP client (langchain-mcp-adapters) │
└────────┼───────────────────────────────────────┘
│ JSON-RPC 2.0 over stdio / HTTP
┌────────┴───────────────────────────────────────┐
│ MCP Server (Part A) │
│ FastMCP · tools + resources · sandboxed FS │
│ read_file · write_file · list_directory · │
│ file_exists · get_file_metadata · search_files│
│ watch_directory · batch_process · metrics │
└────────────────────────────────────────────────┘
│
┌────────┴────────┐
│ Sandbox (data/) │ resumes/ jobs/ reports/
└─────────────────┘
```
Full detail: **[docs/design/ARCHITECTURE.md](docs/design/ARCHITECTURE.md)** · **[docs/design/HLD.md](docs/design/HLD.md)** ·
**[docs/design/LLD.md](docs/design/LLD.md)** · **[docs/project/PROJECT_STRUCTURE.md](docs/project/PROJECT_STRUCTURE.md)** ·
workflow state machine: **[docs/diagrams/workflow.md](docs/diagrams/workflow.md)**.
---
## Quickstart
### 1. Install
Always install into a **project virtualenv** (keeps the global environment clean and
avoids unrelated global pytest-plugin clashes):
```bash
python -m venv .venv
. .venv/Scripts/activate # Windows PowerShell: .venv\Scripts\Activate.ps1
python -m pip install -U pip
pip install -e ".[dev]" # base + dev tools — light, no torch; offline path works
cp .env.example .env # then edit as needed
```
The base install is deliberately small (no `torch`/`chromadb`). For the **recommended
production configuration** — local `sentence-transformers` embeddings and a persistent
Chroma store — add the extras:
```bash
pip install -e ".[full]" # sentence-transformers + chromadb
# or individually: pip install -e ".[local]" / pip install -e ".[chroma]"
```
Without the extras the system runs on the offline path (hash embedder + disk store) and
logs a one-line hint pointing at `.[local]`.
> **Installing from a private index (e.g. AWS CodeArtifact):** pip uses whatever
> `index-url` your `pip config` / environment defines — no special flags needed. Just
> ensure your CodeArtifact auth token is current (`aws codeartifact login --tool pip …`)
> before installing. To pin the public index instead:
> `pip install -e ".[dev]" --index-url https://pypi.org/simple/`.
### 2. Seed sample data (optional — samples are committed)
```bash
python scripts/seed_data.py --root ./data
```
### 3a. Run the agent (recommended — it launches the MCP server for you)
The agent, in `mcp` gateway mode, **spawns the Part A server as a subprocess** and talks
to it over MCP. This is the full Part A + Part B path:
```bash
python matching_agent.py --job jobs/backend_engineer.md --resumes-dir resumes --top-n 3
```
Set `ANTHROPIC_API_KEY` for Claude-grade reasoning. **Without a key it runs fully
offline** (deterministic stub reasoner + local/hash embeddings), so the whole system is
demonstrable with zero external dependencies.
### 3b. Run the MCP server standalone
```bash
python filesystem_mcp_server.py # stdio (for MCP clients)
PM_MCP__TRANSPORT=streamable-http python filesystem_mcp_server.py # networked
```
### Fully-offline run (no API key, no model downloads, no network)
```bash
PM_EMBEDDING__PROVIDER=hash PM_VECTOR_STORE__PROVIDER=disk PM_LLM__FORCE_STUB=true \
python matching_agent.py --job jobs/backend_engineer.md --resumes-dir resumes --top-n 3
```
---
## MCP surface (Part A)
### Tools
| Tool | Purpose | New? |
|------|---------|------|
| `read_file` | Read a text file from the sandbox | Milestone 1 |
| `write_file` | Write a file (creates parents) | Milestone 1 |
| `list_directory` | List entries + metadata | Milestone 1 |
| `file_exists` | Presence check (never raises on escape) | Milestone 1 |
| `get_file_metadata` | size / type / mtime | Milestone 1 |
| `search_files` | Glob search (`*.pdf`, …) | Milestone 1 |
| `watch_directory` | **Monitor for new resumes** (blocks until added / timeout) | **New (MCP-specific)** |
| `batch_process` | **Process many files** (read / metadata / exists / extract_text) with per-item error capture | **New (MCP-specific)** |
| `server_metrics` | In-process metrics snapshot | Ops |
Every tool returns a stable contract: `{"ok": true, "result": …}` or
`{"ok": false, "error": {"code", "message", "kind"}}` — JSON-RPC error codes mapped in
`errors.py`, so the client branches programmatically instead of parsing prose.
### Resources (discovery)
| URI | Description |
|-----|-------------|
| `resumes://index` | JSON index of all resume documents in the sandbox |
| `resume://{path}` | Text content of one resume |
| `config://server` | Non-sensitive server config for capability discovery |
---
## Configuration
All configuration is typed (`src/profile_matcher/config.py`, pydantic-settings) and driven
by `PM_`-prefixed env vars with `__` nesting. See **[.env.example](.env.example)** for the
full list. Highlights:
| Variable | Default | Meaning |
|----------|---------|---------|
| `PM_LLM__MODEL` | `claude-opus-4-8` | Claude model for ranking |
| `PM_EMBEDDING__PROVIDER` | `local` | `local` / `voyage` / `openai` / `hash` |
| `PM_VECTOR_STORE__PROVIDER` | `chroma` | `chroma` (persistent) / `disk` |
| `PM_MCP__SANDBOX_ROOT` | `./data` | Filesystem sandbox root |
| `PM_MCP__TRANSPORT` | `stdio` | `stdio` / `streamable-http` / `sse` |
| `PM_CHECKPOINT__BACKEND` | `sqlite` | Durable agent state backend |
---
## Testing
```bash
pip install -e ".[dev]"
pytest # unit + agent tests (offline)
pytest -m integration # real MCP subprocess end-to-end
```
> **Note (shared machines):** if an unrelated global pytest plugin breaks collection,
> isolate the run: `PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 pytest -p pytest_asyncio.plugin`.
The suite is fully offline (hash embedder + disk store + stub reasoner). Current status:
**38 passing**.
Run the embedding ablation study (feedback A):
```bash
python scripts/ablation.py --providers hash # offline
python scripts/ablation.py --providers hash local # add sentence-transformers
```
---
## Assignment mapping
| Requirement | Where |
|-------------|-------|
| **Part A** — `filesystem_mcp_server.py` | repo root → `src/profile_matcher/mcp_server/` |
| Convert FS tools to MCP; JSON-RPC 2.0 | `mcp_server/server.py` (FastMCP), `errors.py` (JSON-RPC codes) |
| Expose Milestone-1 tools as MCP resources/tools | `server.py` tools + resources |
| `watch_directory()` | `server.py::watch_directory` (+ `_await_new_files`) |
| `batch_process()` | `server.py::batch_process` (+ `_run_single`) |
| Error handling / status codes | `errors.py`, `{ok,error}` tool contract |
| Resource discovery endpoints | `resumes://index`, `resume://{path}`, `config://server` |
| Configuration management | `config.py` (pydantic-settings), `.env.example` |
| **Part B** — `matching_agent.py` | repo root → `src/profile_matcher/agent/` |
| Remove direct FS tools; connect via MCP client | `agent/gateway.py::McpClientGateway` |
| Same functionality, cleaner architecture | `agent/graph.py` state machine + dependency inversion |
| **Bonus** — Multi-MCP integration | `gateway.py` `extra_servers` (see ARCHITECTURE.md) |
| **Deliverables** — JSON-RPC 2.0 server w/ discovery | Part A |
| State machine / workflow diagram | [docs/diagrams/workflow.md](docs/diagrams/workflow.md) |
| Test scenarios | `tests/` (unit + integration) |
| Docs (ARCHITECTURE/HLD/LLD/PLAN/STRUCTURE) | see [Documentation](#documentation) |
| Demo video (5–6 min) | see [docs/guides/DEMO_SCRIPT.md](docs/guides/DEMO_SCRIPT.md) for the walkthrough script |
---
## How prior feedback was addressed
- **RAG (extractor & embedding validation + provider trade-offs).** Extractors and
embedders are pluggable behind protocols; `scripts/ablation.py` measures ranking
quality (top-1, MRR, separation, cost) across providers, written up in
**[docs/guides/ABLATION.md](docs/guides/ABLATION.md)**.
- **Agentic (state persistence, error handling, observability).** Durable SQLite
checkpointing; per-node structured error capture with graceful degradation; structured
logging, tracing spans, metrics, and scoped retries with backoff — see
**[docs/guides/OBSERVABILITY.md](docs/guides/OBSERVABILITY.md)**.
---
## Documentation
All documentation lives under **[docs/](docs/)**; **[docs/README.md](docs/README.md)** is the hub.
| Doc | Contents |
|-----|----------|
| [docs/README.md](docs/README.md) | Documentation index / hub (audience + reading order) |
| [docs/design/ARCHITECTURE.md](docs/design/ARCHITECTURE.md) | System architecture, components, data flow, decisions |
| [docs/design/HLD.md](docs/design/HLD.md) | High-level design: context, containers, sequences |
| [docs/design/LLD.md](docs/design/LLD.md) | Low-level design: modules, classes, contracts |
| [docs/project/IMPLEMENTATION_PLAN.md](docs/project/IMPLEMENTATION_PLAN.md) | Phased build plan & milestones |
| [docs/project/PROJECT_STRUCTURE.md](docs/project/PROJECT_STRUCTURE.md) | Full package/file hierarchy |
| [docs/guides/ABLATION.md](docs/guides/ABLATION.md) | Extractor/embedding ablation & trade-offs |
| [docs/guides/OBSERVABILITY.md](docs/guides/OBSERVABILITY.md) | Logging, tracing, metrics, retries |
| [docs/diagrams/workflow.md](docs/diagrams/workflow.md) | Agent ↔ MCP workflow state machine |
| [docs/guides/DEMO_SCRIPT.md](docs/guides/DEMO_SCRIPT.md) | 5–6 min demo walkthrough |
---
## License
Proprietary — coursework deliverable.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues