From 039206c1f5f596b42f3fda22cd09c8987140189d Mon Sep 17 00:00:00 2001 From: binrogithub Date: Sun, 8 Feb 2026 17:59:29 +0300 Subject: [PATCH] Add tool registry and MCP tools search --- hc_agent/__init__.py | 0 hc_agent/core/__init__.py | 0 hc_agent/core/tool_registry.py | 45 ++++++++++++++++++++++++++++++++++ hc_agent/mcp/__init__.py | 0 hc_agent/mcp/tools.py | 23 +++++++++++++++++ 5 files changed, 68 insertions(+) create mode 100644 hc_agent/__init__.py create mode 100644 hc_agent/core/__init__.py create mode 100644 hc_agent/core/tool_registry.py create mode 100644 hc_agent/mcp/__init__.py create mode 100644 hc_agent/mcp/tools.py diff --git a/hc_agent/__init__.py b/hc_agent/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hc_agent/core/__init__.py b/hc_agent/core/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hc_agent/core/tool_registry.py b/hc_agent/core/tool_registry.py new file mode 100644 index 0000000000..a453ff9219 --- /dev/null +++ b/hc_agent/core/tool_registry.py @@ -0,0 +1,45 @@ +"""Registry for tool schemas used by hc_agent.""" + +from __future__ import annotations + +from dataclasses import asdict, dataclass +from typing import Any, Iterable +import copy + + +@dataclass(frozen=True) +class ToolSpec: + name: str + description: str + risk: str + input_schema: dict[str, Any] + output_schema: dict[str, Any] + examples: tuple[dict[str, Any], ...] = () + + +class ToolRegistry: + """Central registry for tool schemas. + + Tool specifications should be added here to avoid duplicate definitions. + """ + + _tools: list[ToolSpec] = [] + + @classmethod + def register(cls, tool: ToolSpec) -> None: + cls._tools.append(tool) + + @classmethod + def schema(cls) -> tuple[dict[str, Any], ...]: + """Return a deterministic catalog of tool schemas.""" + tools = sorted(cls._tools, key=lambda tool: tool.name) + return tuple(cls._serialize(tool) for tool in tools) + + @staticmethod + def _serialize(tool: ToolSpec) -> dict[str, Any]: + data = asdict(tool) + data["examples"] = list(tool.examples) + return copy.deepcopy(data) + + +__all__: Iterable[str] = ["ToolRegistry", "ToolSpec"] diff --git a/hc_agent/mcp/__init__.py b/hc_agent/mcp/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hc_agent/mcp/tools.py b/hc_agent/mcp/tools.py new file mode 100644 index 0000000000..68b16fc86d --- /dev/null +++ b/hc_agent/mcp/tools.py @@ -0,0 +1,23 @@ +"""Handlers for MCP tool discovery.""" + +from __future__ import annotations + +from typing import Any + +from hc_agent.core.tool_registry import ToolRegistry + + +def hc_tools_search() -> list[dict[str, Any]]: + """Return the tool catalog for MCP tool discovery.""" + catalog = ToolRegistry.schema() + return [ + { + "name": tool["name"], + "description": tool["description"], + "risk": tool["risk"], + "input_schema": tool["input_schema"], + "output_schema": tool["output_schema"], + "examples": tool["examples"], + } + for tool in catalog + ]