Documentation Index
Fetch the complete documentation index at: https://mintlify.com/alexyslozada/mcp-course/llms.txt
Use this file to discover all available pages before exploring further.
Calculator Operations Server
This example demonstrates how to build a simple MCP server in Python using the FastMCP framework. It’s perfect for understanding the basics of MCP tool implementation.
Overview
The Calculator server shows:
- FastMCP Framework: Quick server setup with minimal boilerplate
- Tool Registration: Simple decorator-based tool registration
- Input Validation: Parameter validation and error handling
- Basic Operations: Addition, subtraction, multiplication, and division
Complete Implementation
from mcp.server.fastmcp import FastMCP
# Initialize the MCP server
mcp = FastMCP("Calculator MCP Server")
# Basic arithmetic operations
def add(a: float, b: float) -> float:
return float(a + b)
def subtract(a: float, b: float) -> float:
return float(a - b)
def multiply(a: float, b: float) -> float:
return float(a * b)
def divide(a: float, b: float) -> float:
if b == 0:
raise ValueError("No se puede dividir por cero")
return float(a / b)
# Register the calculator tool
@mcp.tool()
def calculate(a: float, b: float, operation: str) -> float:
"""
Perform basic arithmetic operations.
Args:
a: First number
b: Second number
operation: Operation to perform (add, subtract, multiply, divide)
Returns:
Result of the operation
Raises:
ValueError: If operation is invalid or division by zero
"""
if operation == "add":
return add(a, b)
elif operation == "subtract":
return subtract(a, b)
elif operation == "multiply":
return multiply(a, b)
elif operation == "divide":
return divide(a, b)
else:
raise ValueError("Operación no válida")
# Run the server
if __name__ == "__main__":
mcp.run(transport='stdio')
Understanding the Code
FastMCP Initialization
mcp = FastMCP("Calculator MCP Server")
FastMCP provides a simple way to create MCP servers with minimal configuration. The server name is used for identification.
@mcp.tool()
def calculate(a: float, b: float, operation: str) -> float:
...
The @mcp.tool() decorator automatically:
- Registers the function as an MCP tool
- Extracts parameter types from type hints
- Generates JSON schema for the tool
- Handles serialization/deserialization
Error Handling
def divide(a: float, b: float) -> float:
if b == 0:
raise ValueError("No se puede dividir por cero")
return float(a / b)
Errors are propagated to the client as tool execution errors, making debugging easier.
Installation & Setup
Dependencies
Create a pyproject.toml or requirements.txt:
[project]
name = "calculator-mcp-server"
version = "1.0.0"
requires-python = ">=3.10"
dependencies = [
"mcp>=1.0.0"
]
Or using requirements.txt:
Installation
# Using pip
pip install mcp
# Or using uv
uv pip install mcp
Running the Server
Standalone Mode
The server runs in stdio mode, waiting for MCP client connections.
With MCP Inspector
Use the MCP Inspector to test your server:
npx @modelcontextprotocol/inspector python server.py
Using the Calculator
From Python Client
import asyncio
from mcp_client import MCPClient
async def main():
async with MCPClient("python", ["server.py"]) as client:
# List available tools
tools = await client.list_tools()
print("Available tools:", tools)
# Perform addition
result = await client.execute_tool("calculate", {
"a": 10,
"b": 5,
"operation": "add"
})
print(f"10 + 5 = {result}")
# Perform division
result = await client.execute_tool("calculate", {
"a": 20,
"b": 4,
"operation": "divide"
})
print(f"20 / 4 = {result}")
if __name__ == "__main__":
asyncio.run(main())
Expected Output
Available tools: [...]
10 + 5 = 15.0
20 / 4 = 5.0
Testing Operations
Addition
{
"a": 15,
"b": 7,
"operation": "add"
}
// Result: 22.0
Subtraction
{
"a": 100,
"b": 35,
"operation": "subtract"
}
// Result: 65.0
Multiplication
{
"a": 8,
"b": 7,
"operation": "multiply"
}
// Result: 56.0
Division
{
"a": 100,
"b": 5,
"operation": "divide"
}
// Result: 20.0
Error Case: Division by Zero
{
"a": 10,
"b": 0,
"operation": "divide"
}
// Error: "No se puede dividir por cero"
Configuration for Claude Desktop
claude_desktop_config.json
{
"mcpServers": {
"calculator": {
"command": "python",
"args": ["/path/to/server.py"]
}
}
}
Restart Claude Desktop after adding the configuration.
Extending the Calculator
Adding More Operations
@mcp.tool()
def advanced_calculate(a: float, b: float, operation: str) -> float:
"""Advanced calculator with more operations."""
operations = {
"add": lambda x, y: x + y,
"subtract": lambda x, y: x - y,
"multiply": lambda x, y: x * y,
"divide": lambda x, y: x / y if y != 0 else None,
"power": lambda x, y: x ** y,
"modulo": lambda x, y: x % y if y != 0 else None,
}
if operation not in operations:
raise ValueError(f"Invalid operation: {operation}")
result = operations[operation](a, b)
if result is None:
raise ValueError("Invalid operation parameters")
return float(result)
Scientific Calculator
import math
@mcp.tool()
def scientific_calculate(value: float, operation: str) -> float:
"""Scientific calculator for single-value operations."""
operations = {
"sqrt": math.sqrt,
"sin": math.sin,
"cos": math.cos,
"tan": math.tan,
"log": math.log,
"log10": math.log10,
"exp": math.exp,
}
if operation not in operations:
raise ValueError(f"Invalid operation: {operation}")
return float(operations[operation](value))
Key Advantages of FastMCP
- Minimal Boilerplate: No need to manually define schemas
- Type Hints: Automatic parameter validation from Python types
- Easy Debugging: Clear error messages and stack traces
- Rapid Development: Get a server running in minutes
Common Patterns
@mcp.tool()
def safe_divide(a: float, b: float) -> float:
"""Safely divide two numbers."""
if not isinstance(a, (int, float)):
raise TypeError("a must be a number")
if not isinstance(b, (int, float)):
raise TypeError("b must be a number")
if b == 0:
raise ValueError("Cannot divide by zero")
return float(a / b)
Default Parameters
from typing import Optional
@mcp.tool()
def calculate_with_default(
a: float,
b: float = 1.0,
operation: str = "add"
) -> float:
"""Calculate with default operation."""
# Implementation here
pass
Troubleshooting
Server Not Starting
- Ensure
mcp package is installed: pip install mcp
- Check Python version:
python --version (should be 3.10+)
- Verify the script has no syntax errors
- Ensure the
@mcp.tool() decorator is present
- Check that the function is defined before
mcp.run()
- Verify the server is running in stdio mode
Type Errors
- Use proper type hints:
float, int, str, etc.
- FastMCP uses type hints for validation
Next Steps