Wrap each request in a service scope (#276)

* Wrap each request in a service scope

* Change request/notification delegates to return ValueTask

* Address feedback
This commit is contained in:
Stephen Toub 2025-04-11 19:19:12 -04:00 • committed by GitHub
commit f4c87f5e2f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 477 additions and 306 deletions

View file

@ -82,7 +82,7 @@ public class StreamServerTransport : TransportBase
await JsonSerializer.SerializeAsync(_outputStream, message, McpJsonUtilities.DefaultOptions.GetTypeInfo(typeof(IJsonRpcMessage)), cancellationToken).ConfigureAwait(false);
await _outputStream.WriteAsync(s_newlineBytes, cancellationToken).ConfigureAwait(false);
await _outputStream.FlushAsync(cancellationToken).ConfigureAwait(false);;
await _outputStream.FlushAsync(cancellationToken).ConfigureAwait(false);
_logger.TransportSentMessage(_endpointName, id);
}

View file

@ -77,5 +77,5 @@ public class ClientCapabilities
/// </para>
/// </remarks>
[JsonIgnore]
public IEnumerable<KeyValuePair<string, Func<JsonRpcNotification, CancellationToken, Task>>>? NotificationHandlers { get; set; }
public IEnumerable<KeyValuePair<string, Func<JsonRpcNotification, CancellationToken, ValueTask>>>? NotificationHandlers { get; set; }
}

View file

@ -33,5 +33,5 @@ public class CompletionsCapability
/// and should return appropriate completion suggestions.
/// </remarks>
[JsonIgnore]
public Func<RequestContext<CompleteRequestParams>, CancellationToken, Task<CompleteResult>>? CompleteHandler { get; set; }
public Func<RequestContext<CompleteRequestParams>, CancellationToken, ValueTask<CompleteResult>>? CompleteHandler { get; set; }
}

View file

@ -9,5 +9,5 @@ namespace ModelContextProtocol.Protocol.Types;
public class EmptyResult
{
[JsonIgnore]
internal static Task<EmptyResult> CompletedTask { get; } = Task.FromResult(new EmptyResult());
internal static EmptyResult Instance { get; } = new();
}

View file

@ -19,5 +19,5 @@ public class LoggingCapability
/// Gets or sets the handler for set logging level requests from clients.
/// </summary>
[JsonIgnore]
public Func<RequestContext<SetLevelRequestParams>, CancellationToken, Task<EmptyResult>>? SetLoggingLevelHandler { get; set; }
public Func<RequestContext<SetLevelRequestParams>, CancellationToken, ValueTask<EmptyResult>>? SetLoggingLevelHandler { get; set; }
}

View file

@ -41,7 +41,7 @@ public class PromptsCapability
/// along with any prompts defined in <see cref="PromptCollection"/>.
/// </remarks>
[JsonIgnore]
public Func<RequestContext<ListPromptsRequestParams>, CancellationToken, Task<ListPromptsResult>>? ListPromptsHandler { get; set; }
public Func<RequestContext<ListPromptsRequestParams>, CancellationToken, ValueTask<ListPromptsResult>>? ListPromptsHandler { get; set; }
/// <summary>
/// Gets or sets the handler for <see cref="RequestMethods.PromptsGet"/> requests.
@ -58,7 +58,7 @@ public class PromptsCapability
/// </para>
/// </remarks>
[JsonIgnore]
public Func<RequestContext<GetPromptRequestParams>, CancellationToken, Task<GetPromptResult>>? GetPromptHandler { get; set; }
public Func<RequestContext<GetPromptRequestParams>, CancellationToken, ValueTask<GetPromptResult>>? GetPromptHandler { get; set; }
/// <summary>
/// Gets or sets a collection of prompts that will be served by the server.

View file

