Connect Our MCP Server to an MCP Client
Table of Contents + −
In the previous chapter, we have built our first MCP tool:
add(10, 20)We also connected our MCP server to Jan.
Now let’s understand what actually happens when Jan uses our tool.
The basic flow is:
Let’s break this down step by step.
🔗 6.1 What Is an MCP Client?
An MCP client is the component that connects to an MCP server and communicates with it using the MCP protocol.
In our setup, Jan acts as the application that uses the MCP connection.
The client is responsible for things such as:
- Connecting to the MCP server
- Discovering available capabilities
- Requesting available tools
- Calling tools
- Receiving tool results
Think of the client as the bridge between the AI model and our MCP server.
The overall architecture looks like this:
The AI model decides that it needs to perform an operation.
The MCP client communicates with the MCP server to perform that operation.
🤝 6.2 How Does the Client Connect?
Before the client can use our tools, it needs to establish a connection with the MCP server.
In our example, Jan starts or connects to the MCP server that we configured earlier.
The connection looks like:
Once the connection is established, the client and server can exchange MCP messages.
It’s important to understand that the client and server are separate components.
Our Python application is the MCP server.
Jan is the MCP host application, which uses an MCP client connection to communicate with our server.
🔎 6.3 How Does the Client Discover Our Tool?
Our server currently exposes one tool:
@mcp.tool()def add(a: int, b: int) -> int: """Add two numbers together.""" return a + bBut how does Jan know that add exists?
The client can ask the MCP server:
What tools do you provide?MCP defines a standard operation for this:
tools/listConceptually:
The server responds with information about its available tools.
For our server, the response contains information describing the add tool, including things such as:
Name:add
Description:Add two numbers together.
Arguments:abThe client can then make this information available to the AI model.
This is an important part of MCP.
The client doesn’t need to have our add() function hardcoded into it.
It discovers the tool from the server.
💡 6.4 Why Is Tool Discovery Important?
Imagine that our server eventually has dozens of tools:
addsubtractmultiplydividesearch_documentsread_filecreate_ticketget_customer...We don’t want the MCP client to know about all these tools beforehand.
Instead, the server tells the client what it provides.
This makes MCP servers reusable.
A client can connect to a new MCP server and discover its capabilities dynamically.
The basic flow is:
📞 6.5 How Does the Client Call the Tool?
Now let’s say we ask Jan:
What is 10 + 20?The AI model understands that it needs to perform an addition.
It sees that an add tool is available.
The client can then request that the server execute the tool.
MCP defines the operation:
tools/callConceptually:
The server executes our Python function:
def add(a: int, b: int) -> int: return a + bThe result is:
30The result is then returned to the client.
The AI can then use that result to respond to the user.
🔄 6.6 The Complete Flow
Let’s put everything together.
When we ask:
What is 10 + 20?the simplified flow is:
There are actually several protocol messages and steps involved, but this simplified flow gives us the right mental model.
⚖️ 6.7 Discovery vs Execution
There are two important operations to remember:
🔎 tools/list
Used to discover available tools.
Client → Server
tools/listThe server responds with information about its tools.
📞 tools/call
Used to execute a tool.
Client → Server
tools/call add(10, 20)The server executes the tool and returns the result.
So:
tools/list ↓"What tools do you have?"
tools/call ↓"Execute this tool."That’s the basic mechanism behind what we just built.
🏗️ 6.8 Our MCP Architecture So Far
We now have a complete working flow:
And that gives us the foundation we need to build more useful MCP servers.
Our calculator server currently has only one tool:
In the next chapter, we’ll expand it into a proper calculator by adding:
We’ll also look at parameters, input validation, and error handling as our server becomes more useful.