using Microsoft.Extensions.AI; using Microsoft.Extensions.DependencyInjection; using ModelContextProtocol.Client; using ModelContextProtocol.Protocol; using System.Reflection; using System.Text.Json; namespace ModelContextProtocol.Server; /// /// Represents an invocable tool used by Model Context Protocol clients and servers. /// /// /// /// is an abstract base class that represents an MCP tool for use in the server (as opposed /// to , which provides the protocol representation of a tool, and , which /// provides a client-side representation of a tool). Instances of can be added into a /// to be picked up automatically when is used to create /// an , or added into a . /// /// /// Most commonly, instances are created using the static methods. /// These methods enable creating an for a method, specified via a or /// , and are what are used implicitly by WithToolsFromAssembly and WithTools. The methods /// create instances capable of working with a large variety of .NET method signatures, automatically handling /// how parameters are marshaled into the method from the JSON received from the MCP client, and how the return value is marshaled back /// into the that's then serialized and sent back to the client. /// /// /// By default, parameters are sourced from the dictionary, which is a collection /// of key/value pairs, and are represented in the JSON schema for the function, as exposed in the returned 's /// 's . Those parameters are deserialized from the /// values in that collection. There are a few exceptions to this: /// /// /// /// parameters are automatically bound to a provided by the /// and that respects any s sent by the client for this operation's /// . The parameter is not included in the generated JSON schema. /// /// /// /// /// parameters are bound from the for this request, /// and are not included in the JSON schema. /// /// /// /// /// parameters are not included in the JSON schema and are bound directly to the /// instance associated with this request's . Such parameters may be used to understand /// what server is being used to process the request, and to interact with the client issuing the request to that server. /// /// /// /// /// parameters accepting values /// are not included in the JSON schema and are bound to an instance manufactured /// to forward progress notifications from the tool to the client. If the client included a in their request, /// progress reports issued to this instance will propagate to the client as notifications with /// that token. If the client did not include a , the instance will ignore any progress reports issued to it. /// /// /// /// /// When the is constructed, it may be passed an via /// . Any parameter that can be satisfied by that /// according to will not be included in the generated JSON schema and will be resolved /// from the provided to rather than from the argument collection. /// /// /// /// /// Any parameter attributed with will similarly be resolved from the /// provided to rather than from the argument /// collection, and will not be included in the generated JSON schema. /// /// /// /// /// /// All other parameters are deserialized from the s in the dictionary, /// using the supplied in , or if none was provided, /// using . /// /// /// In general, the data supplied via the 's dictionary is passed along from the caller and /// should thus be considered unvalidated and untrusted. To provide validated and trusted data to the invocation of the tool, consider having /// the tool be an instance method, referring to data stored in the instance, or using an instance or parameters resolved from the /// to provide data to the method. /// /// /// The tool method is responsible for validating its own input arguments (e.g., checking required fields, value ranges, string lengths, or /// any other business rules). Data annotations such as RequiredAttribute and /// MaxLengthAttribute on parameter types influence the generated JSON schema exposed /// to clients, but they are not enforced at runtime by the SDK. Validation should be performed explicitly within the tool method. /// /// /// To signal an error (including validation failures) back to the client, either throw an /// or return a with set to . /// When a tool throws an , its is included in the error result /// sent to the client. Throwing any other exception type also results in an error , but with /// a generic error message (to avoid leaking sensitive information). Alternatively, a tool can declare a return type of /// to have full control over both success and error responses. /// /// /// It is important to provide clear values on tool methods and their parameters. /// These descriptions are surfaced to AI models and help them determine when and how to use the tool, what values to pass for each parameter, /// and what constraints the parameters have. Well-written descriptions reduce incorrect tool invocations and improve the quality of /// model interactions. /// /// /// Return values from a method are used to create the that is sent back to the client: /// /// /// /// /// Returns an empty list. /// /// /// /// Converted to a single object using . /// /// /// /// Converted to a single object with its text set to the string value. /// /// /// /// Returned as a single-item list. /// /// /// of /// Each is converted to a object using . /// /// /// of /// Returned as the list. /// /// /// /// Returned directly without modification. /// /// /// Other types /// Serialized to JSON and returned as a single object with set to "text". /// /// /// public abstract class McpServerTool : IMcpServerPrimitive { /// Initializes a new instance of the class. protected McpServerTool() { } /// Gets the protocol type for this instance. public abstract Tool ProtocolTool { get; } /// /// Gets the metadata for this tool instance. /// /// /// Contains attributes from the associated MethodInfo and declaring class (if any), /// with class-level attributes appearing before method-level attributes. /// public abstract IReadOnlyList Metadata { get; } /// Invokes the . /// The request information resulting in the invocation of this tool. /// The to monitor for cancellation requests. The default is . /// The call response from invoking the tool. /// is . public abstract ValueTask InvokeAsync( RequestContext request, CancellationToken cancellationToken = default); /// /// Creates an instance for a method, specified via a instance. /// /// The method to be represented via the created . /// Optional options used in the creation of the to control its behavior. /// The created for invoking . /// is . public static McpServerTool Create( Delegate method, McpServerToolCreateOptions? options = null) => AIFunctionMcpServerTool.Create(method, options); /// /// Creates an instance for a method, specified via a instance. /// /// The method to be represented via the created . /// The instance if is an instance method; otherwise, . /// Optional options used in the creation of the to control its behavior. /// The created for invoking . /// is . /// is an instance method but is . public static McpServerTool Create( MethodInfo method, object? target = null, McpServerToolCreateOptions? options = null) => AIFunctionMcpServerTool.Create(method, target, options); /// /// Creates an instance for a method, specified via a for /// an instance method, along with a representing the type of the target object to /// instantiate each time the method is invoked. /// /// The instance method to be represented via the created . /// /// Callback used on each function invocation to create an instance of the type on which the instance method /// will be invoked. If the returned instance is or , it will /// be disposed of after method completes its invocation. /// /// Optional options used in the creation of the to control its behavior. /// The created for invoking . /// or is . public static McpServerTool Create( MethodInfo method, Func, object> createTargetFunc, McpServerToolCreateOptions? options = null) => AIFunctionMcpServerTool.Create(method, createTargetFunc, options); /// Creates an that wraps the specified . /// The function to wrap. /// Optional options used in the creation of the to control its behavior. /// is . /// /// Unlike the other overloads of Create, the created by /// does not provide all of the special parameter handling for MCP-specific concepts, like . /// public static McpServerTool Create( AIFunction function, McpServerToolCreateOptions? options = null) => AIFunctionMcpServerTool.Create(function, options); /// public override string ToString() => ProtocolTool.Name; /// string IMcpServerPrimitive.Id => ProtocolTool.Name; }