Build an MCP Server: Complete MCP Tutorial for Beginners
Building an MCP server allows you to connect AI models like Claude to your local tools, data, and applications through a standardized protocol. In this tutorial, you’ll build an event calendar MCP server from scratch using Python’s FastMCP framework, enabling Claude Desktop to manage calendar events through natural language commands.
What you’ll build:
- A functional MCP server with tools for adding, viewing, and deleting calendar events
- Direct integration with Claude Desktop for AI-powered calendar management
- A complete understanding of how MCP servers communicate with AI models
What you’ll need:
- Python 3.10 or later installed on your system
- Basic familiarity with Python functions and syntax
- Claude Desktop (we’ll install this in Step 1)
What is Model Context Protocol (MCP)?
The Model Context Protocol (MCP) is an open standard designed to create a secure, structured bridge between language models and external data, tools, and systems. Instead of giving AI models direct access to your files or databases, MCP provides a structured way for models to request information through servers you control.
Think of MCP as a standardized interface: Claude (or any AI model) can request specific actions through your MCP server, but you decide exactly what data and operations are available. This architecture ensures security while enabling powerful integrations with local data, whether that’s calendar events, file systems, or custom services.
So now that you know what MCP does and why it matters, let’s build our own event calendar MCP server.
Building an event calendar MCP server
In this section, we’ll build an event calendar MCP Server from scratch. This project will show how an MCP server can help a language model like Claude manage data locally, in this case, creating, viewing, and deleting calendar events. Let’s start with the first step:
Step 1: Install Claude desktop
Claude Desktop will act as the MCP client that can talk to the server, and automatically discover and connect to local MCP servers once they’re running on your system. To install Claude desktop, do the following:
Visit the official Claude Desktop download page
Download and install the version compatible with your operating system (Windows or macOS).

