Build a Claude MCP Server in Python

Create a Model Context Protocol (MCP) server in Python that Claude can use as a tool. Expose custom functions, databases, and APIs to Claude Code and Claude Desktop.

💥 50p impulse-buy: Power Prompts PDF (first 10 buyers) 30 battle-tested Claude Code prompts · 8-page PDF · paste into CLAUDE.md and never re-type a prompt again · 50p impulse-buy, no commitment

An MCP server exposes tools Claude can call during any session — without you modifying API calls. This example builds a minimal MCP server in Python using the official mcp SDK.

Installation

pip install mcp

Minimal MCP server with two tools

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("my-tools")

@mcp.tool()
def get_word_count(text: str) -> int:
    """Count the number of words in a text string."""
    return len(text.split())

@mcp.tool()
def calculate(expression: str) -> float:
    """Safely evaluate a mathematical expression like '2 + 3 * 4'."""
    import ast, operator
    ops = {ast.Add: operator.add, ast.Sub: operator.sub,
           ast.Mult: operator.mul, ast.Div: operator.truediv}

    def eval_node(node):
        if isinstance(node, ast.Constant):
            return node.value
        if isinstance(node, ast.BinOp):
            return ops[type(node.op)](eval_node(node.left), eval_node(node.right))
        raise ValueError(f"Unsupported: {node}")

    tree = ast.parse(expression, mode="eval")
    return eval_node(tree.body)

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

MCP server with a resource (read-only data)

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("company-data")

@mcp.resource("company://team-roster")
def get_team_roster() -> str:
    """Current team roster in CSV format."""
    return "name,role,team
Alice,Engineer,Platform
Bob,Designer,Product"

@mcp.tool()
def lookup_employee(name: str) -> dict:
    """Look up an employee by name. Returns role and team."""
    roster = {
        "Alice": {"role": "Engineer", "team": "Platform"},
        "Bob": {"role": "Designer", "team": "Product"}
    }
    return roster.get(name, {"error": f"{name} not found"})

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

Register in Claude Code settings

# ~/.claude/settings.json
{
  "mcpServers": {
    "my-tools": {
      "command": "python",
      "args": ["/path/to/your/server.py"],
      "env": {}
    }
  }
}

Test the server with the MCP inspector

mcp dev /path/to/server.py

Browse available MCP servers and skills at the Claude Skills Browser. For API-level tool use (without MCP), see the tool use Python example.

Frequently asked questions

What is the Model Context Protocol (MCP)?
MCP is an open protocol that lets you expose tools and resources to Claude. An MCP server defines 'tools' (functions Claude can call), 'resources' (data Claude can read), and 'prompts' (reusable prompt templates). Claude Code and Claude Desktop discover MCP servers via a config file.
How is MCP different from the API's tool_use feature?
API tool_use sends tool definitions inline with each API call — your app controls everything. MCP is a sidecar protocol: you run a persistent server process, and Claude discovers it via config. MCP tools are available across all Claude sessions that include your server, not just specific API calls.
Where do I configure MCP servers for Claude Code?
Add MCP server entries to `~/.claude/settings.json` under `mcpServers`. For Claude Desktop, the config file is `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS.

Free tools

Cost Calculator → API Cookbook → Diff Summarizer → Skills Browser →

More examples

Claude API Python QuickstartClaude API Node.js / TypeScript QuickstartClaude API Streaming in PythonClaude API Streaming in Node.js / TypeScriptClaude API Tool Use in PythonClaude API Tool Use in Node.js / TypeScript