| 1 | namespace AgentForge.Abstractions; |
| 2 | |
| 3 | /// <summary>Plugins register MCP tools via descriptor + handler (FORGE-ADR-0025).</summary> |
| 4 | public sealed class ForgeMcpToolRegistry |
| 5 | { |
| 6 | private readonly List<ForgeMcpRegisteredPluginTool> _pluginTools = []; |
| 7 | |
| 8 | public IReadOnlyList<string> ToolNames => |
| 9 | _pluginTools.Select(t => t.Descriptor.Name).ToList(); |
| 10 | |
| 11 | public IReadOnlyList<ForgeMcpRegisteredPluginTool> PluginTools => _pluginTools; |
| 12 | |
| 13 | public void Add(ForgeMcpToolDefinition tool) => |
| 14 | Add(tool.Descriptor, tool.Handler); |
| 15 | |
| 16 | public void Add(ForgeMcpToolDescriptor descriptor, ForgeMcpToolHandler handler) |
| 17 | { |
| 18 | ArgumentNullException.ThrowIfNull(descriptor); |
| 19 | ArgumentNullException.ThrowIfNull(handler); |
| 20 | |
| 21 | if (string.IsNullOrWhiteSpace(descriptor.Name)) |
| 22 | throw new ArgumentException("Tool name is required.", nameof(descriptor)); |
| 23 | |
| 24 | if (_pluginTools.Any(t => string.Equals(t.Descriptor.Name, descriptor.Name, StringComparison.Ordinal))) |
| 25 | throw new InvalidOperationException($"MCP tool '{descriptor.Name}' is already registered."); |
| 26 | |
| 27 | _pluginTools.Add(new ForgeMcpRegisteredPluginTool(descriptor, handler)); |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | public sealed record ForgeMcpRegisteredPluginTool( |
| 32 | ForgeMcpToolDescriptor Descriptor, |
| 33 | ForgeMcpToolHandler Handler); |
| 34 | |
| 35 | public sealed class ForgeFeatureRegistry |
| 36 | { |
| 37 | private readonly List<string> _features = []; |
| 38 | |
| 39 | public IReadOnlyList<string> Features => _features; |
| 40 | |
| 41 | public void Add(string feature) |
| 42 | { |
| 43 | if (string.IsNullOrWhiteSpace(feature)) |
| 44 | return; |
| 45 | |
| 46 | if (_features.Contains(feature, StringComparer.Ordinal)) |
| 47 | return; |
| 48 | |
| 49 | _features.Add(feature.Trim()); |
| 50 | } |
| 51 | } |
| 52 | |