|
import functools |
|
import inspect |
|
import typing as ty |
|
import gradio as gr |
|
|
|
|
|
class MCPToolRegistry: |
|
def __init__(self): |
|
|
|
self.tools = {} |
|
|
|
def define(self, name: str, api_name: str): |
|
"""Decorator to define an MCP tool.""" |
|
def decorator(tool_func: ty.Callable): |
|
if api_name in self.tools: |
|
raise ValueError(f"Tool with api_name '{api_name}' already defined.") |
|
|
|
|
|
self.tools[api_name] = { |
|
'name': name, |
|
'tool_func': tool_func, |
|
'ui_builder': None, |
|
} |
|
|
|
|
|
|
|
|
|
|
|
setattr(tool_func, "__mcp_tool__", {"name": name, "api_name": api_name}) |
|
|
|
|
|
return tool_func |
|
return decorator |
|
|
|
def build_ui_control(self, api_name: str): |
|
"""Decorator to associate a UI builder function with a tool.""" |
|
def decorator(ui_builder_func: ty.Callable[..., ty.Union[gr.components.Component, tuple[gr.components.Component, ...]]]): |
|
if api_name not in self.tools: |
|
raise ValueError(f"Tool with api_name '{api_name}' not defined. Define it using @mcp_tool.define first.") |
|
|
|
|
|
self.tools[api_name]['ui_builder'] = ui_builder_func |
|
|
|
|
|
return ui_builder_func |
|
return decorator |
|
|
|
def get_tools_list(self) -> list[tuple[str, str]]: |
|
"""Returns a list of (tool_name, api_name) for all defined tools.""" |
|
return [(data['name'], api_name) for api_name, data in self.tools.items()] |
|
|
|
def get_tool_info(self, api_name: str) -> ty.Optional[dict]: |
|
"""Returns the full info dict for a given api_name.""" |
|
return self.tools.get(api_name) |
|
|
|
def get_tool_ui_builder(self, api_name: str) -> ty.Optional[ty.Callable]: |
|
"""Returns the UI builder function for a given api_name.""" |
|
info = self.get_tool_info(api_name) |
|
return info['ui_builder'] if info else None |
|
|
|
def get_tool_function(self, api_name: str) -> ty.Optional[ty.Callable]: |
|
"""Returns the tool function for a given api_name.""" |
|
info = self.get_tool_info(api_name) |
|
return info['tool_func'] if info else None |
|
|
|
|
|
mcp_tool = MCPToolRegistry() |
|
|
|
|
|
|
|
|
|
|