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
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.
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]"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")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. Uselogging(which writes to stderr) as shown.Register it in Claude Desktop
Open Claude Desktop's config file:
~/Library/Application Support/Claude/claude_desktop_config.jsonon macOS or%AppData%\Claude\claude_desktop_config.jsonon 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 (fromwhich uv) incommand.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*.logon 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.
More guides
BeginnerClaudeDocuments
Explain a bill or official letter
Paste a bill or letter into free Claude and get plain English, the deadline, and what is actually being asked.
About 10 minutes using Claude
BeginnerClaudeWriting
Write a clear email
Tell free Claude who you are writing to and what you need. You get a short draft, and you send it yourself.
About 8 minutes using Claude
BeginnerClaudeWriting
Rewrite resume bullets from real work
Ask free Claude for three resume bullets that use only the facts you provide, with blanks where a number is missing.
About 12 minutes using Claude
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.