How to Build and Connect a Custom Model Context Protocol (MCP) Server in 5 Minutes
MCP & Agents(Updated )

How to Build and Connect a Custom Model Context Protocol (MCP) Server in 5 Minutes

Minimal Python FastMCP Server Implementation

The Model Context Protocol (MCP) is an open JSON-RPC standard that enables AI assistants to execute local tools and query databases securely.

To build and run an MCP server in Python right now, install FastMCP and the official CLI inspector:

pip install "mcp[cli]>=1.2.0" "fastmcp>=0.4.0"

Create server.py:

from fastmcp import FastMCP
import shutil

mcp = FastMCP("SystemUtilities")

@mcp.tool()
def get_disk_usage(path: str = "/") -> str:
    """Return disk usage statistics for the given filesystem path."""
    total, used, free = shutil.disk_usage(path)
    return f"Total: {total // (2**30)}GB | Used: {used // (2**30)}GB | Free: {free // (2**30)}GB"

if __name__ == "__main__":
    mcp.run()

Run and test the server immediately in your terminal inspector:

mcp dev server.py

1. Connecting Your MCP Server to AI Clients

Once your server runs locally, register it with your primary AI coding assistant by specifying the absolute path to your Python interpreter and server file.

Configuration for Claude Code and Claude Desktop

Add this configuration block to ~/.claude/mcp.json or claude_desktop_config.json:

{
  "mcpServers": {
    "system-utils": {
      "command": "python3",
      "args": ["/home/user/scripts/server.py"]
    }
  }
}

Configuration for Cursor and Antigravity

In your project root or global settings (.cursor/mcp.json or mcp_config.json):

{
  "mcpServers": {
    "system-utils": {
      "type": "stdio",
      "command": "python3",
      "args": ["/home/user/scripts/server.py"]
    }
  }
}

If your client fails during initial handshake, see our guide on how to fix MCP connection closed STDIO errors to isolate broken JSON-RPC frames.


2. FastMCP vs Standard Low-Level SDK Comparison

While the official MCP Python SDK provides the raw low-level mcp protocol bindings, FastMCP wraps boilerplate schema generation and transport initialization into standard Python decorators.

Feature / Dimension FastMCP (Recommended) Official Low-Level MCP SDK
Setup Time Under 2 minutes 15 to 20 minutes of boilerplate
Type Hinting & Schema Generation Automatic from Python docstrings Manual Pydantic / JSON Schema dicts
Transport Support STDIO, SSE, and Unix Domain Sockets Requires custom transport listeners
Context Window Protection Built-in output truncation hooks Manual token truncation required
Best Production Fit Rapid custom tools & internal APIs Custom C++ wrappers & legacy systems

For production database integrations using this SDK pattern, review our walkthrough on building a PostgreSQL and SQLite MCP server.


3. Best Practices for Production MCP Tools

Writing tools for LLMs requires different design patterns than writing traditional REST APIs.

1. Protect STDIO from Standard Print Statements

STDIO transport relies on standard output (stdout) to exchange clean JSON-RPC packets. Calling raw print() inside your Python tools injects unstructured strings into the protocol stream, corrupting message framing. Use sys.stderr.write() or the standard logging module configured to stderr:

import logging
import sys

logging.basicConfig(stream=sys.stderr, level=logging.INFO)
logger = logging.getLogger("mcp-server")

@mcp.tool()
def execute_safe_query(query: str) -> str:
    """Execute a sanitized query and report status."""
    logger.info("Processing query: %s", query)
    return "Query executed successfully"

2. Guard Against Asynchronous Deadlocks

If an external tool hangs on an unresponsive subprocess or remote database lock, your AI coding agent enters an infinite wait loop. If you run multiple concurrent tools or long-running shell scripts, follow our troubleshooting instructions to fix MCP tool timeout deadlocks in FastMCP on Linux.

3. Implement Strict Network Isolation for Remote Transports

When moving from local STDIO pipes to network-accessible SSE (Server-Sent Events) or HTTP endpoints, verify that your endpoints do not allow DNS rebinding or unauthorized internal network requests. Review our security architecture guide on securing remote MCP servers against SSRF.

4. Route Tools Across Multi-Agent Workflows

As your server inventory expands beyond single utilities to specialized memory, database, and terminal tools, avoid cluttering a single agent context. For persistent cross-session vector recall without external cloud databases, see our guide on building a local MCP memory server with sqlite-vec.


Summary Checklist

  • Install fastmcp to eliminate boilerplate JSON Schema definitions.
  • Expose functions using the @mcp.tool() decorator with concrete docstrings and type hints.
  • Direct all debugging logs to stderr to avoid corrupting STDIO JSON-RPC streams.
  • Test your server using mcp dev server.py before linking to your editor.
  • Connect your server file using absolute paths in mcp.json.
BC

Written by B. Cho

Systems & AI Infrastructure Engineer

Specializing in GPU inference engines (vLLM, SGLang, Ollama), CUDA memory allocation, and Model Context Protocol (MCP) infrastructure on Linux workstations.