Once installed, Claude will be ready to detect and interact with the MCP server we’ll create in the next steps.
Step 2: Set up the project structure
Check the Python version on device
Before executing the any commands for project initilaization, check the Python version using this command on the terminal:
python --version
If you see Python 3.10 or later, you’re good to go. If you have an older version or Python isn’t installed, download it from python.org and follow the installation instructions for your operating system.
Initialize the project with uv
Now let’s set up the project structure using the uv init command. uv is a modern Python package manager that creates a new Python project with all the essential boilerplate, containing:
- A virtual environment
pyproject.tomlfilemain.pyfileREADME.mdfile
Open your terminal and run:
uv init event-calendar-mcpcd event-calendar-mcp
A new directory called event-calendar-mcp will be created and initialized as a Python project. The cd command will take us inside this directory.
Understand the project structure
After running uv init, your project looks like this:
event-calendar-mcp/├── .venv/ # Virtual environment (isolated Python)├── main.py # Your code goes here├── pyproject.toml # Project metadata and dependencies└── README.md # Project documentation
Here’s what each file does:
.venv/: This is your virtual environment. It’s a self-contained Python installation that keeps your project’s dependencies separate from your system’s Python.main.py: This is where you’ll write your MCP server code. This is the heart of your application. When you runuv run main.py, this file executes and starts your server.pyproject.toml: This is your project’s configuration file. It contains metadata like your project name and version, and lists all the dependencies your project needs. When you install packages withuv pip install, they get added here.README.md: This is documentation for your project. It explains what your project does, how to install it, and how to use it.
Step 3: Build the MCP server code
Open main.py in your code editor and write the following code. We’ll break it into sections, to understand what each part does.
Imports and server initialization
Start with these imports:
from mcp.server.fastmcp import FastMCPfrom typing import List, Dictfrom datetime import datetime# Create an MCP servermcp = FastMCP("EventCalendar")# In-memory storage for events# Each event is a dict: {"title": str, "date": str, "description": str}events: List[Dict] = []
Here’s what happening:
FastMCPis the framework that handles all the MCP protocol complexity for you. It manages how your server communicates with Claude.ListandDictare type hints that tell Python what kind of data structures you’re using (Python lists and dictionaries).datetimeis a standard Python library for working with dates and times.mcp = FastMCP("EventCalendar")creates your server and names it “EventCalendar”. Claude will recognize this name.events: List[Dict] = []creates an empty list to store your calendar events. Each event is a dictionary with a title, date, and description.
Add the add_event tool
This tool lets Claude add events to your calendar:
# Add an event@mcp.tool()def add_event(title: str, date: str, description: str = "") -> str:"""Add a new calendar event.Date format: YYYY-MM-DD"""try:# Validate date formatdatetime.strptime(date, "%Y-%m-%d")events.append({"title": title, "date": date, "description": description})return f"Event '{title}' added for {date}."except ValueError:return "Invalid date format. Use YYYY-MM-DD."
In this code:
@mcp.tool()is a decorator that tells FastMCP “make this function available as a tool Claude can call.”The function takes three parameters:
title(event name),date(in YYYY-MM-DD format), and an optionaldescription.datetime.strptime(date, "%Y-%m-%d")validates that the date is in the correct format. If it’s not, it raises aValueError.events.append(...)adds the new event to your events list as a dictionary.The function returns a confirmation message to Claude.
Add the view_event tool
This tool lets Claude see all your calendar events:
# View all events@mcp.tool()def view_events() -> str:"""Return all events in the calendar."""if not events:return "No events scheduled."result = "Calendar Events:\n"for event in sorted(events, key=lambda x: x["date"]):desc = f" - {event['description']}" if event['description'] else ""result += f"- {event['date']}: {event['title']}{desc}\n"return result
This code:
First, it checks if there are any events. If the list is empty, it returns “No events scheduled.”
sorted(events, key=lambda x: x["date"])sorts all events by date so they display chronologically.For each event, it builds a formatted string showing the date, title, and description (if one exists).
It returns the entire formatted list as a single string that Claude can display.
Add the delete_event tool and summarize prompt
These complete your server’s functionality:
# Delete an event by title@mcp.tool()def delete_event(title: str) -> str:"""Delete an event by its title."""initial_length = len(events)events[:] = [e for e in events if e["title"].lower() != title.lower()]if len(events) < initial_length:return f"Event '{title}' deleted."else:return f"No event found with title '{title}'."# Summarize events@mcp.prompt()def summarize_events() -> str:"""Generate a summary of upcoming events."""if not events:return "No events scheduled."summary = "Upcoming Events Summary:\n"for e in sorted(events, key=lambda x: x["date"]):summary += f"- {e['date']}: {e['title']}"if e['description']:summary += f" ({e['description']})"summary += "\n"return summaryif __name__ == "__main__":mcp.run()
Here’s what this code is doing:
delete_event()removes an event by title. It compares titles case-insensitively (so “Team Meeting” and “team meeting” are treated the same). It returns a success or “not found” message.@mcp.prompt()creates a reusable prompt (different from@mcp.tool()). Prompts are suggestions Claude can use without you asking.summarize_events()provides a nice summary of all upcoming events.events[:] = [...]is a Python idiom that modifies the list in-place (it doesn’t create a new list). This is important for keeping the same list object.if __name__ == "__main__": mcp.run()is the entry point. When you run this file, this code starts your MCP server.
Step 4: Register your MCP server with uv
Next, we need to tell Claude desktop where to find the server. The uv run mcp install command does this automatically. It reads your main.py file, identifies it as an MCP server, and adds the necessary configuration to Claude’s settings so Claude knows how to start and connect to your server.
Note: Without this step, Claude desktop won’t know your server exists and won’t be able to find it.
Run the following command in your terminal ((in the event-calendar-mcp directory):
uv run mcp install main.py
The uv run executes a command using your project’s Python environment, and mcp install main.py registers main.py as an MCP server.

Finally, let’s test the working of our project.
Step 5: Test the MCP server with Claude desktop
Open Claude desktop (close and reopen it if it was already running). Claude will automatically discover and connect to your registered MCP server. Let’s test adding an event using this prompt:
Add an event called "Team Standup" on 2025-12-15 with description "Daily team sync"
Claude will use your add_event tool to create the event. You should see a response like:
Now ask Claude to show you your events:
Show me all my calendar events
Claude will call your view_events tool and display your event in a formatted list as follows:

Try asking Claude to summarize:
Summarize my upcoming events
Claude will use the summarize_events prompt to give you a summary of all events.
Test deleting an event using:
Delete the Team Standup event
Claude will use your delete_event tool to remove it.

Select the ”Allow” option to delete it:

We’ve successfully created an event calendar MCP server that integrates with Claude! This server manages data locally, responds to Claude’s requests, and demonstrates all the core concepts of the MCP.
Now that you’ve seen how to set one up, let’s look at what’s actually happening behind the scenes, i.e. how MCP servers work.
How do MCP servers work?
When you asked Claude to add an event to your calendar, a lot happened automatically. Claude sent a request to your server, your server processed it, and Claude received a response. But how does this communication actually work?
MCP operates on a simple client-server model. Imagine two programs having a conversation: one asks questions (the client), and the other answers them (the server).
Client (Claude desktop): When you open Claude desktop and chat with Claude, Claude is the client. It’s the one asking questions and making requests. When you type “Add an event,” Claude is the client initiating that request.
Server (your event calendar program): Your
main.pyfile is the server. It sits quietly waiting for requests from Claude. When a request arrives, it processes it, executes the appropriate function, and sends back a response.

They communicate through something called stdio (standard input/output). Think of it like a two-way pipe: Claude writes messages into one end, and your server reads them. This is a local, direct connection with no internet involved, no external services needed.
MCP servers are powerful because they’re secure and put you in control. You define exactly what Claude can do, your data stays local, and everything happens instantly without external dependencies. This is the foundation of how modern AI tools can safely integrate with your personal workflows.
Conclusion
The Model Context Protocol (MCP) provides a standardized way to connect AI models with local tools and data while maintaining security and control. By building this event calendar MCP server, you’ve learned the fundamentals of MCP server development: exposing tools through decorators, managing local data, and integrating with Claude Desktop.
The MCP server you built today demonstrates how AI integration can be both powerful and secure. As you continue developing MCP servers, you’ll discover endless possibilities for connecting AI models to real-world data and systems.
To deepen your knowledge of building AI-powered applications and mastering the tools that power modern development, check out the comprehensive Introduction to Claude Projects.
Frequently asked questions
1. What is the basics of MCP?
MCP, or Model Context Protocol, is a framework that lets AI models like Claude communicate with local tools, data, and apps. It’s built on a client–server model, where the AI (client) sends structured requests to a local MCP server, which processes them and sends back responses in a secure, offline environment.
2. What is an example of an MCP server?
A simple example is a calendar MCP server that can add, view, or delete events on your computer. When Claude asks to “show upcoming meetings,” the MCP server reads your stored events locally and returns the results with no internet connection or external API needed.
3. Is MCP like an API?
In some ways, yes, as it behaves like an API but runs entirely on your local machine. Instead of sending requests over the internet, Claude sends structured messages to your MCP server, which directly executes the logic you define in code.
4. What are MCP tools?
Tools are the functions you expose to Claude through your MCP server. Each tool performs a specific action like adding a calendar event, summarizing a file, or running a local script. Think of tools as your AI assistant’s skill set.
5. What are the benefits of an MCP server?
MCP servers are private, customizable, and offline-first. They let you extend Claude’s abilities using local data and functions while keeping everything secure on your device. No third-party APIs, no data leaks, just precise, local control over your AI’s capabilities.
'The Codecademy Team, composed of experienced educators and tech experts, is dedicated to making tech skills accessible to all. We empower learners worldwide with expert-reviewed content that develops and enhances the technical skills needed to advance and succeed in their careers.'
Meet the full teamRelated articles
- Article
How to Use Model Context Protocol (MCP) with Claude
Learn how to use Model Context Protocol (MCP) with Claude desktop to standardize connections between AI and external tools like GitHub and Slack using this step-by-step guide. - Article
Model Context Protocol (MCP) vs. APIs: Architecture & Use Cases
Learn MCP vs API differences: architecture, real-world use cases, and when to choose each for AI. - Article
Claude Code Tutorial: How to Generate, Debug and Document Code with AI
Learn how to use Claude Code, Anthropic’s AI coding assistant, to generate, refactor, debug, document, and translate code. Discover setup steps, best practices, and limitations.
Learn more on Codecademy
- Learn how to use Model Context Protocol (MCP) servers to extend your LLM's capabilities with hands-on examples.
- Beginner Friendly.1 hour
- Utilize Claude for data insights by managing CSV files, handling data, performing statistical analysis, using natural language queries, and creating visualizations.
- Beginner Friendly.< 1 hour
- Explore Anthropic’s Claude Artifacts. Learn to create and publish documents, SVGs, HTML, and React components with prompt engineering for dynamic projects.
- Beginner Friendly.< 1 hour