tutorial server

Getting Started with MCP Development

Complete tutorial for building your first Model Context Protocol server - from basic concepts to production deployment

5 min read
Language: Python
Framework: FastMCP
Version: 1.0.0
MCP Version: 2024-11-05

Capabilities

Features

✨ Step-by-step Tutorial
✨ Production-ready Patterns
✨ Error Handling Examples
✨ Testing Strategies
✨ Deployment Guide
✨ Real-world Examples

Available Tools (2)

πŸ”§ hello_world

Simple greeting tool for testing MCP functionality

Parameters: name, language
πŸ”§ get_time

Return current time in various formats

Parameters: timezone, format

Getting Started

Installation

# Install FastMCP framework
pip install fastmcp

# Create new MCP server project
mkdir my-mcp-server
cd my-mcp-server

# Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

Basic Usage

# Basic server setup
from fastmcp import FastMCP
from fastmcp.tools import tool

app = FastMCP("my-server")

@tool()
def hello_world(name: str = "World") -> str:
    """Simple greeting tool"""
    return f"Hello, {name}!"

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

Getting Started with MCP Development

Ready to build your first Model Context Protocol (MCP) server? This comprehensive tutorial will take you from zero to production-ready MCP server in just a few steps.

🎯 What You’ll Learn

By the end of this tutorial, you’ll have:

  • Built a working MCP server with multiple tools
  • Integrated it with Claude Code for real-world testing
  • Implemented error handling and logging
  • Deployed to production with proper configuration
  • Understanding of MCP architecture and best practices

πŸš€ Quick Start (5 Minutes)

Step 1: Environment Setup

# Create project directory
mkdir my-first-mcp-server
cd my-first-mcp-server

# Set up Python environment
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

# Install dependencies
pip install fastmcp

Step 2: Create Your First Server

Create server.py:

from fastmcp import FastMCP
from fastmcp.tools import tool
from datetime import datetime
import pytz

# Initialize the MCP server
app = FastMCP("my-first-server")

@tool()
def hello_world(name: str = "World") -> str:
    """A friendly greeting tool"""
    return f"Hello, {name}! Welcome to MCP development!"

@tool()
def get_current_time(timezone: str = "UTC") -> str:
    """Get current time in specified timezone"""
    try:
        tz = pytz.timezone(timezone)
        current_time = datetime.now(tz)
        return current_time.strftime("%Y-%m-%d %H:%M:%S %Z")
    except Exception as e:
        return f"Error: {str(e)}"

@tool()
def calculate(expression: str) -> str:
    """Simple calculator (be careful with eval!)"""
    try:
        # In production, use a proper expression parser
        result = eval(expression)
        return f"{expression} = {result}"
    except Exception as e:
        return f"Error calculating '{expression}': {str(e)}"

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

Step 3: Test Your Server

# Run the server
python server.py

# The server will start on the default port
# You should see: "MCP Server running on port 8000"

πŸ”§ Claude Code Integration

Configuration

Add your server to Claude Code’s configuration:

{
  "mcpServers": {
    "my-first-server": {
      "command": "python",
      "args": ["path/to/your/server.py"],
      "cwd": "/path/to/your/project"
    }
  }
}

Testing in Claude Code

Once configured, you can test your tools:

Hey Claude, can you use the hello_world tool to greet me?
What time is it in Tokyo using the get_current_time tool?
Calculate 42 * 1337 using the calculate tool.

πŸ—οΈ Advanced Features

Adding Resources

Resources provide read-only data that Claude can access:

from fastmcp.resources import resource

@resource("server-info")
def get_server_info():
    """Information about this MCP server"""
    return {
        "name": "My First MCP Server",
        "version": "1.0.0",
        "description": "A tutorial MCP server",
        "tools_count": len(app.tools),
        "uptime": app.get_uptime()
    }

@resource("user-manual")
def get_user_manual():
    """User manual for this server"""
    return """
    # My First MCP Server
    
    ## Available Tools:
    - hello_world: Greet users
    - get_current_time: Get time in any timezone
    - calculate: Simple arithmetic
    
    ## Examples:
    - hello_world(name="Alice")
    - get_current_time(timezone="America/New_York")
    - calculate(expression="2 + 2")
    """

Error Handling & Logging

import logging
from fastmcp.types import McpError

# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@tool()
def robust_tool(input_data: str) -> str:
    """Tool with proper error handling"""
    try:
        logger.info(f"Processing input: {input_data}")
        
        # Your tool logic here
        result = process_data(input_data)
        
        logger.info(f"Successfully processed: {result}")
        return result
        
    except ValueError as e:
        logger.error(f"Validation error: {e}")
        raise McpError(f"Invalid input: {e}")
    except Exception as e:
        logger.error(f"Unexpected error: {e}")
        raise McpError(f"Tool failed: {e}")

Configuration Management

import os
from typing import Optional

class ServerConfig:
    def __init__(self):
        self.debug = os.getenv("DEBUG", "false").lower() == "true"
        self.api_key = os.getenv("API_KEY")
        self.rate_limit = int(os.getenv("RATE_LIMIT", "100"))
    
    def validate(self):
        if not self.api_key:
            raise ValueError("API_KEY environment variable required")

config = ServerConfig()
config.validate()

# Use configuration in tools
@tool()
def api_dependent_tool(query: str) -> str:
    """Tool that requires API access"""
    if not config.api_key:
        return "Error: API key not configured"
    
    # Use the API key...
    return f"Query processed: {query}"

πŸ§ͺ Testing Your Server

Unit Tests

Create test_server.py:

import pytest
from server import hello_world, get_current_time, calculate

def test_hello_world():
    result = hello_world("Alice")
    assert "Alice" in result
    assert "Hello" in result

