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:
parent
f1cc2d81de
commit
f4c87f5e2f
51 changed files with 477 additions and 306 deletions
|
|
@ -4,6 +4,9 @@ root = true
|
||||||
# C# files
|
# C# files
|
||||||
[*.cs]
|
[*.cs]
|
||||||
|
|
||||||
|
# Compiler
|
||||||
|
dotnet_diagnostic.CS1998.severity = suggestion # CS1998: Missing awaits
|
||||||
|
|
||||||
# Code Analysis
|
# Code Analysis
|
||||||
dotnet_diagnostic.CA1002.severity = none # CA1002: Do not expose generic lists
|
dotnet_diagnostic.CA1002.severity = none # CA1002: Do not expose generic lists
|
||||||
dotnet_diagnostic.CA1031.severity = none # CA1031: Do not catch general exception types
|
dotnet_diagnostic.CA1031.severity = none # CA1031: Do not catch general exception types
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ using ModelContextProtocol;
|
||||||
using ModelContextProtocol.Protocol.Types;
|
using ModelContextProtocol.Protocol.Types;
|
||||||
using ModelContextProtocol.Server;
|
using ModelContextProtocol.Server;
|
||||||
|
|
||||||
|
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||||
|
|
||||||
var builder = Host.CreateApplicationBuilder(args);
|
var builder = Host.CreateApplicationBuilder(args);
|
||||||
builder.Logging.AddConsole(consoleLogOptions =>
|
builder.Logging.AddConsole(consoleLogOptions =>
|
||||||
{
|
{
|
||||||
|
|
@ -31,17 +33,17 @@ builder.Services
|
||||||
.WithTools<TinyImageTool>()
|
.WithTools<TinyImageTool>()
|
||||||
.WithPrompts<ComplexPromptType>()
|
.WithPrompts<ComplexPromptType>()
|
||||||
.WithPrompts<SimplePromptType>()
|
.WithPrompts<SimplePromptType>()
|
||||||
.WithListResourceTemplatesHandler((ctx, ct) =>
|
.WithListResourceTemplatesHandler(async (ctx, ct) =>
|
||||||
{
|
{
|
||||||
return Task.FromResult(new ListResourceTemplatesResult
|
return new ListResourceTemplatesResult
|
||||||
{
|
{
|
||||||
ResourceTemplates =
|
ResourceTemplates =
|
||||||
[
|
[
|
||||||
new ResourceTemplate { Name = "Static Resource", Description = "A static resource with a numeric ID", UriTemplate = "test://static/resource/{id}" }
|
new ResourceTemplate { Name = "Static Resource", Description = "A static resource with a numeric ID", UriTemplate = "test://static/resource/{id}" }
|
||||||
]
|
]
|
||||||
});
|
};
|
||||||
})
|
})
|
||||||
.WithReadResourceHandler((ctx, ct) =>
|
.WithReadResourceHandler(async (ctx, ct) =>
|
||||||
{
|
{
|
||||||
var uri = ctx.Params?.Uri;
|
var uri = ctx.Params?.Uri;
|
||||||
|
|
||||||
|
|
@ -61,7 +63,7 @@ builder.Services
|
||||||
|
|
||||||
if (resource.MimeType == "text/plain")
|
if (resource.MimeType == "text/plain")
|
||||||
{
|
{
|
||||||
return Task.FromResult(new ReadResourceResult
|
return new ReadResourceResult
|
||||||
{
|
{
|
||||||
Contents = [new TextResourceContents
|
Contents = [new TextResourceContents
|
||||||
{
|
{
|
||||||
|
|
@ -69,11 +71,11 @@ builder.Services
|
||||||
MimeType = resource.MimeType,
|
MimeType = resource.MimeType,
|
||||||
Uri = resource.Uri,
|
Uri = resource.Uri,
|
||||||
}]
|
}]
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return Task.FromResult(new ReadResourceResult
|
return new ReadResourceResult
|
||||||
{
|
{
|
||||||
Contents = [new BlobResourceContents
|
Contents = [new BlobResourceContents
|
||||||
{
|
{
|
||||||
|
|
@ -81,7 +83,7 @@ builder.Services
|
||||||
MimeType = resource.MimeType,
|
MimeType = resource.MimeType,
|
||||||
Uri = resource.Uri,
|
Uri = resource.Uri,
|
||||||
}]
|
}]
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.WithSubscribeToResourcesHandler(async (ctx, ct) =>
|
.WithSubscribeToResourcesHandler(async (ctx, ct) =>
|
||||||
|
|
@ -106,16 +108,16 @@ builder.Services
|
||||||
|
|
||||||
return new EmptyResult();
|
return new EmptyResult();
|
||||||
})
|
})
|
||||||
.WithUnsubscribeFromResourcesHandler((ctx, ct) =>
|
.WithUnsubscribeFromResourcesHandler(async (ctx, ct) =>
|
||||||
{
|
{
|
||||||
var uri = ctx.Params?.Uri;
|
var uri = ctx.Params?.Uri;
|
||||||
if (uri is not null)
|
if (uri is not null)
|
||||||
{
|
{
|
||||||
subscriptions.Remove(uri);
|
subscriptions.Remove(uri);
|
||||||
}
|
}
|
||||||
return Task.FromResult(new EmptyResult());
|
return new EmptyResult();
|
||||||
})
|
})
|
||||||
.WithCompleteHandler((ctx, ct) =>
|
.WithCompleteHandler(async (ctx, ct) =>
|
||||||
{
|
{
|
||||||
var exampleCompletions = new Dictionary<string, IEnumerable<string>>
|
var exampleCompletions = new Dictionary<string, IEnumerable<string>>
|
||||||
{
|
{
|
||||||
|
|
@ -138,15 +140,15 @@ builder.Services
|
||||||
|
|
||||||
if (resourceId is null)
|
if (resourceId is null)
|
||||||
{
|
{
|
||||||
return Task.FromResult(new CompleteResult());
|
return new CompleteResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
var values = exampleCompletions["resourceId"].Where(id => id.StartsWith(argument.Value));
|
var values = exampleCompletions["resourceId"].Where(id => id.StartsWith(argument.Value));
|
||||||
|
|
||||||
return Task.FromResult(new CompleteResult
|
return new CompleteResult
|
||||||
{
|
{
|
||||||
Completion = new Completion { Values = [.. values], HasMore = false, Total = values.Count() }
|
Completion = new Completion { Values = [.. values], HasMore = false, Total = values.Count() }
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (@ref.Type == "ref/prompt")
|
if (@ref.Type == "ref/prompt")
|
||||||
|
|
@ -157,10 +159,10 @@ builder.Services
|
||||||
}
|
}
|
||||||
|
|
||||||
var values = value.Where(value => value.StartsWith(argument.Value));
|
var values = value.Where(value => value.StartsWith(argument.Value));
|
||||||
return Task.FromResult(new CompleteResult
|
return new CompleteResult
|
||||||
{
|
{
|
||||||
Completion = new Completion { Values = [.. values], HasMore = false, Total = values.Count() }
|
Completion = new Completion { Values = [.. values], HasMore = false, Total = values.Count() }
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new NotSupportedException($"Unknown reference type: {@ref.Type}");
|
throw new NotSupportedException($"Unknown reference type: {@ref.Type}");
|
||||||
|
|
@ -182,8 +184,7 @@ builder.Services
|
||||||
}, cancellationToken: ct);
|
}, cancellationToken: ct);
|
||||||
|
|
||||||
return new EmptyResult();
|
return new EmptyResult();
|
||||||
})
|
});
|
||||||
;
|
|
||||||
|
|
||||||
builder.Services.AddSingleton(subscriptions);
|
builder.Services.AddSingleton(subscriptions);
|
||||||
builder.Services.AddHostedService<SubscriptionMessageSender>();
|
builder.Services.AddHostedService<SubscriptionMessageSender>();
|
||||||
|
|
|
||||||
|
|
@ -948,7 +948,7 @@ public static class McpClientExtensions
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="chatClient"/> is <see langword="null"/>.</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="chatClient"/> is <see langword="null"/>.</exception>
|
||||||
public static Func<CreateMessageRequestParams?, IProgress<ProgressNotificationValue>, CancellationToken, Task<CreateMessageResult>> CreateSamplingHandler(
|
public static Func<CreateMessageRequestParams?, IProgress<ProgressNotificationValue>, CancellationToken, ValueTask<CreateMessageResult>> CreateSamplingHandler(
|
||||||
this IChatClient chatClient)
|
this IChatClient chatClient)
|
||||||
{
|
{
|
||||||
Throw.IfNull(chatClient);
|
Throw.IfNull(chatClient);
|
||||||
|
|
|
||||||
|
|
@ -275,7 +275,7 @@ public static partial class McpServerBuilderExtensions
|
||||||
/// resource system where templates define the URI patterns and the read handler provides the actual content.
|
/// resource system where templates define the URI patterns and the read handler provides the actual content.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static IMcpServerBuilder WithListResourceTemplatesHandler(this IMcpServerBuilder builder, Func<RequestContext<ListResourceTemplatesRequestParams>, CancellationToken, Task<ListResourceTemplatesResult>> handler)
|
public static IMcpServerBuilder WithListResourceTemplatesHandler(this IMcpServerBuilder builder, Func<RequestContext<ListResourceTemplatesRequestParams>, CancellationToken, ValueTask<ListResourceTemplatesResult>> handler)
|
||||||
{
|
{
|
||||||
Throw.IfNull(builder);
|
Throw.IfNull(builder);
|
||||||
|
|
||||||
|
|
@ -308,7 +308,7 @@ public static partial class McpServerBuilderExtensions
|
||||||
/// executes them when invoked by clients.
|
/// executes them when invoked by clients.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static IMcpServerBuilder WithListToolsHandler(this IMcpServerBuilder builder, Func<RequestContext<ListToolsRequestParams>, CancellationToken, Task<ListToolsResult>> handler)
|
public static IMcpServerBuilder WithListToolsHandler(this IMcpServerBuilder builder, Func<RequestContext<ListToolsRequestParams>, CancellationToken, ValueTask<ListToolsResult>> handler)
|
||||||
{
|
{
|
||||||
Throw.IfNull(builder);
|
Throw.IfNull(builder);
|
||||||
|
|
||||||
|
|
@ -328,7 +328,7 @@ public static partial class McpServerBuilderExtensions
|
||||||
/// This method is typically paired with <see cref="WithListToolsHandler"/> to provide a complete tools implementation,
|
/// This method is typically paired with <see cref="WithListToolsHandler"/> to provide a complete tools implementation,
|
||||||
/// where <see cref="WithListToolsHandler"/> advertises available tools and this handler executes them.
|
/// where <see cref="WithListToolsHandler"/> advertises available tools and this handler executes them.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static IMcpServerBuilder WithCallToolHandler(this IMcpServerBuilder builder, Func<RequestContext<CallToolRequestParams>, CancellationToken, Task<CallToolResponse>> handler)
|
public static IMcpServerBuilder WithCallToolHandler(this IMcpServerBuilder builder, Func<RequestContext<CallToolRequestParams>, CancellationToken, ValueTask<CallToolResponse>> handler)
|
||||||
{
|
{
|
||||||
Throw.IfNull(builder);
|
Throw.IfNull(builder);
|
||||||
|
|
||||||
|
|
@ -361,7 +361,7 @@ public static partial class McpServerBuilderExtensions
|
||||||
/// produces them when invoked by clients.
|
/// produces them when invoked by clients.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static IMcpServerBuilder WithListPromptsHandler(this IMcpServerBuilder builder, Func<RequestContext<ListPromptsRequestParams>, CancellationToken, Task<ListPromptsResult>> handler)
|
public static IMcpServerBuilder WithListPromptsHandler(this IMcpServerBuilder builder, Func<RequestContext<ListPromptsRequestParams>, CancellationToken, ValueTask<ListPromptsResult>> handler)
|
||||||
{
|
{
|
||||||
Throw.IfNull(builder);
|
Throw.IfNull(builder);
|
||||||
|
|
||||||
|
|
@ -376,7 +376,7 @@ public static partial class McpServerBuilderExtensions
|
||||||
/// <param name="handler">The handler function that processes prompt requests.</param>
|
/// <param name="handler">The handler function that processes prompt requests.</param>
|
||||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||||
public static IMcpServerBuilder WithGetPromptHandler(this IMcpServerBuilder builder, Func<RequestContext<GetPromptRequestParams>, CancellationToken, Task<GetPromptResult>> handler)
|
public static IMcpServerBuilder WithGetPromptHandler(this IMcpServerBuilder builder, Func<RequestContext<GetPromptRequestParams>, CancellationToken, ValueTask<GetPromptResult>> handler)
|
||||||
{
|
{
|
||||||
Throw.IfNull(builder);
|
Throw.IfNull(builder);
|
||||||
|
|
||||||
|
|
@ -397,7 +397,7 @@ public static partial class McpServerBuilderExtensions
|
||||||
/// where this handler advertises available resources and the read handler provides their content when requested.
|
/// where this handler advertises available resources and the read handler provides their content when requested.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static IMcpServerBuilder WithListResourcesHandler(this IMcpServerBuilder builder, Func<RequestContext<ListResourcesRequestParams>, CancellationToken, Task<ListResourcesResult>> handler)
|
public static IMcpServerBuilder WithListResourcesHandler(this IMcpServerBuilder builder, Func<RequestContext<ListResourcesRequestParams>, CancellationToken, ValueTask<ListResourcesResult>> handler)
|
||||||
{
|
{
|
||||||
Throw.IfNull(builder);
|
Throw.IfNull(builder);
|
||||||
|
|
||||||
|
|
@ -416,7 +416,7 @@ public static partial class McpServerBuilderExtensions
|
||||||
/// This handler is typically paired with <see cref="WithListResourcesHandler"/> to provide a complete resources implementation,
|
/// This handler is typically paired with <see cref="WithListResourcesHandler"/> to provide a complete resources implementation,
|
||||||
/// where the list handler advertises available resources and the read handler provides their content when requested.
|
/// where the list handler advertises available resources and the read handler provides their content when requested.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static IMcpServerBuilder WithReadResourceHandler(this IMcpServerBuilder builder, Func<RequestContext<ReadResourceRequestParams>, CancellationToken, Task<ReadResourceResult>> handler)
|
public static IMcpServerBuilder WithReadResourceHandler(this IMcpServerBuilder builder, Func<RequestContext<ReadResourceRequestParams>, CancellationToken, ValueTask<ReadResourceResult>> handler)
|
||||||
{
|
{
|
||||||
Throw.IfNull(builder);
|
Throw.IfNull(builder);
|
||||||
|
|
||||||
|
|
@ -435,7 +435,7 @@ public static partial class McpServerBuilderExtensions
|
||||||
/// The completion handler is invoked when clients request suggestions for argument values.
|
/// The completion handler is invoked when clients request suggestions for argument values.
|
||||||
/// This enables auto-complete functionality for both prompt arguments and resource references.
|
/// This enables auto-complete functionality for both prompt arguments and resource references.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static IMcpServerBuilder WithCompleteHandler(this IMcpServerBuilder builder, Func<RequestContext<CompleteRequestParams>, CancellationToken, Task<CompleteResult>> handler)
|
public static IMcpServerBuilder WithCompleteHandler(this IMcpServerBuilder builder, Func<RequestContext<CompleteRequestParams>, CancellationToken, ValueTask<CompleteResult>> handler)
|
||||||
{
|
{
|
||||||
Throw.IfNull(builder);
|
Throw.IfNull(builder);
|
||||||
|
|
||||||
|
|
@ -465,7 +465,7 @@ public static partial class McpServerBuilderExtensions
|
||||||
/// resources and to send appropriate notifications through the connection when resources change.
|
/// resources and to send appropriate notifications through the connection when resources change.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static IMcpServerBuilder WithSubscribeToResourcesHandler(this IMcpServerBuilder builder, Func<RequestContext<SubscribeRequestParams>, CancellationToken, Task<EmptyResult>> handler)
|
public static IMcpServerBuilder WithSubscribeToResourcesHandler(this IMcpServerBuilder builder, Func<RequestContext<SubscribeRequestParams>, CancellationToken, ValueTask<EmptyResult>> handler)
|
||||||
{
|
{
|
||||||
Throw.IfNull(builder);
|
Throw.IfNull(builder);
|
||||||
|
|
||||||
|
|
@ -495,7 +495,7 @@ public static partial class McpServerBuilderExtensions
|
||||||
/// to the specified resource.
|
/// to the specified resource.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static IMcpServerBuilder WithUnsubscribeFromResourcesHandler(this IMcpServerBuilder builder, Func<RequestContext<UnsubscribeRequestParams>, CancellationToken, Task<EmptyResult>> handler)
|
public static IMcpServerBuilder WithUnsubscribeFromResourcesHandler(this IMcpServerBuilder builder, Func<RequestContext<UnsubscribeRequestParams>, CancellationToken, ValueTask<EmptyResult>> handler)
|
||||||
{
|
{
|
||||||
Throw.IfNull(builder);
|
Throw.IfNull(builder);
|
||||||
|
|
||||||
|
|
@ -522,7 +522,7 @@ public static partial class McpServerBuilderExtensions
|
||||||
/// most recently set level.
|
/// most recently set level.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static IMcpServerBuilder WithSetLoggingLevelHandler(this IMcpServerBuilder builder, Func<RequestContext<SetLevelRequestParams>, CancellationToken, Task<EmptyResult>> handler)
|
public static IMcpServerBuilder WithSetLoggingLevelHandler(this IMcpServerBuilder builder, Func<RequestContext<SetLevelRequestParams>, CancellationToken, ValueTask<EmptyResult>> handler)
|
||||||
{
|
{
|
||||||
Throw.IfNull(builder);
|
Throw.IfNull(builder);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ internal sealed class SingleSessionMcpServerHostedService(IMcpServer session, IH
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await session.RunAsync(stoppingToken);
|
await session.RunAsync(stoppingToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -69,5 +69,5 @@ public interface IMcpEndpoint : IAsyncDisposable
|
||||||
/// <param name="method">The notification method.</param>
|
/// <param name="method">The notification method.</param>
|
||||||
/// <param name="handler">The handler to be invoked.</param>
|
/// <param name="handler">The handler to be invoked.</param>
|
||||||
/// <returns>An <see cref="IDisposable"/> that will remove the registered handler when disposed.</returns>
|
/// <returns>An <see cref="IDisposable"/> that will remove the registered handler when disposed.</returns>
|
||||||
IAsyncDisposable RegisterNotificationHandler(string method, Func<JsonRpcNotification, CancellationToken, Task> handler);
|
IAsyncDisposable RegisterNotificationHandler(string method, Func<JsonRpcNotification, CancellationToken, ValueTask> handler);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ public class StreamServerTransport : TransportBase
|
||||||
|
|
||||||
await JsonSerializer.SerializeAsync(_outputStream, message, McpJsonUtilities.DefaultOptions.GetTypeInfo(typeof(IJsonRpcMessage)), cancellationToken).ConfigureAwait(false);
|
await JsonSerializer.SerializeAsync(_outputStream, message, McpJsonUtilities.DefaultOptions.GetTypeInfo(typeof(IJsonRpcMessage)), cancellationToken).ConfigureAwait(false);
|
||||||
await _outputStream.WriteAsync(s_newlineBytes, 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);
|
_logger.TransportSentMessage(_endpointName, id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,5 +77,5 @@ public class ClientCapabilities
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IEnumerable<KeyValuePair<string, Func<JsonRpcNotification, CancellationToken, Task>>>? NotificationHandlers { get; set; }
|
public IEnumerable<KeyValuePair<string, Func<JsonRpcNotification, CancellationToken, ValueTask>>>? NotificationHandlers { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -33,5 +33,5 @@ public class CompletionsCapability
|
||||||
/// and should return appropriate completion suggestions.
|
/// and should return appropriate completion suggestions.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<CompleteRequestParams>, CancellationToken, Task<CompleteResult>>? CompleteHandler { get; set; }
|
public Func<RequestContext<CompleteRequestParams>, CancellationToken, ValueTask<CompleteResult>>? CompleteHandler { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -9,5 +9,5 @@ namespace ModelContextProtocol.Protocol.Types;
|
||||||
public class EmptyResult
|
public class EmptyResult
|
||||||
{
|
{
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
internal static Task<EmptyResult> CompletedTask { get; } = Task.FromResult(new EmptyResult());
|
internal static EmptyResult Instance { get; } = new();
|
||||||
}
|
}
|
||||||
|
|
@ -19,5 +19,5 @@ public class LoggingCapability
|
||||||
/// Gets or sets the handler for set logging level requests from clients.
|
/// Gets or sets the handler for set logging level requests from clients.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<SetLevelRequestParams>, CancellationToken, Task<EmptyResult>>? SetLoggingLevelHandler { get; set; }
|
public Func<RequestContext<SetLevelRequestParams>, CancellationToken, ValueTask<EmptyResult>>? SetLoggingLevelHandler { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ public class PromptsCapability
|
||||||
/// along with any prompts defined in <see cref="PromptCollection"/>.
|
/// along with any prompts defined in <see cref="PromptCollection"/>.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<ListPromptsRequestParams>, CancellationToken, Task<ListPromptsResult>>? ListPromptsHandler { get; set; }
|
public Func<RequestContext<ListPromptsRequestParams>, CancellationToken, ValueTask<ListPromptsResult>>? ListPromptsHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for <see cref="RequestMethods.PromptsGet"/> requests.
|
/// Gets or sets the handler for <see cref="RequestMethods.PromptsGet"/> requests.
|
||||||
|
|
@ -58,7 +58,7 @@ public class PromptsCapability
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<GetPromptRequestParams>, CancellationToken, Task<GetPromptResult>>? GetPromptHandler { get; set; }
|
public Func<RequestContext<GetPromptRequestParams>, CancellationToken, ValueTask<GetPromptResult>>? GetPromptHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a collection of prompts that will be served by the server.
|
/// Gets or sets a collection of prompts that will be served by the server.
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ public class ResourcesCapability
|
||||||
/// allowing clients to discover available resource types and their access patterns.
|
/// allowing clients to discover available resource types and their access patterns.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<ListResourceTemplatesRequestParams>, CancellationToken, Task<ListResourceTemplatesResult>>? ListResourceTemplatesHandler { get; set; }
|
public Func<RequestContext<ListResourceTemplatesRequestParams>, CancellationToken, ValueTask<ListResourceTemplatesResult>>? ListResourceTemplatesHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for <see cref="RequestMethods.ResourcesList"/> requests.
|
/// 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.
|
/// The implementation should return a <see cref="ListResourcesResult"/> with the matching resources.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<ListResourcesRequestParams>, CancellationToken, Task<ListResourcesResult>>? ListResourcesHandler { get; set; }
|
public Func<RequestContext<ListResourcesRequestParams>, CancellationToken, ValueTask<ListResourcesResult>>? ListResourcesHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for <see cref="RequestMethods.ResourcesRead"/> requests.
|
/// Gets or sets the handler for <see cref="RequestMethods.ResourcesRead"/> requests.
|
||||||
|
|
@ -62,7 +62,7 @@ public class ResourcesCapability
|
||||||
/// its contents in a ReadResourceResult object.
|
/// its contents in a ReadResourceResult object.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<ReadResourceRequestParams>, CancellationToken, Task<ReadResourceResult>>? ReadResourceHandler { get; set; }
|
public Func<RequestContext<ReadResourceRequestParams>, CancellationToken, ValueTask<ReadResourceResult>>? ReadResourceHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for <see cref="RequestMethods.ResourcesSubscribe"/> requests.
|
/// Gets or sets the handler for <see cref="RequestMethods.ResourcesSubscribe"/> requests.
|
||||||
|
|
@ -75,7 +75,7 @@ public class ResourcesCapability
|
||||||
/// requiring polling.
|
/// requiring polling.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<SubscribeRequestParams>, CancellationToken, Task<EmptyResult>>? SubscribeToResourcesHandler { get; set; }
|
public Func<RequestContext<SubscribeRequestParams>, CancellationToken, ValueTask<EmptyResult>>? SubscribeToResourcesHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for <see cref="RequestMethods.ResourcesUnsubscribe"/> requests.
|
/// Gets or sets the handler for <see cref="RequestMethods.ResourcesUnsubscribe"/> requests.
|
||||||
|
|
@ -86,5 +86,5 @@ public class ResourcesCapability
|
||||||
/// about the specified resource.
|
/// about the specified resource.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<UnsubscribeRequestParams>, CancellationToken, Task<EmptyResult>>? UnsubscribeFromResourcesHandler { get; set; }
|
public Func<RequestContext<UnsubscribeRequestParams>, CancellationToken, ValueTask<EmptyResult>>? UnsubscribeFromResourcesHandler { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -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.
|
/// The handler receives request parameters and should return a <see cref="ListRootsResult"/> containing the collection of available roots.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<ListRootsRequestParams?, CancellationToken, Task<ListRootsResult>>? RootsHandler { get; set; }
|
public Func<ListRootsRequestParams?, CancellationToken, ValueTask<ListRootsResult>>? RootsHandler { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -40,5 +40,5 @@ public class SamplingCapability
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<CreateMessageRequestParams?, IProgress<ProgressNotificationValue>, CancellationToken, Task<CreateMessageResult>>? SamplingHandler { get; set; }
|
public Func<CreateMessageRequestParams?, IProgress<ProgressNotificationValue>, CancellationToken, ValueTask<CreateMessageResult>>? SamplingHandler { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -83,5 +83,5 @@ public class ServerCapabilities
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IEnumerable<KeyValuePair<string, Func<JsonRpcNotification, CancellationToken, Task>>>? NotificationHandlers { get; set; }
|
public IEnumerable<KeyValuePair<string, Func<JsonRpcNotification, CancellationToken, ValueTask>>>? NotificationHandlers { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ public class ToolsCapability
|
||||||
/// and the tools from the collection will be combined to form the complete list of available tools.
|
/// and the tools from the collection will be combined to form the complete list of available tools.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<ListToolsRequestParams>, CancellationToken, Task<ListToolsResult>>? ListToolsHandler { get; set; }
|
public Func<RequestContext<ListToolsRequestParams>, CancellationToken, ValueTask<ListToolsResult>>? ListToolsHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for <see cref="RequestMethods.ToolsCall"/> requests.
|
/// 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.
|
/// being called and its arguments, and should return a <see cref="CallToolResponse"/> with the execution results.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<CallToolRequestParams>, CancellationToken, Task<CallToolResponse>>? CallToolHandler { get; set; }
|
public Func<RequestContext<CallToolRequestParams>, CancellationToken, ValueTask<CallToolResponse>>? CallToolHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a collection of tools served by the server.
|
/// Gets or sets a collection of tools served by the server.
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ internal sealed class AIFunctionMcpServerPrompt : McpServerPrompt
|
||||||
{
|
{
|
||||||
ExcludeFromSchema = true,
|
ExcludeFromSchema = true,
|
||||||
BindParameter = (pi, args) =>
|
BindParameter = (pi, args) =>
|
||||||
GetRequestContext(args)?.Server?.Services?.GetService(pi.ParameterType) ??
|
GetRequestContext(args)?.Services?.GetService(pi.ParameterType) ??
|
||||||
(pi.HasDefaultValue ? null :
|
(pi.HasDefaultValue ? null :
|
||||||
throw new ArgumentException("No service of the requested type was found.")),
|
throw new ArgumentException("No service of the requested type was found.")),
|
||||||
};
|
};
|
||||||
|
|
@ -111,7 +111,7 @@ internal sealed class AIFunctionMcpServerPrompt : McpServerPrompt
|
||||||
{
|
{
|
||||||
ExcludeFromSchema = true,
|
ExcludeFromSchema = true,
|
||||||
BindParameter = (pi, args) =>
|
BindParameter = (pi, args) =>
|
||||||
(GetRequestContext(args)?.Server?.Services as IKeyedServiceProvider)?.GetKeyedService(pi.ParameterType, keyedAttr.Key) ??
|
(GetRequestContext(args)?.Services as IKeyedServiceProvider)?.GetKeyedService(pi.ParameterType, keyedAttr.Key) ??
|
||||||
(pi.HasDefaultValue ? null :
|
(pi.HasDefaultValue ? null :
|
||||||
throw new ArgumentException("No service of the requested type was found.")),
|
throw new ArgumentException("No service of the requested type was found.")),
|
||||||
};
|
};
|
||||||
|
|
@ -206,7 +206,7 @@ internal sealed class AIFunctionMcpServerPrompt : McpServerPrompt
|
||||||
/// <item><description><see cref="ChatMessage"/> objects are converted to prompt messages</description></item>
|
/// <item><description><see cref="ChatMessage"/> objects are converted to prompt messages</description></item>
|
||||||
/// </list>
|
/// </list>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public override async Task<GetPromptResult> GetAsync(
|
public override async ValueTask<GetPromptResult> GetAsync(
|
||||||
RequestContext<GetPromptRequestParams> request, CancellationToken cancellationToken = default)
|
RequestContext<GetPromptRequestParams> request, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
Throw.IfNull(request);
|
Throw.IfNull(request);
|
||||||
|
|
@ -214,7 +214,7 @@ internal sealed class AIFunctionMcpServerPrompt : McpServerPrompt
|
||||||
|
|
||||||
AIFunctionArguments arguments = new()
|
AIFunctionArguments arguments = new()
|
||||||
{
|
{
|
||||||
Services = request.Server?.Services,
|
Services = request.Services,
|
||||||
Context = new Dictionary<object, object?>() { [typeof(RequestContext<GetPromptRequestParams>)] = request }
|
Context = new Dictionary<object, object?>() { [typeof(RequestContext<GetPromptRequestParams>)] = request }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ internal sealed class AIFunctionMcpServerTool : McpServerTool
|
||||||
{
|
{
|
||||||
ExcludeFromSchema = true,
|
ExcludeFromSchema = true,
|
||||||
BindParameter = (pi, args) =>
|
BindParameter = (pi, args) =>
|
||||||
GetRequestContext(args)?.Server?.Services?.GetService(pi.ParameterType) ??
|
GetRequestContext(args)?.Services?.GetService(pi.ParameterType) ??
|
||||||
(pi.HasDefaultValue ? null :
|
(pi.HasDefaultValue ? null :
|
||||||
throw new ArgumentException("No service of the requested type was found.")),
|
throw new ArgumentException("No service of the requested type was found.")),
|
||||||
};
|
};
|
||||||
|
|
@ -132,7 +132,7 @@ internal sealed class AIFunctionMcpServerTool : McpServerTool
|
||||||
{
|
{
|
||||||
ExcludeFromSchema = true,
|
ExcludeFromSchema = true,
|
||||||
BindParameter = (pi, args) =>
|
BindParameter = (pi, args) =>
|
||||||
(GetRequestContext(args)?.Server?.Services as IKeyedServiceProvider)?.GetKeyedService(pi.ParameterType, keyedAttr.Key) ??
|
(GetRequestContext(args)?.Services as IKeyedServiceProvider)?.GetKeyedService(pi.ParameterType, keyedAttr.Key) ??
|
||||||
(pi.HasDefaultValue ? null :
|
(pi.HasDefaultValue ? null :
|
||||||
throw new ArgumentException("No service of the requested type was found.")),
|
throw new ArgumentException("No service of the requested type was found.")),
|
||||||
};
|
};
|
||||||
|
|
@ -237,7 +237,7 @@ internal sealed class AIFunctionMcpServerTool : McpServerTool
|
||||||
public override Tool ProtocolTool { get; }
|
public override Tool ProtocolTool { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override async Task<CallToolResponse> InvokeAsync(
|
public override async ValueTask<CallToolResponse> InvokeAsync(
|
||||||
RequestContext<CallToolRequestParams> request, CancellationToken cancellationToken = default)
|
RequestContext<CallToolRequestParams> request, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
Throw.IfNull(request);
|
Throw.IfNull(request);
|
||||||
|
|
@ -245,7 +245,7 @@ internal sealed class AIFunctionMcpServerTool : McpServerTool
|
||||||
|
|
||||||
AIFunctionArguments arguments = new()
|
AIFunctionArguments arguments = new()
|
||||||
{
|
{
|
||||||
Services = request.Server?.Services,
|
Services = request.Services,
|
||||||
Context = new Dictionary<object, object?>() { [typeof(RequestContext<CallToolRequestParams>)] = request }
|
Context = new Dictionary<object, object?>() { [typeof(RequestContext<CallToolRequestParams>)] = request }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ public abstract class DelegatingMcpServerPrompt : McpServerPrompt
|
||||||
public override Prompt ProtocolPrompt => _innerPrompt.ProtocolPrompt;
|
public override Prompt ProtocolPrompt => _innerPrompt.ProtocolPrompt;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Task<GetPromptResult> GetAsync(
|
public override ValueTask<GetPromptResult> GetAsync(
|
||||||
RequestContext<GetPromptRequestParams> request,
|
RequestContext<GetPromptRequestParams> request,
|
||||||
CancellationToken cancellationToken = default) =>
|
CancellationToken cancellationToken = default) =>
|
||||||
_innerPrompt.GetAsync(request, cancellationToken);
|
_innerPrompt.GetAsync(request, cancellationToken);
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue