Skip to main content
Glama
eeb16027

Filesystem MCP Server

by eeb16027
README.md
# MCP Integration — Submission Package

This covers the "MCP integration" assignment for the Backend AI Track:
Part A (MCP server), Part B (agent refactor + bonus multi-MCP), and the
required diagram/tests/demo materials.

> **Assumption stated up front:** the assignment references "Milestone 1
> tools." I don't have your actual Milestone 1 code, so I've assumed it was
> a basic file-reading toolkit (`list_files`, `read_file`, `search_files`)
> for a resume-matching agent — matching the `matching_agent.py` /
> `watch_directory()` (monitor for new resumes) hints in your brief. If your
> real Milestone 1 tools differ, swap the tool bodies in
> `filesystem_mcp_server.py` — the MCP wrapping pattern stays the same.

---

## Files in this package

| File | Deliverable it satisfies |
|---|---|
| `filesystem_mcp_server.py` | Part A: MCP server, JSON-RPC 2.0 (via FastMCP), error handling, resource discovery, config mgmt, `watch_directory()`, `batch_process()` |
| `matching_agent.py` | Part B: LangGraph agent refactored to use an MCP client instead of direct file tools, + bonus multi-MCP hook |
| `config.json` | Configuration management |
| `test_scenarios.py` | Test scenarios demonstrating MCP resource usage and agent workflow |
| `README.md` (this file) | Workflow diagram + demo video script + setup instructions |

---

## 1. Setup

```bash
python -m venv .venv
source .venv/bin/activate      # Windows: .venv\Scripts\activate
pip install -r requirements.txt
```

Copy `.env.example` to `.env` and add your OpenAI key (only needed for
`matching_agent.py`'s scoring step — `filesystem_mcp_server.py` and
`test_scenarios.py` don't need any API key):
```bash
cp .env.example .env
```

Three sample resumes are already included under `resumes/incoming/` so the
project runs out of the box with no extra setup.

Run the tests:
```bash
pytest test_scenarios.py -v
```

Run the agent end-to-end (this spins up the MCP server itself as a
subprocess via stdio, so you don't start it separately):
```bash
python matching_agent.py
```

---

## 2. State Machine / Workflow Diagram (Agent ↔ MCP Interaction)

```mermaid
stateDiagram-v2
    [*] --> StartWatch

    StartWatch: Agent calls watch_directory() via MCP client
    StartWatch --> ScanDirectory: MCP server begins polling "incoming/"

    ScanDirectory: Agent calls list_files() via MCP client
    ScanDirectory --> ReadResumes: MCP server returns file metadata (JSON)

    ReadResumes: Agent calls batch_process() via MCP client
    ReadResumes --> MatchAgainstJD: MCP server returns file contents (JSON)

    MatchAgainstJD: Agent scores each resume against the job description (LLM call, no MCP)
    MatchAgainstJD --> [*]: Return ranked matches + log

    note right of StartWatch
        Every arrow crossing into the MCP
        server is a JSON-RPC 2.0 request;
        every arrow back is a JSON-RPC
        2.0 response with status/code/data.
    end note
```

**How to read this:** the agent (LangGraph state machine) never touches the
filesystem directly. Every box that says "via MCP client" is a JSON-RPC 2.0
call across the process boundary to `filesystem_mcp_server.py`, which does
the actual file I/O and returns a structured JSON result.

---

## 3. Test Scenarios Summary (see `test_scenarios.py` for full code)

1. Listing an empty directory succeeds with an empty file list.
2. Reading a missing file returns a proper `404` error envelope.
3. Reading an existing resume returns its content.
4. Keyword search only returns files that actually contain the keyword.
5. `batch_process()` handles a mix of valid + missing files gracefully (partial success).
6. `batch_process()` rejects oversized batches with a `413` error instead of overloading.
7. `watch_directory()` + `get_new_files()` detects a resume dropped into the folder mid-run.
8. `list_capabilities()` (resource discovery) returns every registered tool.
9. Path traversal outside the base directory (e.g. `../../etc/passwd`) is blocked with `403`.

---

## 4. Demo Video Script (5–6 minutes)

**0:00–0:45 — Problem & context**
- Briefly explain: previously, `matching_agent.py` called filesystem functions directly (Milestone 1). Show the old direct-call code for contrast.

**0:45–2:00 — MCP server walkthrough**
- Open `filesystem_mcp_server.py`. Point out:
  - The Milestone 1 tools now wrapped as `@mcp.tool()`.
  - The two new capabilities: `watch_directory()` and `batch_process()`.
  - Error handling (`_error()` envelope with status codes) and `list_capabilities()` for resource discovery.
  - `config.json` for configuration management.

**2:00–3:30 — Agent refactor walkthrough**
- Open `matching_agent.py`. Point out:
  - `MultiServerMCPClient` connecting to the filesystem server.
  - No direct `os`/`pathlib` calls anywhere in the agent file.
  - The LangGraph nodes (`start_watch` → `scan_directory` → `read_resumes` → `match_against_jd`) each calling an MCP tool.
  - The commented bonus block showing how a second MCP server (e.g. web search) would be added.

**3:30–4:30 — Live run**
- Run `pytest test_scenarios.py -v` and show tests passing.
- Run `python matching_agent.py`, showing the log output: watch started → directory scanned → resumes batch-read → scores returned.
- Drop a new resume file into `resumes/incoming/` during the run to show `watch_directory()` picking it up live.

**4:30–5:30 — Wrap-up**
- Show the state diagram from this README and narrate the JSON-RPC round trips.
- One sentence on why this is "production-ready": path-traversal protection, per-file error isolation in batch calls, and configuration externalized to `config.json`.

---

## 5. Deliverables Checklist

- [x] `filesystem_mcp_server.py` — MCP-based filesystem server
- [x] `matching_agent.py` — refactored LangGraph agent with MCP client integration
- [x] JSON-RPC 2.0 compliant server (via FastMCP stdio transport) with `list_capabilities()` resource discovery
- [x] `watch_directory()` and `batch_process()` implemented
- [x] State machine / workflow diagram (above, Mermaid)
- [x] Test scenarios (`test_scenarios.py`)
- [ ] Demo video (5–6 min) — record using the script in Section 4
- [ ] Multi-MCP bonus — uncomment and point the `websearch` entry in `matching_agent.py` at a second real MCP server if you want the bonus credit