railroader-setons-special-s.../src/Modules/Mcp/McpRegistry.cs
seton 5e18cb84a1 MCP: localhost agent server with reloadable S3.Mcp.Tools plugin pack
Loopback MCP host with observe/control/develop gates and a hot-reload
tools DLL. Default token is local-dev only. Leave the module off unless
you are driving S3 from an agent.
2026-09-11 15:19:24 -04:00

62 lines
1.6 KiB
C#

using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using S3.Mcp;
namespace S3.Modules.Mcp;
sealed class McpToolEntry
{
public string Name = "";
public string Description = "";
public JObject InputSchema = new();
public McpGate Gate;
public string Source = "host";
public Func<JObject, McpToolResult> Handler = _ => McpToolResult.Fail("no handler");
}
sealed class McpRegistry
{
readonly List<McpToolEntry> _tools = new();
public IReadOnlyList<McpToolEntry> All => _tools;
public void ClearSource(string source)
{
for (int i = _tools.Count - 1; i >= 0; i--)
if (_tools[i].Source == source)
_tools.RemoveAt(i);
}
public void Add(McpToolEntry entry)
{
for (int i = _tools.Count - 1; i >= 0; i--)
if (_tools[i].Name == entry.Name)
_tools.RemoveAt(i);
_tools.Add(entry);
}
public McpToolEntry? Find(string name)
{
for (int i = 0; i < _tools.Count; i++)
if (_tools[i].Name == name)
return _tools[i];
return null;
}
public List<McpToolEntry> Visible()
{
var s = McpModule.Settings;
var list = new List<McpToolEntry>();
for (int i = 0; i < _tools.Count; i++)
{
var t = _tools[i];
if (t.Source == "host") { list.Add(t); continue; }
if (t.Gate == McpGate.Observe && !s.observe) continue;
if (t.Gate == McpGate.Control && !s.control) continue;
if (t.Gate == McpGate.Develop && !s.develop) continue;
list.Add(t);
}
return list;
}
}