Skip to content
Easy AI How-To

AdvancedClaudeBuilding

Build your first MCP server in Python and use it in Claude Desktop

MCP lets Claude and other AI apps use your own tools. In this guide you build a working MCP server in about 30 lines of Python and plug it into Claude Desktop. Terms like server, host, and stdio are explained as you go.

Time
About 35 minutes
Checked
Tools
MCP docs, Claude Desktop

If a button name on the screen does not match this guide, follow the action. These products rename buttons often. This is an advanced guide: it uses code, and each technical term is explained the first time it appears. Model names and prices change, so check the linked docs before you ship.

Steps

  1. Know what you're building

    MCP (Model Context Protocol) is an open standard for connecting AI apps to tools and data. An MCP server is a small program that offers tools (functions the AI can call, with your approval). An MCP host, such as Claude Desktop, starts your server and passes Claude's tool calls to it. This server will count words and characters in text.

  2. Set up the project

    Install uv, then create a project and add the MCP SDK (version 2.0 or newer, per the official tutorial):

    curl -LsSf https://astral.sh/uv/install.sh | sh
    uv init textstats && cd textstats
    uv venv && source .venv/bin/activate
    uv add "mcp[cli]"
    
  3. Write the server

    Save this as server.py. Type hints and the docstring become the tool's description and input schema (the rules for what arguments it accepts).

    import logging
    from mcp.server import MCPServer
    
    logger = logging.getLogger(__name__)
    mcp = MCPServer("textstats")
    
    @mcp.tool()
    def text_stats(text: str) -> str:
        """Count words, characters, and sentences in a piece of text.
    
        Args:
            text: The text to analyze
        """
        words = len(text.split())
        sentences = sum(text.count(p) for p in ".!?") or 1
        logger.info("Analyzed %d words", words)
        return f"Words: {words}\nCharacters: {len(text)}\nSentences: {sentences}"
    
    if __name__ == "__main__":
        mcp.run(transport="stdio")
    
  4. Never print to stdout

    This server talks over stdio: the host sends messages through the program's standard input and reads replies from standard output. A stray print() corrupts those messages. Use logging (which writes to stderr) as shown.

  5. Register it in Claude Desktop

    Open Claude Desktop's config file: ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %AppData%\Claude\claude_desktop_config.json on Windows (create it if missing). Add your server with an absolute path:

    {
      "mcpServers": {
        "textstats": {
          "command": "uv",
          "args": ["--directory", "/ABSOLUTE/PATH/TO/textstats", "run", "server.py"]
        }
      }
    }
    

    If Claude can't find uv, put its full path (from which uv) in command.

  6. Restart and test

    Fully quit Claude Desktop (Cmd+Q on Mac, or Quit from the system tray on Windows) and reopen it. Open the + menu by the message box and look under Connectors for textstats. Then ask: "Use text_stats on this paragraph: ..." and approve the tool call.

Tips

  • If the server doesn't appear, check the logs: ~/Library/Logs/Claude/mcp*.log on macOS.

  • Write clear docstrings. The model decides when to call a tool from its name and description.

  • The same server works with other MCP hosts, such as Claude Code and other MCP-compatible editors.

Common questions

Can I write MCP servers in other languages?

Yes. There are official SDKs for TypeScript, Java, Kotlin, C#, Go, Ruby, Rust, and more. The official tutorial has a version for each.

What's the difference between tools, resources, and prompts?

Tools are functions the model calls. Resources are readable data, like files. Prompts are reusable templates the user picks.

Is it safe to give Claude tools?

Hosts ask for your approval before calling tools. Still, only expose actions you'd be comfortable with, and avoid tools that delete or send things without checks.

Occasional notes

Hear when a new guide is up

A short note when a guide is added. No account, and no emails until this form is connected to a real list.

Placeholder. This form is not connected to an email service. Nothing you type is saved or sent.