import asyncio
import math
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
# Create server instance
server = Server("calculator")
@server.list_tools()
async def list_tools() -> list[Tool]:
"""List available calculator tools."""
return [
Tool(
name="add",
description="Add two numbers",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "First number"},
"b": {"type": "number", "description": "Second number"},
},
"required": ["a", "b"],
},
),
Tool(
name="subtract",
description="Subtract second number from first number",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "First number"},
"b": {"type": "number", "description": "Second number to subtract"},
},
"required": ["a", "b"],
},
),
Tool(
name="multiply",
description="Multiply two numbers",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "First number"},
"b": {"type": "number", "description": "Second number"},
},
"required": ["a", "b"],
},
),
Tool(
name="divide",
description="Divide first number by second number",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "Dividend"},
"b": {"type": "number", "description": "Divisor"},
},
"required": ["a", "b"],
},
),
Tool(
name="power",
description="Raise a number to a power",
inputSchema={
"type": "object",
"properties": {
"base": {"type": "number", "description": "Base number"},
"exponent": {"type": "number", "description": "Exponent"},
},
"required": ["base", "exponent"],
},
),
Tool(
name="sqrt",
description="Calculate square root of a number",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "Number to calculate square root of"},
},
"required": ["a"],
},
),
Tool(
name="modulo",
description="Calculate remainder of division",
inputSchema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "Dividend"},
"b": {"type": "number", "description": "Divisor"},
},
"required": ["a", "b"],
},
),
]
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
"""Handle tool calls for calculator operations."""
try:
if name == "add":
result = arguments["a"] + arguments["b"]
elif name == "subtract":
result = arguments["a"] - arguments["b"]
elif name == "multiply":
result = arguments["a"] * arguments["b"]
elif name == "divide":
if arguments["b"] == 0:
return [TextContent(type="text", text="Error: Division by zero")]
result = arguments["a"] / arguments["b"]
elif name == "power":
result = math.pow(arguments["base"], arguments["exponent"])
elif name == "sqrt":
if arguments["a"] < 0:
return [TextContent(type="text", text="Error: Cannot calculate square root of negative number")]
result = math.sqrt(arguments["a"])
elif name == "modulo":
if arguments["b"] == 0:
return [TextContent(type="text", text="Error: Modulo by zero")]
result = arguments["a"] % arguments["b"]
else:
return [TextContent(type="text", text=f"Error: Unknown tool '{name}'")]
return [TextContent(type="text", text=str(result))]
except Exception as e:
return [TextContent(type="text", text=f"Error: {str(e)}")]
async def main():
"""Run the calculator MCP server."""
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream, server.create_initialization_options())
if __name__ == "__main__":
asyncio.run(main())