mcp preparation

This commit is contained in:
Vitali sharp8n 2026-09-09 11:06:12 +03:00
parent a6f3b36f77
commit 7e971fe917
2 changed files with 36 additions and 0 deletions

View file

@ -0,0 +1,21 @@
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Routing.Executor;
namespace BotSharp.Abstraction.Functions;
/// <summary>
/// W4C extension point: resolves an <see cref="IFunctionExecutor"/> for MCP tools served by
/// dynamically-configured <b>Streamable HTTP</b> servers (user custom MCP servers and the built-in
/// OpenPencil design server). BotSharp's stock <c>McpClientManager</c> only reaches SSE/Stdio
/// servers registered at startup, so hosts that talk to streamable-HTTP servers register an
/// implementation of this and <see cref="Routing.Executor.FunctionExecutorFactory"/> consults it
/// before its own executors. Return <c>null</c> to let the stock executors handle the function.
/// </summary>
public interface IMcpHttpFunctionRouter
{
/// <summary>
/// Returns an executor for <paramref name="functionName"/> when it belongs to a routed MCP server
/// the host can reach over streamable HTTP, otherwise <c>null</c>.
/// </summary>
IFunctionExecutor? Create(Agent agent, string functionName);
}

View file

@ -13,6 +13,21 @@ internal class FunctionExecutorFactory
return new FunctionCallbackExecutor(functionCall);
}
// W4C: route MCP tools served by dynamically-configured Streamable HTTP servers (custom MCP
// servers and the OpenPencil design server) that the stock McpClientManager (SSE/Stdio only)
// cannot reach. The host's router resolves the owning server itself, so it also covers
// "all tools" (empty function list) entries. Returns null when the function is not an MCP
// tool, letting the stock executors below handle it.
var w4c = services.GetService<IMcpHttpFunctionRouter>();
if (w4c != null)
{
var w4cExecutor = w4c.Create(agent, functionName);
if (w4cExecutor != null)
{
return w4cExecutor;
}
}
var functions = (agent?.Functions ?? []).Concat(agent?.SecondaryFunctions ?? []);
var funcDef = functions.FirstOrDefault(x => x.Name == functionName);
if (!string.IsNullOrWhiteSpace(funcDef?.Output))