PTENES
TRACK 3

🐍 Creating Your First MCP Server

Build an MCP Server from scratch in Python, understanding every line of code—from Hello World to a complete server with tools, resources, and prompts.

9
Modules
54
Topics
~6h
Duration
Intermediate
Level

Quick Navigation

Detailed Content
Module 3.1 ~25 min · Theory

🏗️ MCP Server Structure

Server anatomy: initialization, tool registration, and execution cycle.

What it is:

An MCP Server consists of essential components: the FastMCP object that manages everything, the decorated functions that define tools, resources, and prompts, and the entry point that starts the server. Each part has a clear responsibility.

Why learn:

Knowing a server's anatomy lets you understand any MCP code you encounter and confidently create your own servers, knowing where each piece fits.

Key concepts:

FastMCP, server object, decorators, entry point, components, responsibilities.

What it is:

Starting an MCP Server involves creating a FastMCP instance with a name, configuring optional parameters such as version and description, and preparing the environment to receive connections. This is when everything gets registered.

Why learn:

A well-configured setup ensures your server works correctly from the start. Startup errors are the hardest to diagnose if you don’t understand the process.

Key concepts:

FastMCP(), server name, configuration parameters, instantiation, initial setup.

What it is:

Registering tools means decorating Python functions with @mcp.tool() to make them available to the AI model. The decorator automatically extracts the function’s name, description, and parameter schema.

Why learn:

Registering tools is the most fundamental operation of an MCP Server. Mastering this process is essential for creating servers that expose useful functionality to the model.

Key concepts:

@mcp.tool(), automatic registration, function introspection, schema generation, Python decorators.

What it is:

The lifecycle of an MCP Server includes: initialization, handshake with the Client, capability registration, waiting for requests, processing calls, and graceful shutdown. Each phase has specific events and behaviors.

Why learn:

Understanding the lifecycle lets you create robust servers that handle each phase correctly, including clean startup and shutdown.

Key concepts:

Lifecycle, handshake, capabilities, request loop, graceful shutdown, lifecycle events.

What it is:

A typical MCP Server file structure includes the server’s main file, a pyproject.toml or requirements.txt for dependencies, and optionally separate modules for complex tools. Simple servers can be a single file.

Why learn:

Good file organization makes maintenance, testing, and collaboration easier. Following conventions helps other developers understand your server quickly.

Key concepts:

Project structure, main file, dependencies, pyproject.toml, modules, organization.

What it is:

The essential settings for an MCP Server include the server name, version, transport used, and environment variables. These settings define how the server presents itself to the Client and how it behaves in different environments.

Why learn:

Configuring your server correctly ensures compatibility with different Hosts and environments. Incorrect settings are a common cause of connection problems.

Key concepts:

Name and version, transport, environment variables, Host configuration, compatibility.

View Full
Module 3.2 ~30 min · Hands-on

👋 Hello World MCP

Create your first server with a tool that returns 'Hello, world!'—the minimum viable setup.

What it is:

The goal is to create the simplest MCP Server possible: a server with a single tool that returns "Hello, world!". This is the equivalent of Hello World for the MCP ecosystem—the minimum working example that proves everything is working.

Why learn:

Starting with the functional minimum eliminates complexity and lets you focus on what matters. Once Hello World works, you have a solid foundation for adding features.

Key concepts:

Hello World, minimum viable implementation, proof of concept, learning foundation, simplicity.

What it is:

Creating the server file involves defining the project directory, creating the main Python file (e.g., server.py), and ensuring the virtual environment is configured with the correct dependencies installed via pip.

Why learn:

Knowing how to create the initial structure correctly prevents import, dependency, and execution issues. It’s the foundation everything else is built on.

Key concepts:

Project creation, server.py, virtual environment, pip install, directory structure.

What it is:

The Hello World MCP code consists of importing FastMCP, creating the server instance, defining a function decorated with @mcp.tool() that returns "Hello, world!", and adding the entry point with mcp.run(). It's fewer than 10 lines of code.

Why learn:

Writing the code from scratch instead of copying and pasting ensures you understand every line. This is the foundational knowledge that will be expanded on in all the following modules.

Key concepts:

from mcp.server.fastmcp import FastMCP, instantiation, @mcp.tool(), return string, mcp.run().

What it is:

For Claude Desktop to recognize your server, you need to add it to claude_desktop_config.json. The entry includes the command to run Python, the path to the server file, and optional environment variables.

Why learn:

Host configuration is the step that connects your code to the AI model. Without it, your server exists, but no one can use it. It’s the bridge between development and real-world use.

Key concepts:

claude_desktop_config.json, mcpServers, command, args, script path, restart Claude.

What it is:

Testing Hello World involves restarting Claude Desktop, checking that the server appears in the connections list, and sending a message that triggers the tool. Claude should call your tool and display “Hello, world!” in the response.

Why learn:

Seeing your first server working is the most motivating moment in the course. Confirming that everything works gives you the confidence to build more complex servers.

Key concepts:

Manual testing, connection verification, tool calling, expected response, basic troubleshooting.

What it is:

A line-by-line analysis of the Hello World code: the import brings in the framework, FastMCP() creates the server, @mcp.tool() registers the function, the docstring becomes the tool description, return defines the response, and mcp.run() starts the event loop.

Why learn:

Understanding every line in depth turns memorized code into real knowledge. You'll know how to safely modify and expand any part of the server.

Key concepts:

Import statement, instantiation, decorator pattern, docstring as metadata, event loop, execution.

View Full
Module 3.3 ~25 min · Theory

🎨 Understanding Decorators and Schemas

How FastMCP uses Python decorators to register tools and define parameters.

What it is:

Python decorators are functions that wrap other functions, adding behavior without modifying the original code. The @ symbol before a function indicates that it is being decorated. In MCP, decorators register functions as tools, resources, or prompts.

Why learn:

Decorators are FastMCP’s core mechanism. Without understanding them, the code seems like magic. With this knowledge, you control exactly what’s happening.

Key concepts:

Python decorators, @syntax, wrapper functions, metaprogramming, automatic registration.

What it is:

The @mcp.tool() decorator turns a regular Python function into an MCP tool. It extracts the function name, its docstring as the description, and the parameter type hints as the input schema. It also accepts optional parameters to customize the registration.

Why learn:

@mcp.tool() is the decorator you'll use in 90% of cases. Mastering its options and behavior lets you create precise, well-documented tools.

Key concepts:

@mcp.tool(), automatic naming, docstring as description, type hints, optional parameters.

What it is:

Parameter schemas define the input types a tool accepts. FastMCP uses Python type hints (str, int, float, bool, list, dict) to automatically generate the JSON Schema the model uses to build correct calls.

Why learn:

Well-defined schemas ensure the model sends data in the correct format. Without proper schemas, your tools receive unexpected data and fail silently.

Key concepts:

JSON Schema, type hints, str, int, float, bool, Optional, required vs. optional parameters.

What it is:

MCP tools can return simple strings, dictionaries serialized as JSON, or lists of content with specific types (text, image, etc.). The return type determines how the model interprets and presents the result to the user.

Why learn:

Choosing the right return type affects how the model uses the result. Well-formatted returns allow the model to generate more accurate and useful responses.

Key concepts:

Return a string, return a dict, TextContent, ImageContent, serialization, response formatting.

What it is:

Tool descriptions come from the Python functions’ docstrings. The model reads these descriptions to decide when and how to use each tool. Clear, specific descriptions help the model use your tools more intelligently and accurately.

Why learn:

Description quality directly affects the quality of interactions. A poorly described tool will be ignored or misused by the model.

Key concepts:

Docstrings, tool descriptions, parameter descriptions, prompt engineering for tools, clarity.

What it is:

MCP tool best practices include descriptive snake_case names, detailed docstrings, type hints for all parameters, default values when appropriate, informative return values, and consistent error handling.

Why learn:

Following best practices from the start builds habits that lead to more robust servers that are easier to maintain and more effective at interacting with the model.

Key concepts:

Naming conventions, documentation, type safety, default values, error handling, consistency.

View Full
Module 3.4 ~35 min · Hands-on

🔢 Calculator Server

4 tools (add, subtract, multiply, divide) with input validation.

What it is:

Planning the calculator's tools involves defining 4 mathematical operations (add, subtract, multiply, divide), their parameters (two numbers), input types (float), and special behaviors such as validating division by zero.

Why learn:

Planning before coding is an essential habit. Defining the tools' interface before implementing them ensures consistency and avoids rework.

Key concepts:

API planning, interface definition, consistent parameters, edge cases, validation.

What it is:

Implementing addition and subtraction as MCP tools involves creating decorated functions that take two float parameters, perform the operation, and return the formatted result. They are the simplest tools and serve as a model for the next ones.

Why learn:

Starting with the simplest operations lets you focus on the implementation pattern. Once addition and subtraction work, multiplication and division follow the same model.

Key concepts:

Tool implementation, float parameters, formatted return value, descriptive docstrings, replicable pattern.

What it is:

The multiplication tool follows the same pattern as the previous tools, but introduces an opportunity to discuss formatting results with many decimal places and presenting large numbers in a readable way for the model.

Why learn:

The multiplication seems trivial, but it raises practical questions about formatting and numerical precision that matter for any tool that works with numbers.

Key concepts:

Multiplication, number formatting, decimal precision, large numbers, result presentation.

What it is:

The division tool introduces the first real input validation case: checking whether the divisor is zero before performing the operation. This demonstrates how to handle errors elegantly and return informative messages to the model.

Why learn:

Input validation is a critical skill for any server. Division by zero is the perfect example for introducing how tools should handle invalid inputs.

Key concepts:

Input validation, division by zero, error message, conditional return, robustness.

What it is:

Testing all calculator tools involves checking each operation with different types of input: integers, decimals, negative numbers, zero, and very large numbers. It includes testing division by zero to confirm that validation works.

Why learn:

Comprehensive testing ensures that your server works in every scenario. Making a habit of testing with varied inputs helps prevent bugs in production.

Key concepts:

Manual testing, test cases, edge cases, varied inputs, validation checks.

What it is:

Improving the calculator with robust error handling includes adding try/except to catch unexpected exceptions, validating input types, limiting the size of accepted numbers, and returning standardized error messages the model can interpret.

Why learn:

Turning a working prototype into robust code is a professional skill. This step shows you how to evolve your server from “works” to “always works.”

Key concepts:

Try/except, robust validation, input limits, standardized error messages, defensive programming.

View Full
Module 3.5 ~35 min · Hands-on

🌤️ Weather Lookup Server

Tool that queries an external API and returns formatted data.

What it is:

Choosing a free and reliable weather API is the first step in building the server. APIs like Open-Meteo offer weather data without requiring an API key, making setup simpler and more accessible for learning.

Why learn:

Knowing how to choose and evaluate external APIs is an essential skill. Many MCP Servers in practice are wrappers that connect AI models to existing APIs.

Key concepts:

Weather API, Open-Meteo, free API, endpoints, API documentation, rate limits.

What it is:

Making HTTP requests inside an MCP Server requires asynchronous libraries such as httpx, since FastMCP runs on an asyncio event loop. The requests fetch data from the API and return JSON responses that need to be parsed.

Why learn:

HTTP requests are the foundation of any integration with external services. Mastering asynchronous calls ensures your server doesn’t hang while waiting for API responses.

Key concepts:

httpx, async/await, GET request, JSON parsing, headers, query parameters.

What it is:

Implementing the weather tool involves creating a decorated async function that takes the city name as a parameter, makes the API request, extracts the relevant data (temperature, humidity, condition), and returns a formatted string with the information.

Why learn:

This is the first tool that connects your server to the outside world. The pattern of receiving input, fetching data, and formatting a response is used in 80% of real MCP Servers.

Key concepts:

async def, city parameter, API call, data extraction, response formatting.

What it is:

Formatting the response means transforming raw API data into an organized, readable string. This includes presenting temperature with units, weather conditions as descriptive text, and additional information in a structured way for the model to interpret.

Why learn:

Formatting quality determines how well the model interprets and presents data to the user. Well-formatted data leads to more natural and informative responses.

Key concepts:

Data formatting, f-strings, units of measurement, information structuring, readability.

What it is:

Network errors are inevitable: the API may be down, the connection may drop, or the response may come in an unexpected format. Handling these errors involves try/except for httpx.HTTPError, configurable timeouts, and informative error messages.

Why learn:

Tools that depend on external APIs need to be resilient. Without error handling, a network failure takes down the entire server instead of returning a helpful message.

Key concepts:

HTTPError, timeout, ConnectionError, retry logic, fallback, user-friendly error message.

What it is:

Testing with Claude involves asking about the weather in different cities and checking that the model calls the tool correctly, receives the data, and presents the information naturally to the user. It includes testing with nonexistent cities to validate error handling.

Why learn:

Testing with Claude is the real integration test. It shows how the model decides when to use your tool and how it interprets the results it returns.

Key concepts:

Integration testing, interaction with Claude, real tool calling, end-to-end validation, error scenarios.

View Full
Module 3.6 ~30 min · Hands-on

📦 Adding Resources

Expose static and dynamic data as Resources for the model to consume.

What it is:

In code, Resources are functions decorated with @mcp.resource() that return data when accessed through a specific URI. Unlike tools, resources don’t perform actions—they expose information that the model can read to enrich its context.

Why learn:

Resources are the second pillar of an MCP Server. Implementing them in code builds on the theoretical knowledge from Track 1 and expands your server’s capabilities.

Key concepts:

@mcp.resource(), URI, data return, context exposure, difference from tools.

What it is:

Static resources always return the same content — such as documentation, guides, default settings, or any data that doesn’t change between calls. They’re the simplest to implement and ideal for reference context.

Why learn:

Static resources are the simplest way to provide rich context to the model. They can improve response quality by giving the model always-available reference information.

Key concepts:

Static content, documentation, settings, reference guides, immutable data.

What it is:

Dynamic resources calculate or retrieve data on each access—such as the current system status, data from a database, or information that changes over time. They use the same URIs but return updated content.

Why learn:

Dynamic resources let the model access real-time data without tool calls. They’re ideal for dashboards, status, and frequently changing information.

Key concepts:

Dynamic content, real-time data, on-demand calculations, automatic updates, freshness.

What it is:

URI schemes define how resources are identified and accessed. Each resource has a unique URI (e.g., config://app/settings, data://users/list) that the Client uses to request its content. The scheme indicates the type, and the path indicates the specific resource.

Why learn:

Well-designed URIs make your resources intuitive and organized. A good URI scheme makes it easy for the model to discover and use resources.

Key concepts:

URI, scheme, path, unique identification, naming conventions, resource hierarchy.

What it is:

The MCP protocol lets the Client list all resources available on the Server via resources/list. This enables automatic discovery: the model knows what data is available without needing external documentation.

Why learn:

The resource listing is what makes the protocol self-documenting. The model can explore the available resources and choose the most relevant ones for each situation.

Key concepts:

resources/list, automatic discovery, self-documentation, resource metadata, dynamic listing.

What it is:

Testing resources involves checking that they appear in the list, their URIs are accessible, the returned content is correct, and dynamic resources update their data. You can test via Claude or the MCP Inspector.

Why learn:

Testing resources ensures the model has access to the correct data. Broken resources can cause the model to generate responses based on outdated or incorrect information.

Key concepts:

Resource testing, URI verification, correct content, dynamic updates, debugging.

View Full
Module 3.7 ~25 min · Hands-on

📝 Adding Prompts

Create reusable prompts that the model can invoke.

What it is:

In code, Prompts are functions decorated with @mcp.prompt() that return predefined message templates. They can accept parameters for customization and return a list of messages that guide the model’s behavior.

Why learn:

Prompts are the third pillar of MCP and its most underused. Implementing them in code completes your mastery of the three capabilities of an MCP Server.

Key concepts:

@mcp.prompt(), message templates, parameters, message list, role (user/assistant).

What it is:

A simple prompt is a function that returns a fixed message without accepting parameters. For example, a prompt that instructs the model to act as a code reviewer or debugging assistant, with detailed instructions about the expected behavior.

Why learn:

Simple prompts are the most accessible starting point. They demonstrate the mechanism without the complexity of parameters, letting you focus on structure and format.

Key concepts:

Prompt with no parameters, fixed message, behavior instruction, return format, simplicity.

What it is:

Prompts with parameters accept arguments that customize the generated message. For example, a code review prompt that takes the programming language and review focus as parameters, generating specific instructions for each case.

Why learn:

Parameterized prompts are much more versatile than fixed prompts. They let you create reusable templates that adapt to different contexts with a single piece of code.

Key concepts:

Prompt parameters, dynamic templates, f-strings in prompts, customization, reuse.

What it is:

Like tools and resources, prompts can be listed by the Client via prompts/list. The listing shows each prompt’s name, description, and accepted parameters, allowing the Host to offer the user a selection interface.

Why learn:

The prompt listing is how the Host discovers which workflows are available. Well-documented prompts appear clearly in the user interface.

Key concepts:

prompts/list, prompt discovery, metadata, parameter descriptions, Host interface.

What it is:

The best use cases for MCP prompts include standardized workflows (code review, data analysis), onboarding new users, domain-specific instructions, and templates that combine resource context with instructions for using tools.

Why learn:

Knowing when to use prompts vs. tools vs. resources is an important design decision. Prompts shine in scenarios where the model’s behavior needs to be guided consistently.

Key concepts:

Standardized workflows, onboarding, domain instructions, combining with tools and resources, consistency.

What it is:

Testing prompts involves checking that they appear in the list, accept parameters correctly, and that the generated messages guide the model as expected. The test includes checking the model's behavior when the prompt is activated.

Why learn:

Poorly tested prompts can make the model behave unexpectedly. Testing ensures the instructions are clear and produce the desired behavior.

Key concepts:

Prompt testing, parameter validation, behavior checks, instruction quality, iteration.

View Full
Module 3.8 ~25 min · Hands-on

⚠️ Error Handling

How to handle failures, timeouts, and invalid inputs gracefully.

What it is:

Errors in MCP Servers fall into categories: input errors (invalid parameters), runtime errors (logic failures), network errors (inaccessible APIs), system errors (out of memory, disk full), and protocol errors (malformed messages).

Why learn:

Classifying errors is the first step to handling them correctly. Each type of error requires a different handling strategy and an appropriate response message.

Key concepts:

Input errors, runtime errors, network errors, system errors, classification, strategy.

What it is:

Input validation is the process of checking that the received parameters are valid before running the tool's logic. This includes checking types, ranges, string formats, list sizes, and any conditions the data must meet.

Why learn:

Input validation is the first line of defense against errors. Rejecting bad inputs is easier and safer than dealing with the cascading errors they cause during execution.

Key concepts:

Input validation, type checking, range checking, early return, clear rejection messages.

What it is:

Using try/except in tools lets you catch exceptions during execution and return helpful error messages instead of crashes. The recommended pattern is to catch specific exceptions, log the error, and return a message the model can use to inform the user.

Why learn:

A well-implemented try/except is the difference between a server that crashes and one that recovers gracefully. Unhandled exceptions can bring down the entire MCP server.

Key concepts:

try/except, specific exceptions, logging, recovery, error message as return value.

What it is:

Network errors include connection refused, DNS resolution failure, connection timeout, and HTTP responses with error status codes. Each type requires specific handling: retry for transient errors, fallback for prolonged outages.

Why learn:

If your server depends on external APIs, network errors are inevitable. Knowing how to handle them ensures your server remains useful even when external services fail.

Key concepts:

ConnectionError, TimeoutError, HTTP status codes, retry, fallback, circuit breaker.

What it is:

Timeouts limit how long an operation can take before it is canceled. In MCP tools, it's essential to configure timeouts for network calls, disk operations, and any processing that could stall. asyncio.wait_for() is the standard tool.

Why learn:

Without timeouts, a tool can hang indefinitely, blocking the server and frustrating the user. Timeouts ensure the server always responds within a reasonable time.

Key concepts:

asyncio.wait_for(), configurable timeout, TimeoutError, cancellation, response time.

What it is:

Logging in MCP Servers uses Python’s logging module to record events, errors, and debug information. Logs should go to stderr (not stdout, which is used by the protocol). Levels such as DEBUG, INFO, WARNING, and ERROR help filter information.

Why learn:

Without logs, debugging an MCP Server is like navigating in the dark. Good logs are essential for diagnosing problems in development and production.

Key concepts:

logging module, stderr vs stdout, log levels, formatting, debugging in production, traceability.

View Full
Module 3.9 ~30 min · Hands-on

🔍 Testing with MCP Inspector

Use MCP Inspector to debug and test tools without needing Claude.

What it is:

The MCP Inspector is an official tool that lets you connect to an MCP Server and interactively test its tools, resources, and prompts without needing an AI model. It works as an MCP Client with a visual interface.

Why learn:

The Inspector is the most efficient tool for developing and debugging MCP Servers. It lets you test quickly without relying on Claude Desktop, speeding up the development cycle.

Key concepts:

MCP Inspector, testing tool, visual interface, MCP Client, rapid development.

What it is:

You can run the MCP Inspector via npx without a permanent installation. The command npx @modelcontextprotocol/inspector starts the tool and opens a web interface where you can connect to your server and explore its capabilities.

Why learn:

Installing and running the Inspector quickly is a practical skill that speeds up your entire MCP development workflow. It’s a tool you’ll use constantly.

Key concepts:

npx, @modelcontextprotocol/inspector, web interface, no permanent installation, Node.js.

What it is:

Connecting the Inspector to your server involves specifying the command to start the server (e.g., python server.py), the transport (usually STDIO), and clicking Connect. The Inspector performs the MCP handshake and lists all available capabilities.

Why learn:

Knowing how to connect the Inspector to your server is the essential first step to using it. The connection immediately reveals whether there are startup or configuration issues with your server.

Key concepts:

STDIO connection, execution command, handshake, capabilities, troubleshooting.

What it is:

The Inspector lets you select any listed tool, fill in its parameters manually, and run it. The result appears in the interface with full details: returned content, execution time, and any errors that occurred.

Why learn:

Testing tools in the Inspector is much faster than testing via Claude. You can iterate quickly, test edge cases, and verify that your tools work correctly before integrating them.

Key concepts:

Manual execution, parameter entry, result viewing, execution time, rapid iteration.

What it is:

Analyzing responses in the Inspector means examining the content returned by tools, resources, and prompts in raw format. You can see exactly the JSON the server sends, including content types, metadata, and response structure.

Why learn:

Viewing the raw responses lets you understand exactly what the model receives. This is crucial for optimizing formatting and ensuring the responses are interpretable.

Key concepts:

Raw responses, JSON, content types, metadata, formatting, output analysis.

What it is:

The Inspector shows detailed errors when something goes wrong: Python stack traces, protocol errors, timeouts, and connection issues. Combined with server logs, it lets you quickly identify the root cause of any problem.

Why learn:

Efficient debugging is what separates a productive developer from one who gets stuck for hours. Inspector is your main tool for diagnosing and resolving problems in MCP Servers.

Key concepts:

Stack traces, protocol errors, diagnostics, root cause, fix, debug-fix-test cycle.

View Full
← Previous Track Next Track →