Spaces:
Sleeping
Sleeping
#!/usr/bin/env python3 | |
""" | |
Example MCP Server for testing with Minion Brain integration | |
This server provides simple tools for demonstration purposes: | |
- calculator: Basic arithmetic operations | |
- echo: Simple echo/repeat functionality | |
- timestamp: Get current timestamp | |
""" | |
import asyncio | |
import json | |
import math | |
from datetime import datetime | |
from typing import Any, Dict | |
import mcp.types as types | |
from mcp.server import NotificationOptions, Server | |
from mcp.server.models import InitializationOptions | |
import mcp.server.stdio | |
# Create server instance | |
server = Server("example-tools-server") | |
async def handle_list_tools() -> list[types.Tool]: | |
"""List available tools.""" | |
return [ | |
types.Tool( | |
name="calculator", | |
description="Perform basic arithmetic calculations", | |
inputSchema={ | |
"type": "object", | |
"properties": { | |
"expression": { | |
"type": "string", | |
"description": "Mathematical expression to evaluate (e.g., '2 + 3 * 4')" | |
} | |
}, | |
"required": ["expression"] | |
} | |
), | |
types.Tool( | |
name="echo", | |
description="Echo back the provided text", | |
inputSchema={ | |
"type": "object", | |
"properties": { | |
"text": { | |
"type": "string", | |
"description": "Text to echo back" | |
} | |
}, | |
"required": ["text"] | |
} | |
), | |
types.Tool( | |
name="timestamp", | |
description="Get current timestamp", | |
inputSchema={ | |
"type": "object", | |
"properties": { | |
"format": { | |
"type": "string", | |
"description": "Timestamp format ('iso', 'unix', or 'readable')", | |
"default": "iso" | |
} | |
} | |
} | |
), | |
types.Tool( | |
name="math_functions", | |
description="Advanced mathematical functions", | |
inputSchema={ | |
"type": "object", | |
"properties": { | |
"function": { | |
"type": "string", | |
"description": "Math function to use", | |
"enum": ["sin", "cos", "tan", "log", "sqrt", "factorial"] | |
}, | |
"value": { | |
"type": "number", | |
"description": "Input value for the function" | |
} | |
}, | |
"required": ["function", "value"] | |
} | |
) | |
] | |
async def handle_call_tool(name: str, arguments: dict) -> list[types.TextContent]: | |
"""Handle tool execution.""" | |
if name == "calculator": | |
expression = arguments.get("expression", "") | |
try: | |
# Simple and safe evaluation for basic arithmetic | |
# Note: In production, use a proper math parser for security | |
allowed_chars = set("0123456789+-*/()., ") | |
if not all(c in allowed_chars for c in expression): | |
raise ValueError("Invalid characters in expression") | |
result = eval(expression) | |
return [types.TextContent( | |
type="text", | |
text=f"Result: {expression} = {result}" | |
)] | |
except Exception as e: | |
return [types.TextContent( | |
type="text", | |
text=f"Error: Unable to calculate '{expression}': {str(e)}" | |
)] | |
elif name == "echo": | |
text = arguments.get("text", "") | |
return [types.TextContent( | |
type="text", | |
text=f"Echo: {text}" | |
)] | |
elif name == "timestamp": | |
format_type = arguments.get("format", "iso") | |
now = datetime.now() | |
if format_type == "unix": | |
timestamp = str(int(now.timestamp())) | |
elif format_type == "readable": | |
timestamp = now.strftime("%Y-%m-%d %H:%M:%S") | |
else: # iso format | |
timestamp = now.isoformat() | |
return [types.TextContent( | |
type="text", | |
text=f"Current timestamp ({format_type}): {timestamp}" | |
)] | |
elif name == "math_functions": | |
function = arguments.get("function") | |
value = arguments.get("value") | |
try: | |
if function == "sin": | |
result = math.sin(math.radians(value)) | |
elif function == "cos": | |
result = math.cos(math.radians(value)) | |
elif function == "tan": | |
result = math.tan(math.radians(value)) | |
elif function == "log": | |
result = math.log(value) | |
elif function == "sqrt": | |
result = math.sqrt(value) | |
elif function == "factorial": | |
result = math.factorial(int(value)) | |
else: | |
raise ValueError(f"Unknown function: {function}") | |
return [types.TextContent( | |
type="text", | |
text=f"{function}({value}) = {result}" | |
)] | |
except Exception as e: | |
return [types.TextContent( | |
type="text", | |
text=f"Error: Unable to calculate {function}({value}): {str(e)}" | |
)] | |
else: | |
raise ValueError(f"Unknown tool: {name}") | |
async def main(): | |
"""Main function to run the MCP server.""" | |
# Run the server using stdio transport | |
async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): | |
await server.run( | |
read_stream, | |
write_stream, | |
InitializationOptions( | |
server_name="example-tools-server", | |
server_version="1.0.0", | |
capabilities=server.get_capabilities( | |
notification_options=NotificationOptions(), | |
experimental_capabilities={}, | |
), | |
), | |
) | |
if __name__ == "__main__": | |
asyncio.run(main()) |