-
Notifications
You must be signed in to change notification settings - Fork 512
Decouple Handlers and Collections from protocol types #765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jozkee
wants to merge
3
commits into
modelcontextprotocol:main
Choose a base branch
from
jozkee:capabilities4
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,311
−1,349
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
using Microsoft.Extensions.AI; | ||
using ModelContextProtocol.Protocol; | ||
|
||
namespace ModelContextProtocol.Client; | ||
|
||
/// <summary> | ||
/// Provides a container for handlers used in the creation of an MCP client. | ||
/// </summary> | ||
/// <remarks> | ||
/// <para> | ||
/// This class provides a centralized collection of delegates that implement various capabilities of the Model Context Protocol. | ||
/// </para> | ||
/// <para> | ||
/// Each handler in this class corresponds to a specific client endpoint in the Model Context Protocol and | ||
/// is responsible for processing a particular type of message. The handlers are used to customize | ||
/// the behavior of the MCP server by providing implementations for the various protocol operations. | ||
/// </para> | ||
/// <para> | ||
/// When a server sends a message to the client, the appropriate handler is invoked to process it | ||
/// according to the protocol specification. Which handler is selected | ||
/// is done based on an ordinal, case-sensitive string comparison. | ||
/// </para> | ||
/// </remarks> | ||
public class McpClientHandlers | ||
{ | ||
|
||
/// <summary>Gets or sets notification handlers to register with the client.</summary> | ||
/// <remarks> | ||
/// <para> | ||
/// When constructed, the client will enumerate these handlers once, which may contain multiple handlers per notification method key. | ||
/// The client will not re-enumerate the sequence after initialization. | ||
/// </para> | ||
/// <para> | ||
/// Notification handlers allow the client to respond to server-sent notifications for specific methods. | ||
/// Each key in the collection is a notification method name, and each value is a callback that will be invoked | ||
/// when a notification with that method is received. | ||
/// </para> | ||
/// <para> | ||
/// Handlers provided via <see cref="NotificationHandlers"/> will be registered with the client for the lifetime of the client. | ||
/// For transient handlers, <see cref="IMcpEndpoint.RegisterNotificationHandler"/> may be used to register a handler that can | ||
/// then be unregistered by disposing of the <see cref="IAsyncDisposable"/> returned from the method. | ||
/// </para> | ||
/// </remarks> | ||
public IEnumerable<KeyValuePair<string, Func<JsonRpcNotification, CancellationToken, ValueTask>>>? NotificationHandlers { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the handler for <see cref="RequestMethods.RootsList"/> requests. | ||
/// </summary> | ||
/// <remarks> | ||
/// This handler is invoked when a client sends a <see cref="RequestMethods.RootsList"/> request to retrieve available roots. | ||
/// The handler receives request parameters and should return a <see cref="ListRootsResult"/> containing the collection of available roots. | ||
/// </remarks> | ||
public Func<ListRootsRequestParams?, CancellationToken, ValueTask<ListRootsResult>>? RootsHandler { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the handler for processing <see cref="RequestMethods.ElicitationCreate"/> requests. | ||
/// </summary> | ||
/// <remarks> | ||
/// <para> | ||
/// This handler function is called when an MCP server requests the client to provide additional | ||
/// information during interactions. The client must set this property for the elicitation capability to work. | ||
/// </para> | ||
/// <para> | ||
/// The handler receives message parameters and a cancellation token. | ||
/// It should return a <see cref="ElicitResult"/> containing the response to the elicitation request. | ||
/// </para> | ||
/// </remarks> | ||
public Func<ElicitRequestParams?, CancellationToken, ValueTask<ElicitResult>>? ElicitationHandler { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the handler for processing <see cref="RequestMethods.SamplingCreateMessage"/> requests. | ||
/// </summary> | ||
/// <remarks> | ||
/// <para> | ||
/// This handler function is called when an MCP server requests the client to generate content | ||
/// using an AI model. The client must set this property for the sampling capability to work. | ||
/// </para> | ||
/// <para> | ||
/// The handler receives message parameters, a progress reporter for updates, and a | ||
/// cancellation token. It should return a <see cref="CreateMessageResult"/> containing the | ||
/// generated content. | ||
/// </para> | ||
/// <para> | ||
/// You can create a handler using the <see cref="McpClientExtensions.CreateSamplingHandler"/> extension | ||
/// method with any implementation of <see cref="IChatClient"/>. | ||
/// </para> | ||
/// </remarks> | ||
public Func<CreateMessageRequestParams?, IProgress<ProgressNotificationValue>, CancellationToken, ValueTask<CreateMessageResult>>? SamplingHandler { get; set; } | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not being able to set a handler within the object expression seems to me like a regression from a usability perspective. If decoupling handlers from the capability types is essential, consider using a structure that doesn't force this pattern (e.g. putting all handler properties on the
ServerCapabilities
type itself).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That could be enabled by adding a setter to
McpServerOptions.Handlers
.I thought of having Handlers initialized by default to avoid the null-terminating operator in cases like
Handlers?.ListToolsHandler
. We could still achieve both if we make that the setter disallows null.