"""
Tool Registration System
Provides centralized registration and management of MCP tools using
a registry pattern for dynamic component discovery.
"""
import logging
from typing import List, Type, Dict, Any
from fastmcp import FastMCP
from .base import BaseTool
from .arithmetic import ArithmeticTools
from .weather import WeatherTools
from ..config.logging import get_logger
logger = get_logger(__name__)
class ToolRegistry:
"""
Central registry for managing MCP tools.
Provides functionality to register tool classes and automatically
register all tools with a FastMCP instance.
"""
def __init__(self):
"""Initialize the tool registry."""
self._tool_classes: List[Type[BaseTool]] = []
self._registered_tools: Dict[str, BaseTool] = {}
def register(self, tool_class: Type[BaseTool]) -> None:
"""
Register a tool class with the registry.
Args:
tool_class: The tool class to register
"""
if not issubclass(tool_class, BaseTool):
raise TypeError(f"Tool class {tool_class.__name__} must inherit from BaseTool")
self._tool_classes.append(tool_class)
logger.info(f"Registered tool class: {tool_class.__name__}")
def register_all(self, mcp: FastMCP) -> None:
"""
Register all tools with the FastMCP instance.
Args:
mcp: The FastMCP instance to register tools with
"""
logger.info(f"Registering {len(self._tool_classes)} tool classes")
for tool_class in self._tool_classes:
try:
# Instantiate the tool
tool_instance = tool_class()
# Register with MCP
tool_instance.register_with_mcp(mcp)
# Store the instance for potential future use
self._registered_tools[tool_instance.name] = tool_instance
logger.info(f"Successfully registered tool: {tool_instance.name}")
except Exception as e:
logger.error(f"Failed to register tool {tool_class.__name__}: {e}")
# Continue with other tools even if one fails
def get_registered_tools(self) -> Dict[str, BaseTool]:
"""
Get all registered tool instances.
Returns:
Dictionary mapping tool names to instances
"""
return self._registered_tools.copy()
def get_tool_info(self) -> List[Dict[str, Any]]:
"""
Get information about all registered tools.
Returns:
List of dictionaries containing tool metadata
"""
return [tool.get_info() for tool in self._registered_tools.values()]
# Global registry instance
registry = ToolRegistry()
# Register built-in tools
registry.register(ArithmeticTools)
registry.register(WeatherTools)
def register_all_tools(mcp: FastMCP) -> None:
"""
Register all tools with the MCP server.
This is the main entry point for tool registration that should be
called from the server initialization.
Args:
mcp: The FastMCP instance to register tools with
"""
registry.register_all(mcp)
def get_tool_registry() -> ToolRegistry:
"""
Get the global tool registry instance.
Returns:
The global tool registry
"""
return registry
def register_tool_class(tool_class: Type[BaseTool]) -> None:
"""
Convenience function to register a new tool class.
Args:
tool_class: The tool class to register
"""
registry.register(tool_class)