Use DescriptionAttribute and HasDefaultValue in server builder extensions (#46)
This commit is contained in:
parent
e187ebacc4
commit
33d2b0d762
6 changed files with 27 additions and 61 deletions
|
|
@ -1,12 +1,13 @@
|
|||
using McpDotNet.Server;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace TestServerWithHosting.Tools;
|
||||
|
||||
[McpToolType]
|
||||
public static class EchoTool
|
||||
{
|
||||
[McpTool(description: "Echoes the input back to the client.")]
|
||||
public static string Echo([McpParameter(true)] string message)
|
||||
[McpTool, Description("Echoes the input back to the client.")]
|
||||
public static string Echo(string message)
|
||||
{
|
||||
return "hello " + message;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using McpDotNet.Protocol.Types;
|
||||
using McpDotNet.Server;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace TestServerWithHosting.Tools;
|
||||
|
||||
|
|
@ -16,10 +17,10 @@ public class SampleLlmTool
|
|||
_server = server ?? throw new ArgumentNullException(nameof(server));
|
||||
}
|
||||
|
||||
[McpTool(name: "sampleLLM", description: "Samples from an LLM using MCP's sampling feature")]
|
||||
[McpTool("sampleLLM"), Description("Samples from an LLM using MCP's sampling feature")]
|
||||
public async Task<string> SampleLLM(
|
||||
[McpParameter(true, description: "The prompt to send to the LLM")] string prompt,
|
||||
[McpParameter(true, description: "Maximum number of tokens to generate")] int maxTokens,
|
||||
[Description("The prompt to send to the LLM")] string prompt,
|
||||
[Description("Maximum number of tokens to generate")] int maxTokens,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var samplingParams = CreateRequestSamplingParams(prompt ?? string.Empty, "sampleLLM", maxTokens);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Globalization;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using McpDotNet.Configuration;
|
||||
|
|
@ -117,7 +118,7 @@ public static partial class McpServerBuilderExtensions
|
|||
return WithTools(builder, toolTypes.ToArray());
|
||||
}
|
||||
|
||||
private static Tool CreateTool(MethodInfo method, McpToolAttribute attribute)
|
||||
private static Tool CreateTool(MethodInfo method, McpToolAttribute mcpAttribute)
|
||||
{
|
||||
Dictionary<string, JsonSchemaProperty> properties = [];
|
||||
List<string>? requiredProperties = null;
|
||||
|
|
@ -127,15 +128,15 @@ public static partial class McpServerBuilderExtensions
|
|||
if (parameter.ParameterType == typeof(CancellationToken))
|
||||
continue;
|
||||
|
||||
var parameterAttribute = parameter.GetCustomAttribute<McpParameterAttribute>();
|
||||
var parameterDescriptionAttr = parameter.GetCustomAttribute<DescriptionAttribute>();
|
||||
|
||||
properties.Add(parameter.Name ?? "NoName", new JsonSchemaProperty()
|
||||
{
|
||||
Type = GetParameterType(parameter.ParameterType),
|
||||
Description = parameterAttribute?.Description
|
||||
Description = parameterDescriptionAttr?.Description,
|
||||
});
|
||||
|
||||
if (parameterAttribute?.Required == true)
|
||||
if (!parameter.HasDefaultValue)
|
||||
{
|
||||
requiredProperties ??= [];
|
||||
requiredProperties.Add(parameter.Name ?? "NoName");
|
||||
|
|
@ -144,8 +145,8 @@ public static partial class McpServerBuilderExtensions
|
|||
|
||||
return new Tool()
|
||||
{
|
||||
Name = attribute.Name ?? method.Name,
|
||||
Description = attribute.Description,
|
||||
Name = mcpAttribute.Name ?? method.Name,
|
||||
Description = method.GetCustomAttribute<DescriptionAttribute>()?.Description,
|
||||
InputSchema = new JsonSchema()
|
||||
{
|
||||
Type = "object",
|
||||
|
|
@ -229,12 +230,10 @@ public static partial class McpServerBuilderExtensions
|
|||
}
|
||||
else
|
||||
{
|
||||
var parameterAttribute = parameter.GetCustomAttribute<McpParameterAttribute>();
|
||||
|
||||
if (parameterAttribute?.Required == true)
|
||||
if (!parameter.HasDefaultValue)
|
||||
throw new McpServerException($"Missing required argument '{parameter.Name}'.");
|
||||
|
||||
parameters.Add(parameter.HasDefaultValue ? parameter.DefaultValue : null);
|
||||
parameters.Add(parameter.DefaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
namespace McpDotNet.Server;
|
||||
|
||||
/// <summary>
|
||||
/// Attribute to mark a method parameter
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
public sealed class McpParameterAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines if the parameter is required.
|
||||
/// </summary>
|
||||
public bool Required { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A description of the parameter.
|
||||
/// </summary>
|
||||
public string? Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute to mark a method as an MCP tool.
|
||||
/// </summary>
|
||||
/// <param name="required">True if the parameter is mandatory.</param>
|
||||
/// <param name="description">A description of the tool.</param>
|
||||
public McpParameterAttribute(bool required = false, string? description = null)
|
||||
{
|
||||
Required = required;
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,22 +6,15 @@
|
|||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class McpToolAttribute : Attribute
|
||||
{
|
||||
/// The name of the tool. If not provided, the class name will be used.
|
||||
/// <summary>Gets the name of the tool.</summary>
|
||||
/// <remarks>If not provided, the method name will be used.</remarks>
|
||||
public string? Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A description of the tool.
|
||||
/// </summary>
|
||||
public string? Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute to mark a method as an MCP tool.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the tool. If not provided, the class name will be used.</param>
|
||||
/// <param name="description">A description of the tool.</param>
|
||||
public McpToolAttribute(string? name = null, string? description = null)
|
||||
public McpToolAttribute(string? name = null)
|
||||
{
|
||||
Name = name;
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using McpDotNet.Server;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace McpDotNet.Tests;
|
||||
|
||||
|
|
@ -131,14 +132,14 @@ public class McpServerBuilderExtensionsToolsTests
|
|||
|
||||
private static class EchoTool
|
||||
{
|
||||
[McpTool(description: "Echoes the input back to the client.")]
|
||||
public static string Echo([McpParameter(true, description: "the echoes message")] string message)
|
||||
[McpTool, Description("Echoes the input back to the client.")]
|
||||
public static string Echo([Description("the echoes message")] string message)
|
||||
{
|
||||
return "hello " + message;
|
||||
}
|
||||
|
||||
[McpTool(name: "double_echo", description: "Echoes the input back to the client.")]
|
||||
public static string Echo2([McpParameter(true)] string message)
|
||||
[McpTool("double_echo"), Description("Echoes the input back to the client.")]
|
||||
public static string Echo2(string message)
|
||||
{
|
||||
return "hello hello" + message;
|
||||
}
|
||||
|
|
@ -154,8 +155,8 @@ public class McpServerBuilderExtensionsToolsTests
|
|||
{
|
||||
}
|
||||
|
||||
[McpTool(description: "Echoes the input back to the client.")]
|
||||
public Task<string> Echo([McpParameter(true)] string message)
|
||||
[McpTool, Description("Echoes the input back to the client.")]
|
||||
public Task<string> Echo(string message)
|
||||
{
|
||||
return Task.FromResult("hello " + message);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue