using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using ModelContextProtocol.Protocol;
using System.Reflection;
namespace ModelContextProtocol.Server;
///
/// Represents an invocable resource used by Model Context Protocol clients and servers.
///
///
///
/// is an abstract base class that represents an MCP resource for use in the server (as opposed
/// to or , which provide the protocol representations of a resource). 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 WithResourcesFromAssembly and
/// . 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 URI 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.
///
///
/// is used to represent both direct resources (e.g. "resource://example") and templated
/// resources (e.g. "resource://example/{id}").
///
///
/// Read resource requests do not contain separate arguments, only a URI. However, for templated resources, portions of that URI may be considered
/// as arguments and may be bound to parameters. Further, resource methods may accept parameters that will be bound to arguments based on their type.
///
/// -
///
/// parameters are automatically bound to a provided by the
/// and that respects any s sent by the client for this operation's
/// .
///
///
/// -
///
/// parameters are bound from the for this request.
///
///
/// -
///
/// parameters 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 bound to an instance manufactured to forward progress notifications
/// from the resource 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 be resolved from the provided to the
/// resource invocation rather than from the argument collection.
///
///
/// -
///
/// Any parameter attributed with will similarly be resolved from the
/// provided to the resource invocation rather than from the argument collection.
///
///
/// -
///
/// All other parameters are bound from the data in the URI.
///
///
///
///
///
/// Return values from a method are used to create the that is sent back to the client:
///
///
/// -
///
/// Wrapped in a list containing the single .
///
/// -
///
/// Converted to a list containing a single .
///
/// -
///
/// Converted to a list containing a single .
///
/// -
///
/// Converted to a list containing a single .
///
/// -
/// of
/// Returned directly as a list of .
///
/// -
/// of
/// Converted to a list containing a for each and a for each .
///
/// -
/// of
/// Converted to a list containing a , one for each .
///
///
///
/// Other returned types will result in an being thrown.
///
///
public abstract class McpServerResource : IMcpServerPrimitive
{
/// Initializes a new instance of the class.
protected McpServerResource()
{
}
/// Gets whether this resource is a URI template with parameters as opposed to a direct resource.
public bool IsTemplated => ProtocolResourceTemplate.UriTemplate.Contains('{');
/// Gets the protocol type for this instance.
///
///
/// The property represents the underlying resource template definition as defined in the
/// Model Context Protocol specification. It contains metadata like the resource templates's URI template, name, and description.
///
///
/// Every valid resource URI is a valid resource URI template, and thus this property always returns an instance.
/// In contrast, the property may return if the resource template
/// contains a parameter, in which case the resource template URI is not a valid resource URI.
///
///
public abstract ResourceTemplate ProtocolResourceTemplate { get; }
/// Gets the protocol type for this instance.
///
/// The ProtocolResourceTemplate property represents the underlying resource template definition as defined in the
/// Model Context Protocol specification. It contains metadata like the resource templates's URI template, name, and description.
///
public virtual Resource? ProtocolResource => ProtocolResourceTemplate.AsResource();
///
/// Gets the resource, rendering it with the provided request parameters and returning the resource result.
///
///
/// The request context containing information about the resource invocation, including any arguments
/// passed to the resource. This object provides access to both the request parameters and the server context.
///
///
/// The to monitor for cancellation requests. The default is .
///
///
/// A representing the asynchronous operation, containing a with
/// the resource content and messages. If and only if this doesn't match the ,
/// the method returns .
///
/// is .
/// The resource implementation returned or an unsupported result type.
public abstract ValueTask ReadAsync(
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 McpServerResource Create(
Delegate method,
McpServerResourceCreateOptions? options = null) =>
AIFunctionMcpServerResource.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 McpServerResource Create(
MethodInfo method,
object? target = null,
McpServerResourceCreateOptions? options = null) =>
AIFunctionMcpServerResource.Create(method, target, options);
///
/// Creates an instance for a method, specified via an for
/// and 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 .
/// is .
public static McpServerResource Create(
MethodInfo method,
Func, object> createTargetFunc,
McpServerResourceCreateOptions? options = null) =>
AIFunctionMcpServerResource.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 McpServerResource Create(
AIFunction function,
McpServerResourceCreateOptions? options = null) =>
AIFunctionMcpServerResource.Create(function, options);
///
public override string ToString() => ProtocolResourceTemplate.UriTemplate;
///
string IMcpServerPrimitive.Id => ProtocolResourceTemplate.UriTemplate;
}