From af6fcff595138891b00ae560afbcea9d21370802 Mon Sep 17 00:00:00 2001
From: Aditya Singh <60082699+adityasingh2400@users.noreply.github.com>
Date: Fri, 5 Jun 2026 16:52:31 -0700
Subject: [PATCH] Add McpClientOptions.InitializeMeta to set _meta on the
initialize request (#1599)
---
.../Client/McpClientImpl.cs | 1 +
.../Client/McpClientOptions.cs | 16 +++++++
.../Client/McpClientMetaTests.cs | 44 +++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/src/ModelContextProtocol.Core/Client/McpClientImpl.cs b/src/ModelContextProtocol.Core/Client/McpClientImpl.cs
index e6ab3aa..bc58794 100644
--- a/src/ModelContextProtocol.Core/Client/McpClientImpl.cs
+++ b/src/ModelContextProtocol.Core/Client/McpClientImpl.cs
@@ -679,6 +679,7 @@ internal sealed partial class McpClientImpl : McpClient
ProtocolVersion = requestProtocol,
Capabilities = _options.Capabilities ?? new ClientCapabilities(),
ClientInfo = _options.ClientInfo ?? DefaultImplementation,
+ Meta = _options.InitializeMeta,
},
McpJsonUtilities.JsonContext.Default.InitializeRequestParams,
McpJsonUtilities.JsonContext.Default.InitializeResult,
diff --git a/src/ModelContextProtocol.Core/Client/McpClientOptions.cs b/src/ModelContextProtocol.Core/Client/McpClientOptions.cs
index 6d91f5b..f84b848 100644
--- a/src/ModelContextProtocol.Core/Client/McpClientOptions.cs
+++ b/src/ModelContextProtocol.Core/Client/McpClientOptions.cs
@@ -1,5 +1,6 @@
using ModelContextProtocol.Protocol;
using System.Diagnostics.CodeAnalysis;
+using System.Text.Json.Nodes;
namespace ModelContextProtocol.Client;
@@ -31,6 +32,21 @@ public sealed class McpClientOptions
///
public ClientCapabilities? Capabilities { get; set; }
+ ///
+ /// Gets or sets the metadata to include in the _meta field of the request.
+ ///
+ ///
+ ///
+ /// When set, this value is sent as on the during the initialization handshake.
+ /// This allows passing implementation-specific data to the server alongside the standard initialize parameters,
+ /// such as authentication context a server validates before completing the handshake.
+ ///
+ ///
+ /// When , no _meta field is sent.
+ ///
+ ///
+ public JsonObject? InitializeMeta { get; set; }
+
///
/// Gets or sets the protocol version to request from the server, using a date-based versioning scheme.
///
diff --git a/tests/ModelContextProtocol.Tests/Client/McpClientMetaTests.cs b/tests/ModelContextProtocol.Tests/Client/McpClientMetaTests.cs
index 863d8e6..7e67eb4 100644
--- a/tests/ModelContextProtocol.Tests/Client/McpClientMetaTests.cs
+++ b/tests/ModelContextProtocol.Tests/Client/McpClientMetaTests.cs
@@ -8,6 +8,8 @@ namespace ModelContextProtocol.Tests.Client;
public class McpClientMetaTests : ClientServerTestBase
{
+ private readonly TaskCompletionSource _initializeMeta = new();
+
public McpClientMetaTests(ITestOutputHelper outputHelper)
: base(outputHelper)
{
@@ -28,6 +30,48 @@ public class McpClientMetaTests : ClientServerTestBase
o.ResourceCollection = 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]