Skip to content

Commit 5f99299

Browse files
authored
Decouple Handlers and Collections from protocol types (#765)
* Decouple Handlers and Collections (e.g. ToolsHandler and ToolsCollection) from Capabilities by promoting them to the options types. Also, group all handlers in container classes, for server, I decided to move McpServerHandlers down to Mcp.Core and move the NotificationHandlers there too. Also, Fix ListResourceTemplatesHandler issue. * Add remarks for empty protocol capability types * Keep JsonIgnore properties and mark them as Obsolete * Continue supporting Obsolete members * Update Obsolete messages to indicate the member will be removed * Add EditorBrowsable Never to the remaining obsolete members
1 parent 39b0ed3 commit 5f99299

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1588
-1161
lines changed

README.md

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -174,54 +174,51 @@ using System.Text.Json;
174174
McpServerOptions options = new()
175175
{
176176
ServerInfo = new Implementation { Name = "MyServer", Version = "1.0.0" },
177-
Capabilities = new ServerCapabilities
177+
Handlers = new McpServerHandlers()
178178
{
179-
Tools = new ToolsCapability
180-
{
181-
ListToolsHandler = (request, cancellationToken) =>
182-
ValueTask.FromResult(new ListToolsResult
183-
{
184-
Tools =
185-
[
186-
new Tool
187-
{
188-
Name = "echo",
189-
Description = "Echoes the input back to the client.",
190-
InputSchema = JsonSerializer.Deserialize<JsonElement>("""
191-
{
192-
"type": "object",
193-
"properties": {
194-
"message": {
195-
"type": "string",
196-
"description": "The input to echo back"
197-
}
198-
},
199-
"required": ["message"]
200-
}
201-
"""),
202-
}
203-
]
204-
}),
205-
206-
CallToolHandler = (request, cancellationToken) =>
179+
ListToolsHandler = (request, cancellationToken) =>
180+
ValueTask.FromResult(new ListToolsResult
207181
{
208-
if (request.Params?.Name == "echo")
209-
{
210-
if (request.Params.Arguments?.TryGetValue("message", out var message) is not true)
182+
Tools =
183+
[
184+
new Tool
211185
{
212-
throw new McpException("Missing required argument 'message'");
186+
Name = "echo",
187+
Description = "Echoes the input back to the client.",
188+
InputSchema = JsonSerializer.Deserialize<JsonElement>("""
189+
{
190+
"type": "object",
191+
"properties": {
192+
"message": {
193+
"type": "string",
194+
"description": "The input to echo back"
195+
}
196+
},
197+
"required": ["message"]
198+
}
199+
"""),
213200
}
201+
]
202+
}),
214203

215-
return ValueTask.FromResult(new CallToolResult
216-
{
217-
Content = [new TextContentBlock { Text = $"Echo: {message}", Type = "text" }]
218-
});
204+
CallToolHandler = (request, cancellationToken) =>
205+
{
206+
if (request.Params?.Name == "echo")
207+
{
208+
if (request.Params.Arguments?.TryGetValue("message", out var message) is not true)
209+
{
210+
throw new McpException("Missing required argument 'message'");
219211
}
220212

221-
throw new McpException($"Unknown tool: '{request.Params?.Name}'");
222-
},
213+
return ValueTask.FromResult(new CallToolResult
214+
{
215+
Content = [new TextContentBlock { Text = $"Echo: {message}", Type = "text" }]
216+
});
217+
}
218+
219+
throw new McpException($"Unknown tool: '{request.Params?.Name}'");
223220
}
224-
},
221+
}
225222
};
226223

227224
await using McpServer server = McpServer.Create(new StdioServerTransport("MyServer"), options);

docs/concepts/elicitation/samples/client/Program.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,9 @@
1818
Name = "ElicitationClient",
1919
Version = "1.0.0"
2020
},
21-
Capabilities = new()
21+
Handlers = new()
2222
{
23-
Elicitation = new()
24-
{
25-
ElicitationHandler = HandleElicitationAsync
26-
}
23+
ElicitationHandler = HandleElicitationAsync
2724
}
2825
};
2926

samples/AspNetCoreMcpPerSessionTools/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
{
2525
mcpOptions.Capabilities = new();
2626
mcpOptions.Capabilities.Tools = new();
27-
var toolCollection = mcpOptions.Capabilities.Tools.ToolCollection = new();
27+
var toolCollection = mcpOptions.ToolCollection = new();
2828

2929
foreach (var tool in tools)
3030
{

samples/ChatWithTools/Program.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@
4141
}),
4242
clientOptions: new()
4343
{
44-
Capabilities = new() { Sampling = new() { SamplingHandler = samplingClient.CreateSamplingHandler() } },
44+
Handlers = new()
45+
{
46+
SamplingHandler = samplingClient.CreateSamplingHandler()
47+
}
4548
},
4649
loggerFactory: loggerFactory);
4750

samples/InMemoryTransport/Program.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,7 @@
1010
new StreamServerTransport(clientToServerPipe.Reader.AsStream(), serverToClientPipe.Writer.AsStream()),
1111
new McpServerOptions()
1212
{
13-
Capabilities = new()
14-
{
15-
Tools = new()
16-
{
17-
ToolCollection = [McpServerTool.Create((string arg) => $"Echo: {arg}", new() { Name = "Echo" })]
18-
}
19-
}
13+
ToolCollection = [McpServerTool.Create((string arg) => $"Echo: {arg}", new() { Name = "Echo" })]
2014
});
2115
_ = server.RunAsync();
2216

src/ModelContextProtocol.Core/Client/IMcpClient.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
using ModelContextProtocol.Protocol;
2+
using System.ComponentModel;
23

34
namespace ModelContextProtocol.Client;
45

56
/// <summary>
67
/// Represents an instance of a Model Context Protocol (MCP) client that connects to and communicates with an MCP server.
78
/// </summary>
8-
[Obsolete($"Use {nameof(McpClient)} instead.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
9+
[Obsolete($"Use {nameof(McpClient)} instead. This member will be removed in a subsequent release.")] // See: https://github.com/modelcontextprotocol/csharp-sdk/issues/774
10+
[EditorBrowsable(EditorBrowsableState.Never)]
911
public interface IMcpClient : IMcpEndpoint
1012
{
1113
/// <summary>

src/ModelContextProtocol.Core/Client/McpClient.Methods.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,11 +631,11 @@ internal static CreateMessageResult ToCreateMessageResult(ChatResponse chatRespo
631631
}
632632

633633
/// <summary>
634-
/// Creates a sampling handler for use with <see cref="SamplingCapability.SamplingHandler"/> that will
634+
/// Creates a sampling handler for use with <see cref="McpClientHandlers.SamplingHandler"/> that will
635635
/// satisfy sampling requests using the specified <see cref="IChatClient"/>.
636636
/// </summary>
637637
/// <param name="chatClient">The <see cref="IChatClient"/> with which to satisfy sampling requests.</param>
638-
/// <returns>The created handler delegate that can be assigned to <see cref="SamplingCapability.SamplingHandler"/>.</returns>
638+
/// <returns>The created handler delegate that can be assigned to <see cref="McpClientHandlers.SamplingHandler"/>.</returns>
639639
/// <exception cref="ArgumentNullException"><paramref name="chatClient"/> is <see langword="null"/>.</exception>
640640
public static Func<CreateMessageRequestParams?, IProgress<ProgressNotificationValue>, CancellationToken, ValueTask<CreateMessageResult>> CreateSamplingHandler(
641641
IChatClient chatClient)

0 commit comments

Comments
 (0)