main
py 40 lines 1.26 KB
Raw
1 """Allowlisted MCP tool registry."""
2 from __future__ import annotations
3
4 from types import MappingProxyType
5 from typing import Any, Mapping
6
7 from app.contracts import McpToolDefinition
8
9
10 class DuplicateMcpToolError(ValueError):
11 pass
12
13
14 class McpToolRegistry:
15 def __init__(self) -> None:
16 self._tools: dict[str, McpToolDefinition] = {}
17
18 def register(self, definition: McpToolDefinition) -> None:
19 if definition.name in self._tools:
20 raise DuplicateMcpToolError(f"MCP tool already registered: {definition.name}")
21 self._tools[definition.name] = definition
22
23 def get(self, name: str) -> McpToolDefinition | None:
24 return self._tools.get(name)
25
26 @property
27 def tools(self) -> Mapping[str, McpToolDefinition]:
28 return MappingProxyType(self._tools)
29
30 def discover(self) -> list[dict[str, Any]]:
31 return [
32 {
33 "name": definition.name,
34 "description": definition.description,
35 "inputSchema": definition.input_model.model_json_schema(by_alias=True),
36 "riskClass": definition.risk_class.value,
37 "kind": definition.kind.value,
38 }
39 for definition in sorted(self._tools.values(), key=lambda item: item.name)
40 ]