@ -40,7 +40,7 @@ public class ResourcesCapability
/// allowing clients to discover available resource types and their access patterns.
/// </remarks>
[JsonIgnore]
public Func<RequestContext<ListResourceTemplatesRequestParams>, CancellationToken, Task<ListResourceTemplatesResult>>? ListResourceTemplatesHandler { get; set; }
public Func<RequestContext<ListResourceTemplatesRequestParams>, CancellationToken, ValueTask<ListResourceTemplatesResult>>? ListResourceTemplatesHandler { get; set; }
/// <summary>
/// Gets or sets the handler for <see cref="RequestMethods.ResourcesList"/> requests.
@ -50,7 +50,7 @@ public class ResourcesCapability
/// The implementation should return a <see cref="ListResourcesResult"/> with the matching resources.
/// </remarks>
[JsonIgnore]
public Func<RequestContext<ListResourcesRequestParams>, CancellationToken, Task<ListResourcesResult>>? ListResourcesHandler { get; set; }
public Func<RequestContext<ListResourcesRequestParams>, CancellationToken, ValueTask<ListResourcesResult>>? ListResourcesHandler { get; set; }
/// <summary>
/// Gets or sets the handler for <see cref="RequestMethods.ResourcesRead"/> requests.
@ -62,7 +62,7 @@ public class ResourcesCapability
/// its contents in a ReadResourceResult object.
/// </remarks>
[JsonIgnore]
public Func<RequestContext<ReadResourceRequestParams>, CancellationToken, Task<ReadResourceResult>>? ReadResourceHandler { get; set; }
public Func<RequestContext<ReadResourceRequestParams>, CancellationToken, ValueTask<ReadResourceResult>>? ReadResourceHandler { get; set; }
/// <summary>
/// Gets or sets the handler for <see cref="RequestMethods.ResourcesSubscribe"/> requests.
@ -75,7 +75,7 @@ public class ResourcesCapability
/// requiring polling.
/// </remarks>
[JsonIgnore]
public Func<RequestContext<SubscribeRequestParams>, CancellationToken, Task<EmptyResult>>? SubscribeToResourcesHandler { get; set; }
public Func<RequestContext<SubscribeRequestParams>, CancellationToken, ValueTask<EmptyResult>>? SubscribeToResourcesHandler { get; set; }
/// <summary>
/// Gets or sets the handler for <see cref="RequestMethods.ResourcesUnsubscribe"/> requests.
@ -86,5 +86,5 @@ public class ResourcesCapability
/// about the specified resource.
/// </remarks>
[JsonIgnore]
public Func<RequestContext<UnsubscribeRequestParams>, CancellationToken, Task<EmptyResult>>? UnsubscribeFromResourcesHandler { get; set; }
public Func<RequestContext<UnsubscribeRequestParams>, CancellationToken, ValueTask<EmptyResult>>? UnsubscribeFromResourcesHandler { get; set; }
}

View file

@ -41,5 +41,5 @@ public class RootsCapability
/// The handler receives request parameters and should return a <see cref="ListRootsResult"/> containing the collection of available roots.
/// </remarks>
[JsonIgnore]
public Func<ListRootsRequestParams?, CancellationToken, Task<ListRootsResult>>? RootsHandler { get; set; }
public Func<ListRootsRequestParams?, CancellationToken, ValueTask<ListRootsResult>>? RootsHandler { get; set; }
}

View file

@ -40,5 +40,5 @@ public class SamplingCapability
/// </para>
/// </remarks>
[JsonIgnore]
public Func<CreateMessageRequestParams?, IProgress<ProgressNotificationValue>, CancellationToken, Task<CreateMessageResult>>? SamplingHandler { get; set; }
public Func<CreateMessageRequestParams?, IProgress<ProgressNotificationValue>, CancellationToken, ValueTask<CreateMessageResult>>? SamplingHandler { get; set; }
}

View file

@ -83,5 +83,5 @@ public class ServerCapabilities
/// </para>
/// </remarks>
[JsonIgnore]
public IEnumerable<KeyValuePair<string, Func<JsonRpcNotification, CancellationToken, Task>>>? NotificationHandlers { get; set; }
public IEnumerable<KeyValuePair<string, Func<JsonRpcNotification, CancellationToken, ValueTask>>>? NotificationHandlers { get; set; }
}

View file

@ -34,7 +34,7 @@ public class ToolsCapability
/// and the tools from the collection will be combined to form the complete list of available tools.
/// </remarks>
[JsonIgnore]
public Func<RequestContext<ListToolsRequestParams>, CancellationToken, Task<ListToolsResult>>? ListToolsHandler { get; set; }
public Func<RequestContext<ListToolsRequestParams>, CancellationToken, ValueTask<ListToolsResult>>? ListToolsHandler { get; set; }
/// <summary>
/// Gets or sets the handler for <see cref="RequestMethods.ToolsCall"/> requests.
@ -46,7 +46,7 @@ public class ToolsCapability
/// being called and its arguments, and should return a <see cref="CallToolResponse"/> with the execution results.
/// </remarks>
[JsonIgnore]
public Func<RequestContext<CallToolRequestParams>, CancellationToken, Task<CallToolResponse>>? CallToolHandler { get; set; }
public Func<RequestContext<CallToolRequestParams>, CancellationToken, ValueTask<CallToolResponse>>? CallToolHandler { get; set; }
/// <summary>
/// Gets or sets a collection of tools served by the server.