Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace BotSharp.Abstraction.MCP.Services;

/// <summary>
/// An optional host hook over the HTTP headers used to open one MCP server connection.
/// </summary>
/// <remarks>
/// Nothing registers this by default. With no implementation registered the headers configured
/// under <c>MCP:McpServerConfigs</c> are used verbatim, which is the only behaviour there was
/// before the hook existed — a host that does not implement it sees no change at all.
/// <para>
/// It exists so a host can call a server as whoever is driving the conversation instead of with
/// one fixed credential. That decision belongs to the host: it is the only side that knows what
/// a caller's credential is and which servers may be shown it.
/// </para>
/// </remarks>
public interface IMcpClientHeaderProvider
{
/// <summary>
/// Answers the headers to send to <paramref name="serverId"/>.
/// </summary>
/// <param name="configured">
/// The headers from configuration. This dictionary is shared for the lifetime of the process,
/// so an implementation that changes a header MUST copy it rather than write into it.
/// </param>
/// <returns>
/// The headers to send. Returning <paramref name="configured"/> unchanged is the no-op answer,
/// and is the answer expected for any server the implementation does not recognise.
/// </returns>
Dictionary<string, string>? GetHeaders(string serverId, Dictionary<string, string>? configured);
}
19 changes: 17 additions & 2 deletions src/Infrastructure/BotSharp.Core/MCP/Managers/McpClientManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public McpClientManager(
{
Name = config.Name,
Endpoint = new Uri(config.HttpConfig.EndPoint),
AdditionalHeaders = config.HttpConfig.AdditionalHeaders,
AdditionalHeaders = ResolveHeaders(config.Id, config.HttpConfig.AdditionalHeaders),
ConnectionTimeout = config.HttpConfig.ConnectionTimeout
});
}
Expand All @@ -44,7 +44,7 @@ public McpClientManager(
{
Name = config.Name,
Endpoint = new Uri(config.SseConfig.EndPoint),
AdditionalHeaders = config.SseConfig.AdditionalHeaders,
AdditionalHeaders = ResolveHeaders(config.Id, config.SseConfig.AdditionalHeaders),
ConnectionTimeout = config.SseConfig.ConnectionTimeout
});
}
Expand Down Expand Up @@ -74,6 +74,21 @@ public McpClientManager(
}
}

/// <summary>
/// The headers to open a connection with: the ones from configuration, unless the host has
/// registered an <see cref="IMcpClientHeaderProvider"/> that wants to adjust them.
/// </summary>
/// <remarks>
/// No provider is registered by default, and a provider is free to answer with what it was
/// given, so a host without one — or with one that does not recognise this server — gets the
/// configured headers back untouched.
/// </remarks>
private Dictionary<string, string>? ResolveHeaders(string serverId, Dictionary<string, string>? configured)
{
var provider = _services.GetService<IMcpClientHeaderProvider>();
return provider == null ? configured : provider.GetHeaders(serverId, configured);
}

public void Dispose()
{

Expand Down
Loading