using ModelContextProtocol.Server; using Microsoft.Extensions.Options; using ModelContextProtocol.Utils; namespace Microsoft.Extensions.DependencyInjection; /// /// Configures the McpServerOptions using addition services from DI. /// /// The server handlers configuration options. /// Tools individually registered. /// Prompts individually registered. /// Resources individually registered. internal sealed class McpServerOptionsSetup( IOptions serverHandlers, IEnumerable serverTools, IEnumerable serverPrompts, IEnumerable serverResources) : IConfigureOptions { /// /// Configures the given McpServerOptions instance by setting server information /// and applying custom server handlers and tools. /// /// The options instance to be configured. public void Configure(McpServerOptions options) { Throw.IfNull(options); // Collect all of the provided tools into a tools collection. If the options already has // a collection, add to it, otherwise create a new one. We want to maintain the identity // of an existing collection in case someone has provided their own derived type, wants // change notifications, etc. McpServerPrimitiveCollection toolCollection = options.Capabilities?.Tools?.ToolCollection ?? []; foreach (var tool in serverTools) { toolCollection.TryAdd(tool); } if (!toolCollection.IsEmpty) { options.Capabilities ??= new(); options.Capabilities.Tools ??= new(); options.Capabilities.Tools.ToolCollection = toolCollection; } // Collect all of the provided prompts into a prompts collection. If the options already has // a collection, add to it, otherwise create a new one. We want to maintain the identity // of an existing collection in case someone has provided their own derived type, wants // change notifications, etc. McpServerPrimitiveCollection promptCollection = options.Capabilities?.Prompts?.PromptCollection ?? []; foreach (var prompt in serverPrompts) { promptCollection.TryAdd(prompt); } if (!promptCollection.IsEmpty) { options.Capabilities ??= new(); options.Capabilities.Prompts ??= new(); options.Capabilities.Prompts.PromptCollection = promptCollection; } // Collect all of the provided resources into a resources collection. If the options already has // a collection, add to it, otherwise create a new one. We want to maintain the identity // of an existing collection in case someone has provided their own derived type, wants // change notifications, etc. McpServerPrimitiveCollection resourceCollection = options.Capabilities?.Resources?.ResourceCollection ?? []; foreach (var resource in serverResources) { resourceCollection.TryAdd(resource); } if (!resourceCollection.IsEmpty) { options.Capabilities ??= new(); options.Capabilities.Resources ??= new(); options.Capabilities.Resources.ResourceCollection = resourceCollection; } // Apply custom server handlers. serverHandlers.Value.OverwriteWithSetHandlers(options); } }