Understanding MCP

Setting Up Your MCP Development Environment

5 min read

Ten minutes of setup, and the rest of the course is writing server code rather than fighting your environment.

Prerequisites

  • A Python or Node.js runtime. Each SDK states its own minimum version, and those move — check the MCP SDK documentation for the current requirement rather than trusting a number written in a course.
  • Claude Desktop, which is what you will test against.
  • A code editor. Any will do.

Installing the MCP SDK

Official SDKs cover Python, TypeScript, C#, Java, Kotlin, and Swift, with community SDKs for Rust, Go, and others. This course uses Python for the examples and TypeScript where it differs meaningfully — the protocol is identical underneath, so the concepts port to whichever you pick.

Install the SDK

bash
# Isolate the project so SDK upgrades can't break other work
python -m venv mcp-env
source mcp-env/bin/activate       # Windows: mcp-env\Scripts\activate

pip install mcp

# Confirm it imported cleanly before writing any server code
python -c "import mcp; print('mcp ready')"

Your First MCP Server (Python)

Create a file called server.py:

from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent

# Create server instance
server = Server(name="hello-mcp")

# Define a simple tool
@server.list_tools()
async def list_tools():
    return [
        Tool(
            name="greet",
            description="Greet someone by name",
            inputSchema={
                "type": "object",
                "properties": {
                    "name": {"type": "string", "description": "Name to greet"}
                },
                "required": ["name"]
            }
        )
    ]

@server.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "greet":
        return [TextContent(type="text", text=f"Hello, {arguments['name']}!")]
    raise ValueError(f"Unknown tool: {name}")

# Run the server
async def main():
    async with stdio_server() as (read, write):
        await server.run(read, write)

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

Configuring Claude Desktop

Add your server to Claude Desktop's config file:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "hello-mcp": {
      "command": "python",
      "args": ["/path/to/server.py"]
    }
  }
}

Testing Your Server

  1. Restart Claude Desktop
  2. Open a new conversation
  3. Ask Claude: "Use the greet tool to say hello to Alice"
  4. Claude will invoke your MCP server!

When it doesn't work

Almost every first-run failure is one of four things, and they are distinguishable in under a minute. Work through it:

My server isn't showing up in Claude Desktop

Did you fully quit and reopen Claude Desktop after editing the config?

The one that catches everyone: on a stdio server, stdout is the protocol channel. A stray print() injects garbage into the JSON-RPC stream and the connection dies with no useful error. Log to a file, or to stderr, never to stdout.

Next: building a real server with tools and resources. :::

Quiz

Module 1 Quiz: MCP Fundamentals

Take Quiz
Was this lesson helpful?

Sign in to rate