using System.ComponentModel; using AwesomeCopilot.McpServer.Models; using AwesomeCopilot.McpServer.Services; using ModelContextProtocol.Server; namespace AwesomeCopilot.McpServer.Tools; /// /// This provides interfaces for metadata tool operations. /// public interface IMetadataTool { /// /// Searches custom instructions based on keywords in their titles and descriptions. /// /// The keyword to search for /// A containing the search results. Task SearchAsync(string keywords); /// /// Loads a custom instruction from the awesome-copilot repository. /// /// The instruction mode /// The filename of the instruction /// The file contents as a string Task LoadAsync(InstructionMode mode, string filename); } /// /// This represents the tools entity for metadata of Awesome Copilot repository. /// [McpServerToolType] public class MetadataTool(IMetadataService service, ILogger logger) : IMetadataTool { /// [McpServerTool(Name = "search_instructions", Title = "Searches custom instructions")] [Description("Searches custom instructions based on keywords in their titles and descriptions.")] public async Task SearchAsync( [Description("The keyword to search for")] string keywords) { var result = new MetadataResult(); try { var metadata = await service.SearchAsync(keywords).ConfigureAwait(false); logger.LogInformation("Search completed successfully with keyword '{Keywords}'.", keywords); result.Metadata = metadata; } catch (Exception ex) { logger.LogError(ex, "Error occurred while searching instructions with keyword '{Keywords}'.", keywords); result.ErrorMessage = ex.Message; } return result; } /// [McpServerTool(Name = "load_instruction", Title = "Loads a custom instruction")] [Description("Loads a custom instruction from the repository.")] public async Task LoadAsync( [Description("The instruction mode")] InstructionMode mode, [Description("The filename of the instruction")] string filename) { try { if (mode == InstructionMode.Undefined) { throw new ArgumentException("Instruction mode must be defined.", nameof(mode)); } var result = await service.LoadAsync(mode.ToString().ToLowerInvariant(), filename).ConfigureAwait(false); logger.LogInformation("Load completed successfully with mode {Mode} and filename {Filename}.", mode, filename); return result; } catch (Exception ex) { logger.LogError(ex, "Error occurred while loading instruction with mode {Mode} and filename {Filename}.", mode, filename); return ex.Message; } } }