Create your first functional MCP Server—a simple tool that returns "Hello, world!"—and connect it to Claude Desktop.
In this module, we’ll create the simplest MCP Server possible: a single tool that takes a name and returns a greeting. The goal isn’t to impress with complexity, but to understand every line of code and the complete flow—from the Python code to Claude using the tool. If you fully understand Hello World, building complex servers will simply be a matter of adding more tools.
O Hello World MCP is a server with a single tool: hello(nome: str) that returns f"Olá, {nome}!". It’s the equivalent of “Hello World” in any programming language—the smallest functional program possible. The difference is that, instead of printing to the terminal, this function will be called by an AI through the MCP protocol. The model decides when to call it, passes the parameters, and receives the result.
Resist the temptation to add extra features to Hello World. The goal here is total clarity, not functionality. When you understand every line of this minimal server, you’ll be able to build anything. Think of it as learning to walk before you run — a solid foundation now will save you hours of debugging later.
Let's use the uv to create and configure the project. uv takes care of everything: it initializes the project with pyproject.toml, creates the virtual environment, and installs the dependencies. In three commands, you'll have a Python project ready for the server code.
Project creation uses three commands: uv init hello-mcp — creates the directory with pyproject.toml; cd hello-mcp — enters the directory; and uv add fastmcp — adds FastMCP as a dependency. Then, create the file server.py where the server code will go. In less than 30 seconds, you have a complete, configured Python project.
Execute uv init hello-mcp — creates the project directory with pyproject.toml, .python-version, and an initial structure.
Go to the directory with cd hello-mcp — all the following commands must be run from inside the project.
Execute uv add fastmcp — installs FastMCP and all its dependencies in the project's virtual environment.
Create the file server.py in the project root directory—this is where we’ll write the MCP Server code.
If you already have the uv installed, you can do everything in one line: uv init hello-mcp && cd hello-mcp && uv add fastmcp. uv is extremely fast—the installation of FastMCP and all its dependencies takes just a few seconds, much faster than traditional pip.
Now comes the most satisfying part: writing the server code. It’s only 10 lines—but each one has a specific purpose. Don’t copy and paste without understanding; read each line and understand what it does. This is the code that turns an ordinary Python function into a capability accessible to any MCP-compatible AI.
The complete code for the Hello World MCP Server:
These ~10 lines make up a complete, working MCP Server. FastMCP handles the entire protocol behind the scenes—JSON-RPC, transport, capability negotiation, serialization—you only need to worry about your tool's logic.
Without FastMCP, implementing the same server using the low-level MCP protocol would require more than 150 lines of code — including JSON-RPC parsing, stdio transport management, capability negotiation, schema serialization, and protocol error handling. FastMCP reduces this to ~10 lines, a reduction of more than 90% in the code required. That's the advantage of using a well-designed framework.
With the code ready, it’s time to connect the server to Claude Desktop. You do this by editing Claude’s configuration file and adding an entry for your server. Claude Desktop will use the uv to start the server automatically when needed.
Add to the file claude_desktop_config.json of Claude Desktop:
Replace /caminho/completo/hello-mcp with the actual absolute path to your project. Then restart Claude Desktop so it detects the new server.
The path in --directory must be absolute — relative paths don't work. Use the full path, such as /home/usuario/projetos/hello-mcp on Linux/Mac or C:\\Users\\usuario\\projetos\\hello-mcp on Windows. An incorrect path is the number one reason a "server doesn’t appear in Claude"—check carefully!
With the server configured and Claude Desktop restarted, it’s time for the magic moment: testing whether everything works. Open a new conversation in Claude and ask it to use the tool. If everything is correct, Claude will automatically identify the tool, call it with the right parameters, and display the result. This is the MCP experience working end to end.
To test, open Claude Desktop and type something like "Say hello to Maria". Claude should: (1) recognize that it has a tool hello available; (2) decide to use it to fulfill the request; (3) call the tool with nome="Maria"; (4) receive the result "Olá, Maria!"; e (5) present the result in the conversation. If that happens, congratulations — your first MCP Server is working!
If the tool doesn’t appear in Claude Desktop, check: (1) the path in config.json is correct and absolute; (2) uv is installed and accessible; (3) Claude Desktop was restarted; (4) the server.py file has no syntax errors. You can test the server manually with uv run server.py in the terminal — if you get an error, the problem is in the code.
Open Claude Desktop and start a new conversation.
Check whether the tools icon (hammer) appears — it indicates that MCP Servers are connected.
Type "Say hello to Maria" and send the message.
Claude will ask permission to use the "hello" tool — click "Allow" to authorize it.
Check that the result displays "Hello, Maria!" — your MCP Server is working!
Now that the server works, let’s go back to the code and break down each line in detail. Understanding the “why” behind each element is what separates copying code from understanding it. Each line of Hello World has a specific role in how the MCP Server works, and none of them is superfluous.
from fastmcp import FastMCP — brings the framework into your code. Without it, Python doesn't know what FastMCP is.
mcp = FastMCP("hello-mcp") — creates the server object. The name identifies the server in the client.
@mcp.tool() — registers the function as an MCP tool. Without the decorator, it's just a regular Python function.
def hello(nome: str) -> str — the tool logic. The function name becomes the tool name.
nome: str e -> str — define the tool schema. The model knows it needs to send a string and will receive a string.
"""Diz olá para a pessoa informada.""" — becomes the description of the tool that the model reads to decide when to use it.
Each code element has a direct mapping in the MCP protocol: the function name becomes the field name of the tool; the type hints become the inputSchema (JSON Schema); the docstring becomes the field description; e o return value becomes the content of the response. FastMCP handles this translation automatically — you write idiomatic Python, and the framework generates the correct MCP protocol.
Try changing things and see what happens: change the docstring and see how Claude describes the tool; add a second parameter and see Claude ask for the extra information; change the function name and see the new name appear in Claude. This hands-on experimentation is the best way to internalize how each part of the code connects to the MCP Server’s behavior.
hello that returns a personalized greeting.
uv init e uv add fastmcp — complete setup in seconds.
claude_desktop_config.json with an absolute path required.
Next Module: 3.3 — Understanding Decorators and Schemas