Initial commit
This commit is contained in:
47
server/tools/mcp_proxy_tool.py
Normal file
47
server/tools/mcp_proxy_tool.py
Normal file
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
tools/mcp_proxy_tool.py — Dynamic BaseTool wrapper for external MCP server tools.
|
||||
|
||||
One McpProxyTool instance is created per tool discovered from each MCP server.
|
||||
The tool name is namespaced as mcp__{server_slug}__{tool_name} to avoid collisions.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
|
||||
from .base import BaseTool, ToolResult
|
||||
|
||||
|
||||
def _slugify(name: str) -> str:
|
||||
"""Convert a server name to a safe identifier component."""
|
||||
return re.sub(r"[^a-z0-9]+", "_", name.lower()).strip("_")
|
||||
|
||||
|
||||
class McpProxyTool(BaseTool):
|
||||
requires_confirmation = False
|
||||
allowed_in_scheduled_tasks = True
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
server_id: str,
|
||||
server_name: str,
|
||||
server: dict,
|
||||
tool_name: str,
|
||||
description: str,
|
||||
input_schema: dict,
|
||||
) -> None:
|
||||
self.name = f"mcp__{_slugify(server_name)}__{tool_name}"
|
||||
self.description = f"[{server_name}] {description}"
|
||||
self.input_schema = input_schema if input_schema else {
|
||||
"type": "object", "properties": {}, "required": []
|
||||
}
|
||||
self._server_id = server_id
|
||||
self._server_display_name = server_name # human-readable name for UI
|
||||
self._server = server # full server dict with decrypted secrets
|
||||
self._remote_tool_name = tool_name # original name on the MCP server
|
||||
|
||||
async def execute(self, **kwargs) -> ToolResult:
|
||||
from ..mcp_client.manager import call_tool
|
||||
# Refresh server config (api_key may have changed since startup)
|
||||
from ..mcp_client.store import get_server
|
||||
server = await get_server(self._server_id, include_secrets=True) or self._server
|
||||
return await call_tool(server, self._remote_tool_name, kwargs)
|
||||
Reference in New Issue
Block a user