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;
}
}
}