RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Fredoline Eruo
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /Courses
  5. /MCP Server Implementation
  6. /Ch. 8
MCP Server Implementation

08. File System Server

Chapter 8 of 22 · 20 min
KEY INSIGHT

A file system MCP server requires careful permission scoping, path validation, and error handling to prevent unauthorized access while enabling useful operations. Building a file system MCP server demonstrates real-world integration challenges. This chapter covers implementation decisions that apply to most resource-intensive servers. **Security Foundation:** Never expose absolute paths. Establish a root directory that bounds all operations. ```python from pathlib import Path class FileSystemServer: def __init__(self, root_path: str): self.root = Path(root_path).resolve() # Verify root exists and is accessible if not self.root.exists(): raise ValueError(f"Root path does not exist: {self.root}") def _resolve_path(self, relative_path: str) -> Path: # Prevent path traversal attacks requested = (self.root / relative_path).resolve() if not str(requested).startswith(str(self.root)): raise PermissionError("Path outside root directory") return requested ``` **Resource Implementation:** ```python from mcp.types import Resource, ResourceTemplate @server.list_resources() async def list_resources() -> list[Resource]: return [ Resource( uri=f"fs://README.md", name="readme", description="Project README", mimeType="text/markdown" ), Resource( uri=f"fs://config.yaml", name="config", description="Application configuration", mimeType="application/yaml" ) ] @server.list_resource_templates() async def list_templates() -> list[ResourceTemplate]: return [ ResourceTemplate( uriTemplate="fs://{filepath}", name="file", description="Access files by path" ) ] @server.read_resource() async def read_resource(uri: str) -> str: path = self._resolve_path(uri.replace("fs://", "")) if path.is_dir(): return "\n".join(f.name for f in path.iterdir()) return path.read_text() ``` **Tool Implementation:** ```python @server.call_tool() async def call_tool(name: str, args: dict) -> str: match name: case "read_file": path = self._resolve_path(args["path"]) return path.read_text() case "write_file": path = self._resolve_path(args["path"]) path.parent.mkdir(parents=True, exist_ok=True) path.write_text(args["content"]) return f"Wrote {len(args['content'])} bytes to {args['path']}" case "list_directory": path = self._resolve_path(args["path"]) return "\n".join(f.name for f in path.iterdir()) case "file_exists": path = self._resolve_path(args["path"]) return "yes" if path.exists() else "no" ``` **Error Handling:** ```python @server.read_resource() async def read_resource(uri: str) -> str: try: path = self._resolve_path(uri.replace("fs://", "")) return path.read_text() except FileNotFoundError: raise ResourceError(f"File not found: {uri}") except PermissionError: raise ResourceError(f"Access denied: {uri}") except IsADirectoryError: raise ResourceError(f"Path is a directory: {uri}") ``` **Configuration Options:** ```python @dataclass class FileSystemConfig: root_path: str max_file_size: int = 1024 * 1024 # 1MB default allowed_extensions: list[str] | None = None write_enabled: bool = False ```

EXERCISE

Extend the file system server with: (1) support for binary file reading with base64 encoding, (2) a tool for searching file contents using grep-style patterns, (3) resource change notifications when files are modified.

← Chapter 7
Prompts in MCP
Chapter 9 →
Database Query Server