Skip to main content
Glama
Afreed1607

Filesystem MCP Server

by Afreed1607

MCP Resume Matching

A LangGraph resume-matching workflow that accesses resumes exclusively through an MCP stdio server. The official MCP Python SDK owns MCP initialization, capability discovery, and JSON-RPC 2.0 transport; application code does not implement JSON-RPC itself.

Architecture

LangGraph matching agent
        |
        v
Filesystem MCP client
        |
        | MCP / JSON-RPC 2.0 / stdio
        v
Filesystem MCP server
        |
        v
Filesystem service
        |
        v
Configured resume directory

See docs/architecture.md for the full component and workflow diagrams.

Related MCP server: filesystem-mcp-server

Install

Python 3.11 or newer is required.

python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[test]"

Configuration

Variable

Default

Meaning

RESUME_DIRECTORY

./resumes

Allowed root directory for resume files.

RESUME_EXTENSIONS

.txt,.md,.pdf,.docx

Comma-separated extension allowlist. Values may omit the leading period.

MCP_PYTHON

Active Python interpreter

Optional Python executable used to start the MCP server subprocess.

For example:

$env:RESUME_DIRECTORY = "$PWD\resumes"
$env:RESUME_EXTENSIONS = ".txt,.md,.pdf,.docx"

MCP Tools

Tool

Purpose

list_files()

Lists supported resume paths relative to the configured root.

read_file(file)

Reads one allowed resume.

search_files(query)

Searches allowed resume text case-insensitively.

parse_resume(file)

Returns basic name, email, skills, and extracted text.

batch_process(files, max_concurrency=4)

Parses unique inputs concurrently with failure isolation.

watch_directory(known_files=None)

Performs one bounded polling snapshot for newly visible resumes.

Tool input schemas are generated from the Python type annotations by FastMCP. Domain failures include an error type and actionable message; the client raises a contextual MCPToolError for those failures.

MCP Resources

Resume text is also available through the parameterized resource URI:

resume://<filename>

For example, resume://candidate.txt returns the text for candidate.txt. This is a resource template, so MCP exposes it through resources/templates/list as resume://{file}; clients then read a concrete URI through resources/read. It applies the same root, extension, traversal, and symlink-escape checks as read_file.

Running the MCP Server

The server uses stdio and is normally launched by the client. To run it for MCP Inspector or another MCP host:

python filesystem_mcp_server.py

Do not type plain text into its terminal: it expects MCP JSON-RPC messages from its host.

Running the Agent

$env:RESUME_DIRECTORY = "$PWD\resumes"
python matching_agent.py

The agent starts and closes its own MCP subprocess, discovers required tools, batches the available resumes, and ranks them with the existing deterministic matching logic.

Batch Processing

batch_process accepts only relative paths. It keeps the first occurrence of duplicates, preserves first-seen order, uses bounded worker concurrency, and continues after a missing, unsupported, or malformed file.

{
  "files": ["alice.txt", "missing.txt", "alice.txt"],
  "max_concurrency": 4
}

Its result includes requested, duplicates_ignored, processed, successful, failed, and ordered per-file results.

Directory Watching

watch_directory is deliberately a single, stateless polling call rather than an unbounded MCP request or background worker. Call it once, retain known_files, then submit that list on the next call:

{"known_files": ["alice.txt", "bob.md"]}

It returns new_files and the refreshed known_files. Unsupported files are excluded. A missing or unavailable configured directory yields a structured error response instead of blocking indefinitely. The legacy files and known keys are retained as aliases for older callers.

Error Handling and Security

The filesystem service is the sole authority for filesystem access. It rejects absolute paths, .. traversal, paths resolving through a symlink outside the configured root, and extensions outside the configured allowlist. It exposes no arbitrary file read capability. Batch operations isolate expected per-file errors while unexpected errors are logged and represented in that file's result.

MCP connection, tool, and resource errors preserve the tool/resource name and diagnostic context. The service logs detailed operational failures but does not return absolute internal paths as part of file-read errors.

Testing

python -m pytest

The deterministic suite uses temporary directories and covers service behavior, filesystem boundaries, batch success/failure/duplicates/invalid input, bounded watching, MCP stdio startup and initialization, tool/resource discovery and reads, MCP error propagation, agent-to-MCP integration, and end-to-end ranking.

Demo Walkthrough (6 minutes)

Time

Demonstration

0:00–0:45

Explain the problem and show the architecture diagram.

0:45–1:45

Open filesystem_mcp_server.py; show the six tools and resume://{file} resource template.

1:45–2:30

Use an MCP host/Inspector to initialize the server and discover tools and resource templates.

2:30–3:30

Open matching_agent.py and mcp_client.py; show discovery, lifecycle management, and no direct filesystem import.

3:30–4:30

Run python matching_agent.py with two sample resumes and rank candidates for a job description.

4:30–5:15

Demonstrate batch_process with a duplicate/missing input, then poll watch_directory after adding a resume.

5:15–6:00

Run python -m pytest and revisit the architecture/state diagrams.

Limitation

The repository's existing matching policy is deterministic token-overlap ranking. This MCP refactor preserves that existing behavior; it does not introduce an external LLM or a new paid model dependency.

Related MCP Connectors

Related MCP Servers