DEV Community

gentic news
gentic news

Posted on • Originally published at gentic.news

Build a Zero-Dependency MCP Server

Build a zero-dependency MCP server in 50 lines of Python to give Claude Code direct file access. Register it in claude.json and skip SDK bloat.

The Problem: Claude Code Can't See Your Files

Claude Code is powerful, but it has a blind spot: it can't directly read or write arbitrary files on your system unless you explicitly pass them in the conversation or use its built-in file tools. For developers working with large codebases, configuration files, or data files scattered across directories, this creates friction.

You could install a heavy MCP SDK or use an existing file server, but sometimes you just want something lightweight, auditable, and dependency-free.

What Changed — The Zero-Dependency Approach

A developer recently published a walkthrough of building a Model Context Protocol (MCP) server using only Python's standard library — no pip install, no SDKs, no frameworks. The result: a ~50-line server that exposes read_file and write_file tools to any MCP-compatible client, including Claude Code.

The Model Context Protocol (MCP), introduced by Anthropic in November 2024, standardizes how AI models connect to external tools and data. This server implements the JSON-RPC-based protocol directly over stdin/stdout, which is exactly how Claude Code communicates with MCP servers.

What It Means For You

If you've ever been frustrated that Claude Code can't access a config file in /etc/ or a data file in /data/, this is your solution. You get:

  • No dependencies — runs on any Python 3.6+ installation
  • Full control — you write exactly what tools to expose
  • Security — you control the file paths and permissions
  • Zero bloat — no SDK updates or version conflicts

This is particularly useful for CI/CD pipelines, Docker containers, or any environment where you can't or won't install extra packages.

Try It Now — Build Your Own File Server

Step 1: The Server Code

Create a file called file_server.py:

#!/usr/bin/env python3
"""Zero-dependency MCP server for file read/write."""
import json
import sys
import os

def read_file(path):
    with open(path, 'r') as f:
        return f.read()

def write_file(path, content):
    os.makedirs(os.path.dirname(path), exist_ok=True)
    with open(path, 'w') as f:
        f.write(content)
    return "ok"

def handle_request(request):
    method = request.get("method")
    params = request.get("params", {})
    if method == "list_tools":
        return {
            "tools": [{
                "name": "read_file",
                "description": "Read a file from the filesystem",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "path": {"type": "string"}
                    },
                    "required": ["path"]
                }
            }, {
                "name": "write_file",
                "description": "Write content to a file",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "path": {"type": "string"},
                        "content": {"type": "string"}
                    },
                    "required": ["path", "content"]
                }
            }]
        }
    elif method == "call_tool":
        name = params["name"]
        args = params["arguments"]
        if name == "read_file":
            result = read_file(args["path"])
        elif name == "write_file":
            result = write_file(args["path"], args["content"])
        else:
            return {"error": f"Unknown tool: {name}"}
        return {"content": [{"type": "text", "text": str(result)}]}
    return {"error": f"Unknown method: {method}"}

def main():
    for line in sys.stdin:
        request = json.loads(line)
        response = handle_request(request)
        sys.stdout.write(json.dumps(response) + "\n")
        sys.stdout.flush()

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

Step 2: Register with Claude Code

Add this server to your claude.json configuration:

{
  "mcpServers": {
    "file-access": {
      "command": "python3",
      "args": ["/path/to/file_server.py"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Use It

Restart Claude Code. Now you can ask it to read or write files directly:

"Read /etc/hosts and tell me what entries exist"
"Write a new config file at /data/config.json with these settings..."

Claude Code will call your MCP server's tools automatically.

Why This Matters for Claude Code Users

The MCP ecosystem is growing fast — Anthropic's protocol is now used by Claude Code, GitHub Copilot, and others. But you don't need to wait for someone else to build the server you need. With ~50 lines of Python, you can create custom tools that give Claude Code exactly the capabilities your workflow demands.

This approach scales: add tools for database queries, API calls, or even custom business logic. Each tool is just a function registered in the list_tools response.

Security Note

This server has no path sanitization. In production, add checks to restrict access to specific directories or file types. For example:

def read_file(path):
    allowed_prefix = "/home/user/projects/"
    if not path.startswith(allowed_prefix):
        raise PermissionError(f"Access denied: {path}")
    with open(path, 'r') as f:
        return f.read()
Enter fullscreen mode Exit fullscreen mode

The Takeaway

You don't need a heavy SDK to extend Claude Code. The Model Context Protocol is simple enough to implement from scratch. Build exactly the tools you need, with zero dependencies, and keep your workflow lean.


Source: news.google.com


Originally published on gentic.news

Top comments (0)