Add McpClientOptions.InitializeMeta to set _meta on the initialize request (#1599)
This commit is contained in:
parent
20ddd2fb10
commit
af6fcff595
3 changed files with 61 additions and 0 deletions
|
|
@ -679,6 +679,7 @@ internal sealed partial class McpClientImpl : McpClient
|
||||||
ProtocolVersion = requestProtocol,
|
ProtocolVersion = requestProtocol,
|
||||||
Capabilities = _options.Capabilities ?? new ClientCapabilities(),
|
Capabilities = _options.Capabilities ?? new ClientCapabilities(),
|
||||||
ClientInfo = _options.ClientInfo ?? DefaultImplementation,
|
ClientInfo = _options.ClientInfo ?? DefaultImplementation,
|
||||||
|
Meta = _options.InitializeMeta,
|
||||||
},
|
},
|
||||||
McpJsonUtilities.JsonContext.Default.InitializeRequestParams,
|
McpJsonUtilities.JsonContext.Default.InitializeRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.InitializeResult,
|
McpJsonUtilities.JsonContext.Default.InitializeResult,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using ModelContextProtocol.Protocol;
|
using ModelContextProtocol.Protocol;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
|
|
||||||
namespace ModelContextProtocol.Client;
|
namespace ModelContextProtocol.Client;
|
||||||
|
|
||||||
|
|
@ -31,6 +32,21 @@ public sealed class McpClientOptions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ClientCapabilities? Capabilities { get; set; }
|
public ClientCapabilities? Capabilities { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the metadata to include in the <c>_meta</c> field of the <see cref="RequestMethods.Initialize"/> request.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// When set, this value is sent as <see cref="RequestParams.Meta"/> on the <see cref="InitializeRequestParams"/> during the initialization handshake.
|
||||||
|
/// This allows passing implementation-specific data to the server alongside the standard <c>initialize</c> parameters,
|
||||||
|
/// such as authentication context a server validates before completing the handshake.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// When <see langword="null"/>, no <c>_meta</c> field is sent.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public JsonObject? InitializeMeta { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the protocol version to request from the server, using a date-based versioning scheme.
|
/// Gets or sets the protocol version to request from the server, using a date-based versioning scheme.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ namespace ModelContextProtocol.Tests.Client;
|
||||||
|
|
||||||
public class McpClientMetaTests : ClientServerTestBase
|
public class McpClientMetaTests : ClientServerTestBase
|
||||||
{
|
{
|
||||||
|
private readonly TaskCompletionSource<JsonNode?> _initializeMeta = new();
|
||||||
|
|
||||||
public McpClientMetaTests(ITestOutputHelper outputHelper)
|
public McpClientMetaTests(ITestOutputHelper outputHelper)
|
||||||
: base(outputHelper)
|
: base(outputHelper)
|
||||||
{
|
{
|
||||||
|
|
@ -28,6 +30,48 @@ public class McpClientMetaTests : ClientServerTestBase
|
||||||
o.ResourceCollection = new ();
|
o.ResourceCollection = new ();
|
||||||
o.PromptCollection = new ();
|
o.PromptCollection = new ();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Capture the _meta the server receives on the initialize request so tests can
|
||||||
|
// assert that McpClientOptions.InitializeMeta is threaded through the handshake.
|
||||||
|
mcpServerBuilder.WithMessageFilters(filters =>
|
||||||
|
filters.AddIncomingFilter(next => async (context, cancellationToken) =>
|
||||||
|
{
|
||||||
|
if (context.JsonRpcMessage is JsonRpcRequest { Method: RequestMethods.Initialize } request)
|
||||||
|
{
|
||||||
|
_initializeMeta.TrySetResult(request.Params?["_meta"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
await next(context, cancellationToken);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InitializeMeta_IsSentToServer_WhenSet()
|
||||||
|
{
|
||||||
|
var clientOptions = new McpClientOptions
|
||||||
|
{
|
||||||
|
InitializeMeta = new JsonObject
|
||||||
|
{
|
||||||
|
{ "foo", "bar baz" }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
await using McpClient client = await CreateMcpClientForServer(clientOptions);
|
||||||
|
|
||||||
|
var meta = await _initializeMeta.Task.WaitAsync(TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
|
Assert.NotNull(meta);
|
||||||
|
Assert.Equal("bar baz", meta["foo"]?.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task InitializeMeta_IsOmitted_WhenNotSet()
|
||||||
|
{
|
||||||
|
await using McpClient client = await CreateMcpClientForServer();
|
||||||
|
|
||||||
|
var meta = await _initializeMeta.Task.WaitAsync(TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
|
Assert.Null(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue