Skip to content

Commit 124b43b

Browse files
Copilotstephentoubjeffhandley
authored
Add explicit [Experimental] protected constructors to McpClient and McpServer (#1363)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> Co-authored-by: jeffhandley <1031940+jeffhandley@users.noreply.github.com> Co-authored-by: Jeff Handley <jeffhandley@users.noreply.github.com>
1 parent 9b2aaed commit 124b43b

File tree

8 files changed

+44
-2
lines changed

8 files changed

+44
-2
lines changed

docs/list-of-diagnostics.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ If you use experimental APIs, you will get one of the diagnostics shown below. T
2424
| Diagnostic ID | Description |
2525
| :------------ | :---------- |
2626
| `MCPEXP001` | MCP experimental APIs including Tasks and Extensions. Tasks provide a mechanism for asynchronous long-running operations that can be polled for status and results (see [MCP Tasks specification](https://modelcontextprotocol.io/specification/draft/basic/utilities/tasks)). Extensions provide a framework for extending the Model Context Protocol while maintaining interoperability (see [SEP-2133](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2133)). |
27+
| `MCPEXP002` | Subclassing `McpClient` and `McpServer` is experimental and subject to change (see [#1363](https://github.com/modelcontextprotocol/csharp-sdk/pull/1363)). |
2728

2829
## Obsolete APIs
2930

@@ -34,4 +35,4 @@ When APIs are marked as obsolete, a diagnostic is emitted to warn users that the
3435
| Diagnostic ID | Status | Description |
3536
| :------------ | :----- | :---------- |
3637
| `MCP9001` | In place | The `EnumSchema` and `LegacyTitledEnumSchema` APIs are deprecated as of specification version 2025-11-25. Use the current schema APIs instead. |
37-
| `MCP9002` | Removed | The `AddXxxFilter` extension methods on `IMcpServerBuilder` (e.g., `AddListToolsFilter`, `AddCallToolFilter`, `AddIncomingMessageFilter`) were superseded by `WithRequestFilters()` and `WithMessageFilters()`. |
38+
| `MCP9002` | Removed | The `AddXxxFilter` extension methods on `IMcpServerBuilder` (e.g., `AddListToolsFilter`, `AddCallToolFilter`, `AddIncomingMessageFilter`) were superseded by `WithRequestFilters()` and `WithMessageFilters()`. |

src/Common/Experimentals.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,19 @@ internal static class Experimentals
5656
/// URL for the experimental MCP Extensions feature.
5757
/// </summary>
5858
public const string Extensions_Url = "https://github.com/modelcontextprotocol/csharp-sdk/blob/main/docs/list-of-diagnostics.md#mcpexp001";
59+
60+
/// <summary>
61+
/// Diagnostic ID for experimental subclassing of McpClient and McpServer.
62+
/// </summary>
63+
public const string Subclassing_DiagnosticId = "MCPEXP002";
64+
65+
/// <summary>
66+
/// Message for experimental subclassing of McpClient and McpServer.
67+
/// </summary>
68+
public const string Subclassing_Message = "Subclassing McpClient and McpServer is experimental and subject to change.";
69+
70+
/// <summary>
71+
/// URL for experimental subclassing of McpClient and McpServer.
72+
/// </summary>
73+
public const string Subclassing_Url = "https://github.com/modelcontextprotocol/csharp-sdk/pull/1363";
5974
}

src/ModelContextProtocol.Core/Client/McpClient.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using ModelContextProtocol.Protocol;
1+
using System.Diagnostics.CodeAnalysis;
2+
using ModelContextProtocol.Protocol;
23

34
namespace ModelContextProtocol.Client;
45

@@ -7,6 +8,14 @@ namespace ModelContextProtocol.Client;
78
/// </summary>
89
public abstract partial class McpClient : McpSession
910
{
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="McpClient"/> class.
13+
/// </summary>
14+
[Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)]
15+
protected McpClient()
16+
{
17+
}
18+
1019
/// <summary>
1120
/// Gets the capabilities supported by the connected server.
1221
/// </summary>

src/ModelContextProtocol.Core/Client/McpClientImpl.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace ModelContextProtocol.Client;
77

88
/// <inheritdoc/>
9+
#pragma warning disable MCPEXP002
910
internal sealed partial class McpClientImpl : McpClient
1011
{
1112
private static Implementation DefaultImplementation { get; } = new()
@@ -37,6 +38,7 @@ internal sealed partial class McpClientImpl : McpClient
3738
/// <param name="options">Options for the client, defining protocol version and capabilities.</param>
3839
/// <param name="loggerFactory">The logger factory.</param>
3940
internal McpClientImpl(ITransport transport, string endpointName, McpClientOptions? options, ILoggerFactory? loggerFactory)
41+
#pragma warning restore MCPEXP002
4042
{
4143
options ??= new();
4244

src/ModelContextProtocol.Core/Server/DestinationBoundMcpServer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
namespace ModelContextProtocol.Server;
55

6+
#pragma warning disable MCPEXP002
67
internal sealed class DestinationBoundMcpServer(McpServerImpl server, ITransport? transport) : McpServer
8+
#pragma warning restore MCPEXP002
79
{
810
public override string? SessionId => transport?.SessionId ?? server.SessionId;
911
public override string? NegotiatedProtocolVersion => server.NegotiatedProtocolVersion;

src/ModelContextProtocol.Core/Server/McpServer.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics.CodeAnalysis;
12
using ModelContextProtocol.Protocol;
23

34
namespace ModelContextProtocol.Server;
@@ -7,6 +8,14 @@ namespace ModelContextProtocol.Server;
78
/// </summary>
89
public abstract partial class McpServer : McpSession
910
{
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="McpServer"/> class.
13+
/// </summary>
14+
[Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)]
15+
protected McpServer()
16+
{
17+
}
18+
1019
/// <summary>
1120
/// Gets the capabilities supported by the client.
1221
/// </summary>

src/ModelContextProtocol.Core/Server/McpServerImpl.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace ModelContextProtocol.Server;
1010

1111
/// <inheritdoc />
12+
#pragma warning disable MCPEXP002
1213
internal sealed partial class McpServerImpl : McpServer
1314
{
1415
internal static Implementation DefaultImplementation { get; } = new()
@@ -54,6 +55,7 @@ internal sealed partial class McpServerImpl : McpServer
5455
/// <param name="serviceProvider">Optional service provider to use for dependency injection</param>
5556
/// <exception cref="McpException">The server was incorrectly configured.</exception>
5657
public McpServerImpl(ITransport transport, McpServerOptions options, ILoggerFactory? loggerFactory, IServiceProvider? serviceProvider)
58+
#pragma warning restore MCPEXP002
5759
{
5860
Throw.IfNull(transport);
5961
Throw.IfNull(options);

tests/ModelContextProtocol.Tests/Server/McpServerTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,9 @@ private static async Task InitializeServerAsync(TestServerTransport transport, C
943943
await tcs.Task.WaitAsync(TestConstants.DefaultTimeout, cancellationToken);
944944
}
945945

946+
#pragma warning disable MCPEXP002
946947
private sealed class TestServerForIChatClient(bool supportsSampling) : McpServer
948+
#pragma warning restore MCPEXP002
947949
{
948950
public override ClientCapabilities? ClientCapabilities =>
949951
supportsSampling ? new ClientCapabilities { Sampling = new SamplingCapability() } :

0 commit comments

Comments
 (0)