MCP for Beginners: Complete Guide to Model Context Protocol
Everything you need to understand MCP and build your first server. From zero to working code in 5 minutes.
1. What is MCP?
Model Context Protocol (MCP) is an open standard that connects AI models to external tools and data. Think of it like USB for AI—a universal interface that lets any AI model plug into any service.
Before MCP, connecting Claude (or any AI) to your database, APIs, or files required custom code for each integration. MCP changes that. Build one server, and it works with Claude Desktop, Cursor IDE, Cline, and any other MCP-compatible client.
2. Why MCP Matters
The Old Way
- • Custom integration for each AI provider
- • Different APIs, different auth, different patterns
- • Maintain separate code for each connection
The MCP Way
- • One standard interface
- • Build once, works everywhere
- • Community of shared servers
Real example: Instead of building a custom "search my Notion" feature for Claude, you install an MCP server that already does it. Takes 2 minutes instead of 2 days.
3. Core Concepts
MCP has three building blocks:
1. Tools
Functions the AI can call. Like "search_files", "send_email", or "query_database". You define what they do, the AI decides when to use them.
@mcp.tool()
def search_notes(query: str) -> str:
"""Search your notes for relevant content."""
# Your search logic here
return results2. Resources
Data the AI can read. Documents, configurations, database records. Unlike tools, resources are passively available—the AI can reference them without explicitly calling anything.
@mcp.resource("notes://recent")
def get_recent_notes() -> str:
"""Last 10 notes you created."""
return format_notes(get_latest(10))3. Prompts
Reusable prompt templates. Useful for complex workflows you run repeatedly.
@mcp.prompt()
def code_review(code: str) -> str:
"""Standard code review template."""
return f"Review this code for bugs, security issues, and style:\n\n{code}"4. Your First MCP Server (5 Minutes)
Let's build a working server. We'll use Python with FastMCP—the easiest way to get started.
Step 1: Install FastMCP
pip install fastmcp
Step 2: Create server.py
from fastmcp import FastMCP
mcp = FastMCP("my-first-server")
@mcp.tool()
def add_numbers(a: int, b: int) -> int:
"""Add two numbers together."""
return a + b
@mcp.tool()
def greet(name: str) -> str:
"""Generate a greeting."""
return f"Hello, {name}! Welcome to MCP."
if __name__ == "__main__":
mcp.run()Step 3: Test It
python server.py
Your server is running. Now let's connect it to Claude.
Step 4: Connect to Claude Desktop
Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"my-first-server": {
"command": "python",
"args": ["/path/to/server.py"]
}
}
}Restart Claude Desktop. Ask Claude to "add 5 and 3"—it will use your tool.
Need detailed setup help? See our Claude Desktop MCP Setup Guide.
5. Building Something Useful
The hello-world is nice, but let's build something you'd actually use: a note-taking server.
from fastmcp import FastMCP
from pathlib import Path
from datetime import datetime
mcp = FastMCP("notes")
NOTES_DIR = Path.home() / "notes"
NOTES_DIR.mkdir(exist_ok=True)
@mcp.tool()
def create_note(title: str, content: str) -> str:
"""Create a new note with title and content."""
filename = f"{datetime.now():%Y%m%d_%H%M}_{title.lower().replace(' ', '_')}.md"
filepath = NOTES_DIR / filename
filepath.write_text(f"# {title}\n\n{content}")
return f"Created: {filename}"
@mcp.tool()
def search_notes(query: str) -> str:
"""Search all notes for a query string."""
results = []
for note in NOTES_DIR.glob("*.md"):
content = note.read_text()
if query.lower() in content.lower():
results.append(f"**{note.name}**\n{content[:200]}...")
return "\n\n".join(results) if results else "No matching notes found."
@mcp.tool()
def list_notes() -> str:
"""List all notes."""
notes = list(NOTES_DIR.glob("*.md"))
return "\n".join(n.name for n in sorted(notes, reverse=True)[:20])
if __name__ == "__main__":
mcp.run()Now Claude can create, search, and list your notes. This took 30 lines of code.
6. Connecting to Real Services
MCP shines when connecting to external APIs. Here's a pattern for API integrations:
import httpx
from fastmcp import FastMCP
mcp = FastMCP("weather")
@mcp.tool()
def get_weather(city: str) -> str:
"""Get current weather for a city."""
# Using wttr.in—free, no API key needed
response = httpx.get(f"https://wttr.in/{city}?format=3")
return response.text
@mcp.tool()
def get_forecast(city: str) -> str:
"""Get 3-day forecast for a city."""
response = httpx.get(f"https://wttr.in/{city}?format=%l:+%c+%t+%w")
return response.textThe same pattern works for any API: Notion, Slack, GitHub, your own services.
7. Security Basics
MCP servers run on your machine with your permissions. Be careful:
Do:
- • Validate all inputs
- • Use environment variables for API keys
- • Limit file access to specific directories
- • Log what your server does
Don't:
- • Expose raw database queries
- • Allow arbitrary file access
- • Hard-code credentials
- • Trust AI-generated paths without validation
Example: Input Validation
@mcp.tool()
def read_file(filename: str) -> str:
"""Read a file from the allowed directory."""
# Prevent path traversal
safe_path = (ALLOWED_DIR / filename).resolve()
if not safe_path.is_relative_to(ALLOWED_DIR):
raise ValueError("Access denied: path outside allowed directory")
return safe_path.read_text()8. Where to Use MCP
MCP works with multiple clients:
Same server, different contexts. Build once, use everywhere. Learn more about IDE setup in our MCP with Cursor & IDEs guide.
9. Next Steps
You've got the basics. Here's where to go next:
1. Browse existing servers
Don't reinvent the wheel. Check the MCP Server Directory for pre-built integrations.
2. Learn TypeScript
For production servers, TypeScript with the official SDK offers better type safety.
3. Handle errors properly
Production servers need robust error handling. Learn the patterns.
4. Add authentication
For sensitive data, add auth. API keys, OAuth, secrets management.
5. Test your servers
Before shipping, test thoroughly with MCP Inspector and unit tests.
Common Mistakes to Avoid
Starting too complex — Begin with a single tool. Add more once that works.
Ignoring error messages — When Claude says "failed to connect," check your server logs first.
Skipping validation — Every input from the AI should be validated. Trust nothing.
Forgetting the restart — Claude Desktop needs a restart after config changes. Every time.
Summary
MCP is the standard way to give AI models access to tools and data. The core concepts:
- Tools = functions the AI can call
- Resources = data the AI can read
- Prompts = reusable templates
Start with FastMCP for Python, build a simple tool, connect to Claude Desktop. Once that works, gradually add complexity. The best MCP servers do one thing well. Start small, ship fast, iterate.
Ready to Build?
You understand the basics. Now it's time to build something real.
Get updates in your inbox
Tutorials, updates, and best practices for Model Context Protocol.
No spam. Unsubscribe anytime.