def test_hello_world_default():
    result = hello_world()
    assert "World" in result

def test_get_current_time():
    result = get_current_time("UTC")
    assert "UTC" in result
    # Should include year
    assert "2025" in result or "2024" in result

def test_calculate():
    result = calculate("2 + 2")
    assert "4" in result

def test_calculate_error():
    result = calculate("invalid expression")
    assert "Error" in result

# Run tests: pytest test_server.py

Integration Tests

import asyncio
from fastmcp.client import McpClient

async def test_server_integration():
    """Test the actual MCP server"""
    async with McpClient("http://localhost:8000") as client:
        # Test tool listing
        tools = await client.list_tools()
        assert len(tools) > 0
        
        # Test tool execution
        result = await client.call_tool("hello_world", {"name": "Test"})
        assert "Test" in result

πŸš€ Production Deployment

Environment Variables

Create .env file:

# Server configuration
DEBUG=false
PORT=8000
LOG_LEVEL=INFO

# API keys (never commit these!)
API_KEY=your_secret_key_here
DATABASE_URL=postgresql://user:pass@localhost/db

# Rate limiting
RATE_LIMIT=1000
RATE_WINDOW=3600

Docker Deployment

Create Dockerfile:

FROM python:3.11-slim

WORKDIR /app

# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application
COPY . .

# Create non-root user
RUN adduser --disabled-password --gecos '' appuser
RUN chown -R appuser:appuser /app
USER appuser

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8000/health || exit 1

EXPOSE 8000

CMD ["python", "server.py"]

Production Server Code

from fastmcp import FastMCP
from fastmcp.middleware import rate_limit, logging_middleware
import os

# Production configuration
app = FastMCP(
    name="my-production-server",
    debug=os.getenv("DEBUG", "false").lower() == "true"
)

# Add middleware
app.add_middleware(rate_limit(
    calls=int(os.getenv("RATE_LIMIT", "1000")),
    window=int(os.getenv("RATE_WINDOW", "3600"))
))
app.add_middleware(logging_middleware())

# Health check endpoint
@app.route("/health")
def health_check():
    return {"status": "healthy", "version": "1.0.0"}

# Your tools here...

if __name__ == "__main__":
    port = int(os.getenv("PORT", "8000"))
    app.run(host="0.0.0.0", port=port)

πŸ“š Next Steps

Explore Advanced Patterns

  1. Check out the MCP Server Collection - 50+ production servers
  2. Read about Agent MCP Server - AI-powered recommendations
  3. Study Real-world Examples - Recursive AI development

Join the Community

Contributing

Found a bug? Want to contribute? The MCP ecosystem thrives on community involvement:

# Fork and clone the repository
git clone https://git.supported.systems/MCP/your-fork
cd your-fork

# Create a feature branch
git checkout -b feature/amazing-improvement

# Make your changes and test
pytest tests/

# Submit a pull request
git push origin feature/amazing-improvement

πŸ† Success Stories

Developers using this tutorial have built:

  • Enterprise integrations serving thousands of users
  • Personal productivity tools saving hours weekly
  • Research platforms accelerating scientific discovery
  • Creative tools enabling new forms of AI collaboration

Your turn! What will you build with MCP?


Ready to revolutionize how Claude interacts with your systems? Start building today!

☎️ contact.info // get in touch

Click to establish communication link

Astro
ASTRO POWERED
HTML5 READY
CSS3 ENHANCED
JS ENABLED
FreeBSD HOST
Caddy
CADDY SERVED
PYTHON SCRIPTS
VIM
VIM EDITED
AI ENHANCED
TERMINAL READY
RAILWAY BBS // SYSTEM DIAGNOSTICS
πŸ” REAL-TIME NETWORK DIAGNOSTICS
πŸ“‘ Connection type: Detecting... β—‰ SCANNING
⚑ Effective bandwidth: Measuring... β—‰ ACTIVE
πŸš€ Round-trip time: Calculating... β—‰ OPTIMAL
πŸ“± Data saver mode: Unknown β—‰ CHECKING
🧠 BROWSER PERFORMANCE METRICS
πŸ’Ύ JS heap used: Analyzing... β—‰ MONITORING
βš™οΈ CPU cores: Detecting... β—‰ AVAILABLE
πŸ“Š Page load time: Measuring... β—‰ COMPLETE
πŸ”‹ Device memory: Querying... β—‰ SUFFICIENT
πŸ›‘οΈ SESSION & SECURITY STATUS
πŸ”’ Protocol: HTTPS/2 β—‰ ENCRYPTED
πŸš€ Session ID: PWA_SESSION_LOADING β—‰ ACTIVE
⏱️ Session duration: 0s β—‰ TRACKING
πŸ“Š Total requests: 1 β—‰ COUNTED
πŸ›‘οΈ Threat level: MONITORED β—‰ MONITORED
πŸ“± PWA & CACHE MANAGEMENT
πŸ”§ PWA install status: Checking... β—‰ SCANNING
πŸ—„οΈ Service Worker: Detecting... β—‰ CHECKING
πŸ’Ύ Cache storage size: Calculating... β—‰ MEASURING
πŸ”’ Notifications: Querying... β—‰ CHECKING
⏰ TEMPORAL SYNC
πŸ•’ Live timestamp: 2025-09-20T12:33:29.538Z
🎯 Update mode: REAL-TIME API β—‰ LIVE
β—‰
REAL-TIME DIAGNOSTICS INITIALIZING...
πŸ“‘ API SUPPORT STATUS
Network Info API: Checking...
Memory API: Checking...
Performance API: Checking...
Hardware API: Checking...
Loading discussion...