Make options types fully mutable (#107)
This commit is contained in:
parent
b61cdef994
commit
95a017a03a
9 changed files with 97 additions and 172 deletions
|
|
@ -7,25 +7,25 @@ namespace ModelContextProtocol.Client;
|
||||||
/// protocol version.
|
/// protocol version.
|
||||||
/// <see href="https://spec.modelcontextprotocol.io/specification/2024-11-05/basic/lifecycle/">See the protocol specification for details on capability negotiation</see>
|
/// <see href="https://spec.modelcontextprotocol.io/specification/2024-11-05/basic/lifecycle/">See the protocol specification for details on capability negotiation</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record McpClientOptions
|
public class McpClientOptions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Information about this client implementation.
|
/// Information about this client implementation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public required Implementation ClientInfo { get; init; }
|
public required Implementation ClientInfo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Client capabilities to advertise to the server.
|
/// Client capabilities to advertise to the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ClientCapabilities? Capabilities { get; init; }
|
public ClientCapabilities? Capabilities { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Protocol version to request from the server.
|
/// Protocol version to request from the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ProtocolVersion { get; init; } = "2024-11-05";
|
public string ProtocolVersion { get; set; } = "2024-11-05";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Timeout for initialization sequence.
|
/// Timeout for initialization sequence.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TimeSpan InitializationTimeout { get; init; } = TimeSpan.FromSeconds(60);
|
public TimeSpan InitializationTimeout { get; set; } = TimeSpan.FromSeconds(60);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,22 +25,14 @@ internal sealed class McpServerOptionsSetup(
|
||||||
|
|
||||||
// Configure the option's server information based on the current process,
|
// Configure the option's server information based on the current process,
|
||||||
// if it otherwise lacks server information.
|
// if it otherwise lacks server information.
|
||||||
var assemblyName = (Assembly.GetEntryAssembly() ?? Assembly.GetCallingAssembly()).GetName();
|
if (options.ServerInfo is not { } serverInfo)
|
||||||
if (options.ServerInfo is not { } serverInfo ||
|
|
||||||
serverInfo.Name is null ||
|
|
||||||
serverInfo.Version is null)
|
|
||||||
{
|
{
|
||||||
options.ServerInfo = options.ServerInfo is null ?
|
var assemblyName = (Assembly.GetEntryAssembly() ?? Assembly.GetCallingAssembly()).GetName();
|
||||||
new()
|
options.ServerInfo = new()
|
||||||
{
|
{
|
||||||
Name = assemblyName.Name ?? "McpServer",
|
Name = assemblyName.Name ?? "McpServer",
|
||||||
Version = assemblyName.Version?.ToString() ?? "1.0.0",
|
Version = assemblyName.Version?.ToString() ?? "1.0.0",
|
||||||
} :
|
};
|
||||||
options.ServerInfo with
|
|
||||||
{
|
|
||||||
Name = options.ServerInfo.Name ?? assemblyName.Name ?? "McpServer",
|
|
||||||
Version = options.ServerInfo.Version ?? assemblyName.Version?.ToString() ?? "1.0.0",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect all of the provided tools into a tools collection. If the options already has
|
// Collect all of the provided tools into a tools collection. If the options already has
|
||||||
|
|
@ -55,14 +47,9 @@ internal sealed class McpServerOptionsSetup(
|
||||||
|
|
||||||
if (!toolsCollection.IsEmpty)
|
if (!toolsCollection.IsEmpty)
|
||||||
{
|
{
|
||||||
options.Capabilities = options.Capabilities is null ?
|
options.Capabilities ??= new();
|
||||||
new() { Tools = new() { ToolCollection = toolsCollection } } :
|
options.Capabilities.Tools ??= new();
|
||||||
options.Capabilities with
|
options.Capabilities.Tools.ToolCollection = toolsCollection;
|
||||||
{
|
|
||||||
Tools = options.Capabilities.Tools is null ?
|
|
||||||
new() { ToolCollection = toolsCollection } :
|
|
||||||
options.Capabilities.Tools with { ToolCollection = toolsCollection },
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply custom server handlers.
|
// Apply custom server handlers.
|
||||||
|
|
|
||||||
|
|
@ -7,62 +7,62 @@ namespace ModelContextProtocol.Protocol.Types;
|
||||||
/// Represents the capabilities that a client may support.
|
/// Represents the capabilities that a client may support.
|
||||||
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record ClientCapabilities
|
public class ClientCapabilities
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Experimental, non-standard capabilities that the client supports.
|
/// Experimental, non-standard capabilities that the client supports.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("experimental")]
|
[JsonPropertyName("experimental")]
|
||||||
public Dictionary<string, object>? Experimental { get; init; }
|
public Dictionary<string, object>? Experimental { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Present if the client supports listing roots.
|
/// Present if the client supports listing roots.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("roots")]
|
[JsonPropertyName("roots")]
|
||||||
public RootsCapability? Roots { get; init; }
|
public RootsCapability? Roots { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Present if the client supports sampling from an LLM.
|
/// Present if the client supports sampling from an LLM.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("sampling")]
|
[JsonPropertyName("sampling")]
|
||||||
public SamplingCapability? Sampling { get; init; }
|
public SamplingCapability? Sampling { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the roots capability configuration.
|
/// Represents the roots capability configuration.
|
||||||
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record RootsCapability
|
public class RootsCapability
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the client supports notifications for changes to the roots list.
|
/// Whether the client supports notifications for changes to the roots list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("listChanged")]
|
[JsonPropertyName("listChanged")]
|
||||||
public bool? ListChanged { get; init; }
|
public bool? ListChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>Gets or sets the handler for sampling requests.</summary>
|
/// <summary>Gets or sets the handler for sampling requests.</summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<ListRootsRequestParams?, CancellationToken, Task<ListRootsResult>>? RootsHandler { get; init; }
|
public Func<ListRootsRequestParams?, CancellationToken, Task<ListRootsResult>>? RootsHandler { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the sampling capability configuration.
|
/// Represents the sampling capability configuration.
|
||||||
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record SamplingCapability
|
public class SamplingCapability
|
||||||
{
|
{
|
||||||
// Currently empty in the spec, but may be extended in the future
|
// Currently empty in the spec, but may be extended in the future
|
||||||
|
|
||||||
/// <summary>Gets or sets the handler for sampling requests.</summary>
|
/// <summary>Gets or sets the handler for sampling requests.</summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<CreateMessageRequestParams?, CancellationToken, Task<CreateMessageResult>>? SamplingHandler { get; init; }
|
public Func<CreateMessageRequestParams?, CancellationToken, Task<CreateMessageResult>>? SamplingHandler { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the logging capability configuration.
|
/// Represents the logging capability configuration.
|
||||||
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record LoggingCapability
|
public class LoggingCapability
|
||||||
{
|
{
|
||||||
// Currently empty in the spec, but may be extended in the future
|
// Currently empty in the spec, but may be extended in the future
|
||||||
|
|
||||||
|
|
@ -71,106 +71,106 @@ public record LoggingCapability
|
||||||
/// Gets or sets the handler for set logging level requests.
|
/// Gets or sets the handler for set logging level requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<SetLevelRequestParams>, CancellationToken, Task<EmptyResult>>? SetLoggingLevelHandler { get; init; }
|
public Func<RequestContext<SetLevelRequestParams>, CancellationToken, Task<EmptyResult>>? SetLoggingLevelHandler { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the prompts capability configuration.
|
/// Represents the prompts capability configuration.
|
||||||
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record PromptsCapability
|
public class PromptsCapability
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this server supports notifications for changes to the prompt list.
|
/// Whether this server supports notifications for changes to the prompt list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("listChanged")]
|
[JsonPropertyName("listChanged")]
|
||||||
public bool? ListChanged { get; init; }
|
public bool? ListChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for list prompts requests.
|
/// Gets or sets the handler for list prompts requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<ListPromptsRequestParams>, CancellationToken, Task<ListPromptsResult>>? ListPromptsHandler { get; init; }
|
public Func<RequestContext<ListPromptsRequestParams>, CancellationToken, Task<ListPromptsResult>>? ListPromptsHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for get prompt requests.
|
/// Gets or sets the handler for get prompt requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<GetPromptRequestParams>, CancellationToken, Task<GetPromptResult>>? GetPromptHandler { get; init; }
|
public Func<RequestContext<GetPromptRequestParams>, CancellationToken, Task<GetPromptResult>>? GetPromptHandler { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the resources capability configuration.
|
/// Represents the resources capability configuration.
|
||||||
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record ResourcesCapability
|
public class ResourcesCapability
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this server supports subscribing to resource updates.
|
/// Whether this server supports subscribing to resource updates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("subscribe")]
|
[JsonPropertyName("subscribe")]
|
||||||
public bool? Subscribe { get; init; }
|
public bool? Subscribe { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this server supports notifications for changes to the resource list.
|
/// Whether this server supports notifications for changes to the resource list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("listChanged")]
|
[JsonPropertyName("listChanged")]
|
||||||
public bool? ListChanged { get; init; }
|
public bool? ListChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for list resource templates requests.
|
/// Gets or sets the handler for list resource templates requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<ListResourceTemplatesRequestParams>, CancellationToken, Task<ListResourceTemplatesResult>>? ListResourceTemplatesHandler { get; init; }
|
public Func<RequestContext<ListResourceTemplatesRequestParams>, CancellationToken, Task<ListResourceTemplatesResult>>? ListResourceTemplatesHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for list resources requests.
|
/// Gets or sets the handler for list resources requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<ListResourcesRequestParams>, CancellationToken, Task<ListResourcesResult>>? ListResourcesHandler { get; init; }
|
public Func<RequestContext<ListResourcesRequestParams>, CancellationToken, Task<ListResourcesResult>>? ListResourcesHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for read resources requests.
|
/// Gets or sets the handler for read resources requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<ReadResourceRequestParams>, CancellationToken, Task<ReadResourceResult>>? ReadResourceHandler { get; init; }
|
public Func<RequestContext<ReadResourceRequestParams>, CancellationToken, Task<ReadResourceResult>>? ReadResourceHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for subscribe to resources messages.
|
/// Gets or sets the handler for subscribe to resources messages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<SubscribeRequestParams>, CancellationToken, Task<EmptyResult>>? SubscribeToResourcesHandler { get; init; }
|
public Func<RequestContext<SubscribeRequestParams>, CancellationToken, Task<EmptyResult>>? SubscribeToResourcesHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for unsubscribe from resources messages.
|
/// Gets or sets the handler for unsubscribe from resources messages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<UnsubscribeRequestParams>, CancellationToken, Task<EmptyResult>>? UnsubscribeFromResourcesHandler { get; init; }
|
public Func<RequestContext<UnsubscribeRequestParams>, CancellationToken, Task<EmptyResult>>? UnsubscribeFromResourcesHandler { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the tools capability configuration.
|
/// Represents the tools capability configuration.
|
||||||
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record ToolsCapability
|
public class ToolsCapability
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets whether this server supports notifications for changes to the tool list.
|
/// Gets or sets whether this server supports notifications for changes to the tool list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("listChanged")]
|
[JsonPropertyName("listChanged")]
|
||||||
public bool? ListChanged { get; init; }
|
public bool? ListChanged { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for list tools requests.
|
/// Gets or sets the handler for list tools requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<ListToolsRequestParams>, CancellationToken, Task<ListToolsResult>>? ListToolsHandler { get; init; }
|
public Func<RequestContext<ListToolsRequestParams>, CancellationToken, Task<ListToolsResult>>? ListToolsHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the handler for call tool requests.
|
/// Gets or sets the handler for call tool requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Func<RequestContext<CallToolRequestParams>, CancellationToken, Task<CallToolResponse>>? CallToolHandler { get; init; }
|
public Func<RequestContext<CallToolRequestParams>, CancellationToken, Task<CallToolResponse>>? CallToolHandler { get; set; }
|
||||||
|
|
||||||
/// <summary>Gets or sets a collection of tools served by the server.</summary>
|
/// <summary>Gets or sets a collection of tools served by the server.</summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
|
|
@ -182,5 +182,5 @@ public record ToolsCapability
|
||||||
/// will be invoked as a fallback.
|
/// will be invoked as a fallback.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public McpServerToolCollection? ToolCollection { get; init; }
|
public McpServerToolCollection? ToolCollection { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -6,17 +6,17 @@ namespace ModelContextProtocol.Protocol.Types;
|
||||||
/// Describes the name and version of an MCP implementation.
|
/// Describes the name and version of an MCP implementation.
|
||||||
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record Implementation
|
public class Implementation
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Name of the implementation.
|
/// Name of the implementation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("name")]
|
[JsonPropertyName("name")]
|
||||||
public required string Name { get; init; }
|
public required string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version of the implementation.
|
/// Version of the implementation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("version")]
|
[JsonPropertyName("version")]
|
||||||
public required string Version { get; init; }
|
public required string Version { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -6,35 +6,35 @@ namespace ModelContextProtocol.Protocol.Types;
|
||||||
/// Represents the capabilities that a server may support.
|
/// Represents the capabilities that a server may support.
|
||||||
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record ServerCapabilities
|
public class ServerCapabilities
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Experimental, non-standard capabilities that the server supports.
|
/// Experimental, non-standard capabilities that the server supports.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("experimental")]
|
[JsonPropertyName("experimental")]
|
||||||
public Dictionary<string, object>? Experimental { get; init; }
|
public Dictionary<string, object>? Experimental { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Present if the server supports sending log messages to the client.
|
/// Present if the server supports sending log messages to the client.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("logging")]
|
[JsonPropertyName("logging")]
|
||||||
public LoggingCapability? Logging { get; init; }
|
public LoggingCapability? Logging { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Present if the server offers any prompt templates.
|
/// Present if the server offers any prompt templates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("prompts")]
|
[JsonPropertyName("prompts")]
|
||||||
public PromptsCapability? Prompts { get; init; }
|
public PromptsCapability? Prompts { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Present if the server offers any resources to read.
|
/// Present if the server offers any resources to read.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("resources")]
|
[JsonPropertyName("resources")]
|
||||||
public ResourcesCapability? Resources { get; init; }
|
public ResourcesCapability? Resources { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Present if the server offers any tools to call.
|
/// Present if the server offers any tools to call.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonPropertyName("tools")]
|
[JsonPropertyName("tools")]
|
||||||
public ToolsCapability? Tools { get; init; }
|
public ToolsCapability? Tools { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -263,25 +263,14 @@ internal sealed class McpServer : McpJsonRpcEndpoint, IMcpServer
|
||||||
return tool.InvokeAsync(request, cancellationToken);
|
return tool.InvokeAsync(request, cancellationToken);
|
||||||
};
|
};
|
||||||
|
|
||||||
toolsCapability = toolsCapability is null ?
|
toolsCapability ??= new();
|
||||||
new()
|
toolsCapability.CallToolHandler = callToolHandler;
|
||||||
{
|
toolsCapability.ListToolsHandler = listToolsHandler;
|
||||||
CallToolHandler = callToolHandler,
|
toolsCapability.ToolCollection = tools;
|
||||||
ListToolsHandler = listToolsHandler,
|
toolsCapability.ListChanged = true;
|
||||||
ToolCollection = tools,
|
|
||||||
ListChanged = true,
|
|
||||||
} :
|
|
||||||
toolsCapability with
|
|
||||||
{
|
|
||||||
CallToolHandler = callToolHandler,
|
|
||||||
ListToolsHandler = listToolsHandler,
|
|
||||||
ToolCollection = tools,
|
|
||||||
ListChanged = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
options.Capabilities = options.Capabilities is null ?
|
options.Capabilities ??= new();
|
||||||
new() { Tools = toolsCapability } :
|
options.Capabilities.Tools = toolsCapability;
|
||||||
options.Capabilities with { Tools = toolsCapability };
|
|
||||||
|
|
||||||
tools.Changed += delegate
|
tools.Changed += delegate
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -72,91 +72,47 @@ public sealed class McpServerHandlers
|
||||||
PromptsCapability? promptsCapability = options.Capabilities?.Prompts;
|
PromptsCapability? promptsCapability = options.Capabilities?.Prompts;
|
||||||
if (ListPromptsHandler is not null || GetPromptHandler is not null)
|
if (ListPromptsHandler is not null || GetPromptHandler is not null)
|
||||||
{
|
{
|
||||||
promptsCapability = promptsCapability is null ?
|
promptsCapability ??= new();
|
||||||
new()
|
promptsCapability.ListPromptsHandler = ListPromptsHandler ?? promptsCapability.ListPromptsHandler;
|
||||||
{
|
promptsCapability.GetPromptHandler = GetPromptHandler ?? promptsCapability.GetPromptHandler;
|
||||||
ListPromptsHandler = ListPromptsHandler,
|
|
||||||
GetPromptHandler = GetPromptHandler,
|
|
||||||
} :
|
|
||||||
promptsCapability with
|
|
||||||
{
|
|
||||||
ListPromptsHandler = ListPromptsHandler ?? promptsCapability.ListPromptsHandler,
|
|
||||||
GetPromptHandler = GetPromptHandler ?? promptsCapability.GetPromptHandler,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourcesCapability? resourcesCapability = options.Capabilities?.Resources;
|
ResourcesCapability? resourcesCapability = options.Capabilities?.Resources;
|
||||||
if (ListResourcesHandler is not null ||
|
if (ListResourcesHandler is not null ||
|
||||||
ReadResourceHandler is not null)
|
ReadResourceHandler is not null)
|
||||||
{
|
{
|
||||||
resourcesCapability = resourcesCapability is null ?
|
resourcesCapability ??= new();
|
||||||
new()
|
resourcesCapability.ListResourceTemplatesHandler = ListResourceTemplatesHandler ?? resourcesCapability.ListResourceTemplatesHandler;
|
||||||
{
|
resourcesCapability.ListResourcesHandler = ListResourcesHandler ?? resourcesCapability.ListResourcesHandler;
|
||||||
ListResourceTemplatesHandler = ListResourceTemplatesHandler,
|
resourcesCapability.ReadResourceHandler = ReadResourceHandler ?? resourcesCapability.ReadResourceHandler;
|
||||||
ListResourcesHandler = ListResourcesHandler,
|
|
||||||
ReadResourceHandler = ReadResourceHandler
|
|
||||||
} :
|
|
||||||
resourcesCapability with
|
|
||||||
{
|
|
||||||
ListResourceTemplatesHandler = ListResourceTemplatesHandler ?? resourcesCapability.ListResourceTemplatesHandler,
|
|
||||||
ListResourcesHandler = ListResourcesHandler ?? resourcesCapability.ListResourcesHandler,
|
|
||||||
ReadResourceHandler = ReadResourceHandler ?? resourcesCapability.ReadResourceHandler
|
|
||||||
};
|
|
||||||
|
|
||||||
if (SubscribeToResourcesHandler is not null || UnsubscribeFromResourcesHandler is not null)
|
if (SubscribeToResourcesHandler is not null || UnsubscribeFromResourcesHandler is not null)
|
||||||
{
|
{
|
||||||
resourcesCapability = resourcesCapability with
|
resourcesCapability.SubscribeToResourcesHandler = SubscribeToResourcesHandler ?? resourcesCapability.SubscribeToResourcesHandler;
|
||||||
{
|
resourcesCapability.UnsubscribeFromResourcesHandler = UnsubscribeFromResourcesHandler ?? resourcesCapability.UnsubscribeFromResourcesHandler;
|
||||||
SubscribeToResourcesHandler = SubscribeToResourcesHandler ?? resourcesCapability.SubscribeToResourcesHandler,
|
resourcesCapability.Subscribe = true;
|
||||||
UnsubscribeFromResourcesHandler = UnsubscribeFromResourcesHandler ?? resourcesCapability.UnsubscribeFromResourcesHandler,
|
|
||||||
Subscribe = true
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolsCapability? toolsCapability = options.Capabilities?.Tools;
|
ToolsCapability? toolsCapability = options.Capabilities?.Tools;
|
||||||
if (ListToolsHandler is not null || CallToolHandler is not null)
|
if (ListToolsHandler is not null || CallToolHandler is not null)
|
||||||
{
|
{
|
||||||
toolsCapability = toolsCapability is null ?
|
toolsCapability ??= new();
|
||||||
new()
|
toolsCapability.ListToolsHandler = ListToolsHandler ?? toolsCapability.ListToolsHandler;
|
||||||
{
|
toolsCapability.CallToolHandler = CallToolHandler ?? toolsCapability.CallToolHandler;
|
||||||
ListToolsHandler = ListToolsHandler,
|
|
||||||
CallToolHandler = CallToolHandler,
|
|
||||||
} :
|
|
||||||
toolsCapability with
|
|
||||||
{
|
|
||||||
ListToolsHandler = ListToolsHandler ?? toolsCapability.ListToolsHandler,
|
|
||||||
CallToolHandler = CallToolHandler ?? toolsCapability.CallToolHandler,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LoggingCapability? loggingCapability = options.Capabilities?.Logging;
|
LoggingCapability? loggingCapability = options.Capabilities?.Logging;
|
||||||
if (SetLoggingLevelHandler is not null)
|
if (SetLoggingLevelHandler is not null)
|
||||||
{
|
{
|
||||||
loggingCapability = loggingCapability is null ?
|
loggingCapability ??= new();
|
||||||
new()
|
loggingCapability.SetLoggingLevelHandler = SetLoggingLevelHandler;
|
||||||
{
|
|
||||||
SetLoggingLevelHandler = SetLoggingLevelHandler,
|
|
||||||
} :
|
|
||||||
loggingCapability with
|
|
||||||
{
|
|
||||||
SetLoggingLevelHandler = SetLoggingLevelHandler ?? loggingCapability.SetLoggingLevelHandler,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
options.Capabilities = options.Capabilities is null ?
|
options.Capabilities ??= new();
|
||||||
new()
|
options.Capabilities.Prompts = promptsCapability;
|
||||||
{
|
options.Capabilities.Resources = resourcesCapability;
|
||||||
Prompts = promptsCapability,
|
options.Capabilities.Tools = toolsCapability;
|
||||||
Resources = resourcesCapability,
|
|
||||||
Tools = toolsCapability,
|
|
||||||
} :
|
|
||||||
options.Capabilities with
|
|
||||||
{
|
|
||||||
Prompts = promptsCapability,
|
|
||||||
Resources = resourcesCapability,
|
|
||||||
Tools = toolsCapability,
|
|
||||||
};
|
|
||||||
|
|
||||||
options.GetCompletionHandler = GetCompletionHandler ?? options.GetCompletionHandler;
|
options.GetCompletionHandler = GetCompletionHandler ?? options.GetCompletionHandler;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ public class SseServerIntegrationTestFixture : IAsyncDisposable
|
||||||
private readonly DelegatingTestOutputHelper _delegatingTestOutputHelper = new();
|
private readonly DelegatingTestOutputHelper _delegatingTestOutputHelper = new();
|
||||||
private readonly ILoggerFactory _redirectingLoggerFactory;
|
private readonly ILoggerFactory _redirectingLoggerFactory;
|
||||||
|
|
||||||
public McpClientOptions DefaultOptions { get; }
|
|
||||||
public McpServerConfig DefaultConfig { get; }
|
public McpServerConfig DefaultConfig { get; }
|
||||||
|
|
||||||
public SseServerIntegrationTestFixture()
|
public SseServerIntegrationTestFixture()
|
||||||
|
|
@ -26,11 +25,6 @@ public class SseServerIntegrationTestFixture : IAsyncDisposable
|
||||||
builder.AddProvider(new XunitLoggerProvider(_delegatingTestOutputHelper));
|
builder.AddProvider(new XunitLoggerProvider(_delegatingTestOutputHelper));
|
||||||
});
|
});
|
||||||
|
|
||||||
DefaultOptions = new()
|
|
||||||
{
|
|
||||||
ClientInfo = new() { Name = "IntegrationTestClient", Version = "1.0.0" },
|
|
||||||
};
|
|
||||||
|
|
||||||
DefaultConfig = new McpServerConfig
|
DefaultConfig = new McpServerConfig
|
||||||
{
|
{
|
||||||
Id = "test_server",
|
Id = "test_server",
|
||||||
|
|
@ -43,6 +37,11 @@ public class SseServerIntegrationTestFixture : IAsyncDisposable
|
||||||
_serverTask = Program.MainAsync([], _redirectingLoggerFactory, _stopCts.Token);
|
_serverTask = Program.MainAsync([], _redirectingLoggerFactory, _stopCts.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static McpClientOptions CreateDefaultClientOptions() => new()
|
||||||
|
{
|
||||||
|
ClientInfo = new() { Name = "IntegrationTestClient", Version = "1.0.0" },
|
||||||
|
};
|
||||||
|
|
||||||
public void Initialize(ITestOutputHelper output)
|
public void Initialize(ITestOutputHelper output)
|
||||||
{
|
{
|
||||||
_delegatingTestOutputHelper.CurrentTestOutputHelper = output;
|
_delegatingTestOutputHelper.CurrentTestOutputHelper = output;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public class SseServerIntegrationTests : LoggedTest, IClassFixture<SseServerInte
|
||||||
{
|
{
|
||||||
return McpClientFactory.CreateAsync(
|
return McpClientFactory.CreateAsync(
|
||||||
_fixture.DefaultConfig,
|
_fixture.DefaultConfig,
|
||||||
options ?? _fixture.DefaultOptions,
|
options ?? SseServerIntegrationTestFixture.CreateDefaultClientOptions(),
|
||||||
loggerFactory: LoggerFactory);
|
loggerFactory: LoggerFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,28 +201,22 @@ public class SseServerIntegrationTests : LoggedTest, IClassFixture<SseServerInte
|
||||||
// Set up the sampling handler
|
// Set up the sampling handler
|
||||||
int samplingHandlerCalls = 0;
|
int samplingHandlerCalls = 0;
|
||||||
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
|
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||||
var options = _fixture.DefaultOptions with
|
var options = SseServerIntegrationTestFixture.CreateDefaultClientOptions();
|
||||||
|
options.Capabilities ??= new();
|
||||||
|
options.Capabilities.Sampling ??= new();
|
||||||
|
options.Capabilities.Sampling.SamplingHandler = async (_, _) =>
|
||||||
{
|
{
|
||||||
Capabilities = new()
|
samplingHandlerCalls++;
|
||||||
|
return new CreateMessageResult
|
||||||
{
|
{
|
||||||
Sampling = new()
|
Model = "test-model",
|
||||||
|
Role = "assistant",
|
||||||
|
Content = new Content
|
||||||
{
|
{
|
||||||
SamplingHandler = async (_, _) =>
|
Type = "text",
|
||||||
{
|
Text = "Test response"
|
||||||
samplingHandlerCalls++;
|
|
||||||
return new CreateMessageResult
|
|
||||||
{
|
|
||||||
Model = "test-model",
|
|
||||||
Role = "assistant",
|
|
||||||
Content = new Content
|
|
||||||
{
|
|
||||||
Type = "text",
|
|
||||||
Text = "Test response"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
var client = await GetClientAsync(options);
|
var client = await GetClientAsync(options);
|
||||||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
|
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue