Build Our First MCP Tool
Table of Contents + −
From the previous chapter, our MCP server is running, and we have connected it to Jan.
Now let’s make our server actually do something. 🚀
We’ll start with a very simple tool:
add(10, 20)The tool will take two numbers, add them together, and return the result.
By the end of this chapter, we’ll be able to ask our AI:
What is 10 + 20?and the AI will be able to use our MCP tool to calculate the answer.
Let’s build it step by step.
🛠️ 5.1 What Is an MCP Tool?
An MCP tool is a function that an MCP server makes available to an MCP client.
The function can perform some action on behalf of the AI application.
For example, a tool could:
add two numbersread a filequery a databasecall an APIsearch documentscreate a ticketIn our case, we’ll start with something much simpler:
add(10, 20)Think of it like this:
The important idea is that the AI doesn’t implement the calculation itself.
Instead, it can ask the MCP server to execute the tool.
✍️ 5.2 Define Our First Tool
Open the server.py file we created earlier.
Currently, we have:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Calculator Server")
if __name__ == "__main__": mcp.run()Let’s add our first tool.
Add the following function:
@mcp.tool()def add(a: int, b: int) -> int: return a + bOur complete server now looks like this:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Calculator Server")
@mcp.tool()def add(a: int, b: int) -> int: return a + b
if __name__ == "__main__": mcp.run()That’s our first MCP tool! 🎉
But there are several things happening in these few lines, so let’s understand them.
🧩 5.3 How Do We Define a Tool?
The MCP Python SDK provides the @mcp.tool() decorator.
@mcp.tool()This tells the MCP server:
“Expose the following Python function as an MCP tool.”
Without this decorator, add() would simply be a normal Python function.
With the decorator, it becomes a tool that MCP clients can discover and call.
So:
def add(a: int, b: int) -> int:is a normal Python function, while:
@mcp.tool()def add(a: int, b: int) -> int:is an MCP tool.
🏷️ 5.4 Tool Name
Our tool is called:
addThe name comes from the Python function name:
def add(a: int, b: int) -> int:So an MCP client will see a tool named:
addTool names should be clear and descriptive.
For example:
addsubtractsearch_documentsget_weathercreate_ticketA good tool name makes it easier for an AI model to understand what the tool does.
📝 5.5 Tool Description
A tool also needs a description.
The description helps the AI understand when and why it should use the tool.
Let’s add one to our tool:
@mcp.tool()def add(a: int, b: int) -> int: """Add two numbers together.""" return a + bNow the complete function is:
@mcp.tool()def add(a: int, b: int) -> int: """Add two numbers together.""" return a + bThe description is:
Add two numbers together.This may look like a small detail, but descriptions become very important when a server exposes many tools.
For example, imagine our server has:
addsearch_documentscreate_ticketget_customerdelete_customerThe AI needs enough information to understand what each tool does.
A clear description helps it choose the right tool.
🔢 5.6 Tool Arguments
Our tool needs two numbers.
We define them here:
def add(a: int, b: int) -> int:The arguments are:
abBoth are integers:
a: intb: intSo our tool expects:
a → integerb → integerFor example:
a = 10b = 20The tool receives:
add(10, 20)and performs:
10 + 20↩️ 5.7 Return Value
The function returns:
return a + bSo:
add(10, 20)returns:
30We also specify the return type:
-> intSo the function signature tells us:
def add(a: int, b: int) -> int:In simple terms:
Input: a → integer b → integer
Output: integerThis information is also useful to the MCP SDK when exposing the tool to clients.
🧾 5.8 Our Complete MCP Tool
Let’s look at the complete tool again:
@mcp.tool()def add(a: int, b: int) -> int: """Add two numbers together.""" return a + bWe can break it down like this:
Now we have a real MCP tool.
▶️ 5.9 Run Our MCP Server
Let’s start the server again.
From the project directory:
python server.pyOur server is now running with the add tool available.
The architecture has changed slightly:
But how does Jan know that the add tool exists?
That’s where MCP’s tool discovery mechanism comes in.
When an MCP client connects to our server, it can discover the tools that the server exposes.
We’ll look at exactly how that works in a later chapter.
For now, let’s use the tool.
🧪 5.10 Try Our First Tool
Open Jan and make sure our MCP server is connected.
Now ask:
What is 10 + 20?The AI can determine that it needs to perform an addition and use our add tool.
Conceptually, the flow is:
🎉 We’ve just built and used our first MCP tool!
✅ 5.11 What We Have Learned
Our first tool was intentionally simple, but it introduced the core pieces of an MCP tool.
We learned:
| Part | Example |
|---|---|
| Tool decorator | @mcp.tool() |
| Tool name | add |
| Description | Add two numbers together. |
| Arguments | a, b |
| Argument types | int, int |
| Return type | int |
| Implementation | return a + b |
Our server now looks like:
This is the basic pattern we’ll use for every tool we build later.
In the next chapter, we’ll take a closer look at what happens between Jan and our MCP server.
We’ll see how the client discovers our add tool and how it asks the server to execute it.