In the previous labs, we connected a Strands Agent to an existing MCP server and used its tools.
But what if you want to create your own MCP server?
That's exactly what we'll do in this lab.
We'll build a Calculator MCP Server that exposes arithmetic operations such as addition, subtraction, multiplication, and division. Then we'll connect a Strands Agent to that server using Streamable HTTP transport.
By the end of this tutorial, you'll understand both sides of the MCP ecosystem:
- MCP Server
- MCP Client
- Strands Agent
📚 Strands Agentic AI Lab Series
⬅️ Previous: Lab 06: Connecting to MCP with STDIO
📍 Current: Lab 07: Build Your First MCP Server
➡️ Next: Lab 08: Advanced MCP Tools & Multi-Tool Workflows
🚀 What You'll Learn
In this lab, you'll learn:
- How to create an MCP Server
- How MCP tools are exposed
- How Streamable HTTP transport works
- How to connect a Strands Agent to a custom MCP server
- How agents invoke MCP tools automatically
🤖 Why Build Your Own MCP Server?
Previously we consumed an existing MCP server.
Agent
↓
AWS Documentation MCP Server
Now we'll build one ourselves.
Agent
↓
Your MCP Server
↓
Your Tools
This allows you to expose:
- Internal APIs
- Databases
- Business Logic
- Enterprise Systems
- Custom Applications
through a standard MCP interface.
🏗️ Architecture
Our solution looks like this:
User
↓
Strands Agent
↓
MCP Client
↓
Calculator MCP Server
↓
Calculator Tools
The agent doesn't perform calculations directly.
Instead, it delegates them to MCP tools.
🛠️ Prerequisites
Before starting, ensure you have:
- Python 3.10+
- Strands SDK
- MCP SDK
- AWS Bedrock access
- uv installed
Install dependencies:
pip install strands-agents
pip install mcp
📜 The Complete Script
This example creates:
- An MCP Calculator Server
- Four calculator tools
- A Strands Agent
- An interactive chat loop
The agent automatically uses MCP tools whenever calculations are required.
⚙️ Step 1: Create the MCP Server
mcp = FastMCP("Calculator Server")
This initializes a new MCP server.
Think of it as:
Web Framework
↓
Routes
but for AI tools.
MCP Server
↓
Tools
⚙️ Step 2: Create MCP Tools
Addition Tool
@mcp.tool(description="Add two numbers together")
def add(x: int, y: int) -> int:
return x + y
Subtraction Tool
@mcp.tool(description="Subtract one number from another")
def subtract(x: int, y: int) -> int:
return x - y
Multiplication Tool
@mcp.tool(description="Multiply two numbers together")
def multiply(x: int, y: int) -> int:
return x * y
Division Tool
@mcp.tool(description="Divide one number by another")
def divide(x: float, y: float) -> float:
if y == 0:
raise ValueError("Cannot divide by zero")
return x / y
Every tool becomes automatically discoverable through MCP.
No additional registration is required.
⚙️ Step 3: Start the MCP Server
mcp.run(
transport="streamable-http"
)
This launches the MCP server using Streamable HTTP transport.
Server endpoint:
http://localhost:8000
Now other MCP clients can connect.
⚙️ Step 4: Run the Server in a Background Thread
server_thread = threading.Thread(
target=start_calculator_server,
daemon=True
)
Why?
Because we need:
Calculator Server
+
Strands Agent
running simultaneously.
The background thread keeps the server alive while the agent runs.
⚙️ Step 5: Connect the MCP Client
def create_streamable_http_transport():
return streamablehttp_client(
"http://localhost:8000/mcp/"
)
This creates an MCP Client connection.
Architecture:
Agent
↓
MCP Client
↓
HTTP Transport
↓
Calculator Server
⚙️ Step 6: Discover Available Tools
tools = streamable_http_mcp_client.list_tools_sync()
This is one of MCP's biggest advantages.
Instead of manually registering tools:
tools=[add, subtract]
the client automatically discovers them.
Example:
Available MCP tools:
add
subtract
multiply
divide
⚙️ Step 7: Create the Agent
agent = Agent(
model=bedrock_model,
system_prompt=system_prompt,
tools=tools
)
Notice:
tools=tools
Those tools came directly from the MCP Server.
No custom integration required.
⚙️ Step 8: Interactive Calculator Assistant
while True:
user_input = input("Question: ")
response = agent(user_input)
print(response)
This creates a conversational calculator.
Example:
Question:
What is 125 * 42?
Agent:
5250
Behind the scenes:
Agent
↓
multiply()
↓
5250
▶️ Run the Application
Execute:
python agent.py
Or:
uv run labs/07-mcp-calculator-server/agent.py
📊 Example Interaction
User
What is 25 + 17?
Agent Workflow
Question
↓
Agent Reasoning
↓
add Tool
↓
42
↓
Response
Response
25 + 17 = 42
🔍 What Happened Behind the Scenes?
When you asked:
What is 25 + 17?
the agent:
- Understood the request.
- Found an MCP tool capable of addition.
- Invoked the tool.
- Received the result.
- Generated a response.
The actual calculation happened in the MCP Server.
Not in the LLM.
💡 Why This Matters
This simple calculator demonstrates a powerful concept.
Today:
add()
subtract()
multiply()
divide()
Tomorrow:
Create Customer
Generate Invoice
Query Database
Deploy Lambda
Update CRM
The exact same MCP architecture scales to enterprise applications.
🎯 Key Takeaways
- MCP Servers expose tools to AI agents
- FastMCP makes building servers simple
- Streamable HTTP enables remote communication
- Agents automatically discover tools
- MCP separates tool implementation from agent logic
- This pattern scales from calculators to enterprise systems
📚 Source Code
Lab Source Code:
Your GitHub Repository
🔗 Continue Learning
⬅️ Previous Lab
Lab 05: Connecting to an MCP Server with STDIO Transport | Strands Agentic AI
➡️ Next Lab
Lab 07: Building Multi-Agent Systems with an Orchestrator | Strands Agentic AI
🚀 Next Lab
In the next tutorial, we'll build more sophisticated MCP tools, explore tool schemas, and learn how agents can choose between multiple MCP capabilities to solve complex tasks.
Top comments (0)