Claude Code - Backend Implementation Specialist
Add complete AI Todo Chatbot backend application
b93a6a5
"""
MCP (Model Context Protocol) Server for AI Chatbot.
This module initializes and manages MCP tools that the AI can use
to interact with the task management system.
"""
import logging
from typing import Dict, Any, Callable, List
from pydantic import BaseModel
logger = logging.getLogger(__name__)
class MCPTool(BaseModel):
"""Base model for MCP tool definition."""
name: str
description: str
parameters: Dict[str, Any]
function: Any # Will be the actual callable
class MCPServer:
"""
MCP Server managing tool registration and execution.
This server acts as a registry for tools that the AI can invoke.
All tools must be registered before they can be used.
"""
def __init__(self, name: str = "todo-tools", version: str = "1.0.0"):
self.name = name
self.version = version
self.tools: Dict[str, MCPTool] = {}
logger.info(f"MCP Server initialized: {name} v{version}")
def register_tool(
self,
name: str,
description: str,
parameters: Dict[str, Any],
function: Callable
):
"""
Register a new tool with the MCP server.
Args:
name: Tool name (must be unique)
description: Human-readable description of what the tool does
parameters: JSON schema describing the tool's parameters
function: The actual function to execute when tool is called
"""
if name in self.tools:
logger.warning(f"Tool '{name}' already registered, overwriting")
tool = MCPTool(
name=name,
description=description,
parameters=parameters,
function=function
)
self.tools[name] = tool
logger.info(f"Registered tool: {name}")
def get_tool(self, name: str) -> MCPTool:
"""Get a registered tool by name."""
if name not in self.tools:
raise ValueError(f"Tool '{name}' not found in MCP server")
return self.tools[name]
def list_tools(self) -> List[Dict[str, Any]]:
"""
List all registered tools in Cohere-compatible format.
Returns:
List of tool definitions for Cohere API v2
"""
tools_list = []
for tool in self.tools.values():
# Convert parameter definitions to JSON Schema format
properties = {}
required = []
for param_name, param_def in tool.parameters.items():
properties[param_name] = {
"type": param_def.get("type", "string"),
"description": param_def.get("description", "")
}
if param_def.get("required", False):
required.append(param_name)
tools_list.append({
"type": "function",
"function": {
"name": tool.name,
"description": tool.description,
"parameters": {
"type": "object",
"properties": properties,
"required": required
}
}
})
return tools_list
async def execute_tool(
self,
tool_name: str,
parameters: Dict[str, Any],
db: Any = None
) -> Dict[str, Any]:
"""
Execute a registered tool with given parameters.
Args:
tool_name: Name of the tool to execute
parameters: Parameters to pass to the tool
db: Database session to pass to the tool
Returns:
Tool execution result as dictionary
"""
tool = self.get_tool(tool_name)
try:
logger.info(f"Executing tool: {tool_name} with params: {parameters}")
# Pass database session to tool
result = await tool.function(**parameters, db=db)
logger.info(f"Tool {tool_name} executed successfully")
return result
except Exception as e:
logger.error(f"Tool {tool_name} execution failed: {str(e)}")
raise
# Global MCP server instance
mcp_server = MCPServer()