"""Dynamic MCP server implementation with JSON-schema based tool registration.""" from typing import Any from fastmcp import FastMCP from fastmcp.tools import FunctionTool from reme.core.schema import ToolCall from reme.core.utils import create_pydantic_model mcp = FastMCP("DynamicSchemaServer", port=8010) # Configuration including enum examples MODES_CONFIG = { "register_user": ToolCall( **{ "name": "register_user", "description": "Register a new user with metadata, tags, and roles.", "parameters": { "type": "object", "properties": { "username": {"type": "string", "description": "Unique username"}, "role": { "type": "string", "enum": ["admin", "editor", "viewer"], "description": "User access level", }, "metadata": { "type": "object", "description": "User metadata", "properties": { "age": {"type": "integer"}, "location": {"type": "string"}, }, "required": ["age"], }, "tags": { "type": "array", "description": "User tags", "items": { "type": "object", "properties": { "tag_id": {"type": "string"}, "level": {"type": "number"}, }, "required": ["tag_id"], }, }, }, "required": ["username", "metadata", "role"], }, }, ), "create_order": ToolCall( **{ "name": "create_order", "description": "创建订单", "parameters": { "type": "object", "properties": { "order_id": {"type": "string", "description": "订单ID"}, "amount": {"type": "number", "description": "订单金额"}, "customer": { "type": "object", "description": "客户信息", "properties": { "name": {"type": "string", "description": "客户姓名"}, "email": {"type": "string", "description": "客户邮箱"}, "phone": {"type": "string", "description": "联系电话"}, }, "required": ["name", "email"], }, }, "required": ["order_id", "customer"], }, }, ), } async def core_handler(mode: str, **kwargs: Any) -> dict[str, Any]: """Process dynamic tool requests and return execution results.""" print(f"Executing Mode: {mode}, Parameters: {kwargs}") return { "status": "success", "mode": mode, "received_data": kwargs, } def register_dynamic_tools() -> None: """Iterate over tool configurations and register them to the MCP instance.""" for mode_name, tool_call in MODES_CONFIG.items(): # Create Pydantic model from tool parameters request_model = create_pydantic_model(tool_call.name, tool_call.parameters) # Create execution function with closure to capture current mode and model def create_tool_func(current_mode: str, model: type): async def execute_tool(**kwargs: Any) -> dict[str, Any]: # Validate and normalize input using Pydantic model validated_data = model(**kwargs).model_dump(exclude_none=True) return await core_handler(current_mode, **validated_data) return execute_tool tool_fn = create_tool_func(mode_name, request_model) # Extract parameters schema tool_call_schema = tool_call.simple_input_dump() parameters = tool_call_schema[tool_call_schema["type"]]["parameters"] # Create FunctionTool and register tool = FunctionTool( name=tool_call.name, description=tool_call.description, fn=tool_fn, parameters=parameters, ) mcp.add_tool(tool) if __name__ == "__main__": register_dynamic_tools() mcp.run(transport="sse")