|
1 | 1 | using Microsoft.Extensions.AI;
|
| 2 | +using Microsoft.Extensions.DependencyInjection; |
| 3 | +using ModelContextProtocol.Client; |
| 4 | +using ModelContextProtocol.Protocol.Messages; |
2 | 5 | using ModelContextProtocol.Protocol.Types;
|
3 | 6 | using System.Diagnostics.CodeAnalysis;
|
4 | 7 | using System.Reflection;
|
| 8 | +using System.Text.Json; |
5 | 9 |
|
6 | 10 | namespace ModelContextProtocol.Server;
|
7 | 11 |
|
8 |
| -/// <summary>Represents an invocable prompt used by Model Context Protocol servers.</summary> |
| 12 | +/// <summary> |
| 13 | +/// Represents an invocable prompt used by Model Context Protocol clients and servers. |
| 14 | +/// </summary> |
| 15 | +/// <remarks> |
| 16 | +/// <para> |
| 17 | +/// <see cref="McpServerPrompt"/> is an abstract base class that represents an MCP prompt for use in the server (as opposed |
| 18 | +/// to <see cref="Prompt"/>, which provides the protocol representation of a prompt, and <see cref="McpClientPrompt"/>, which |
| 19 | +/// provides a client-side representation of a prompt). Instances of <see cref="McpServerPrompt"/> can be added into a |
| 20 | +/// <see cref="IServiceCollection"/> to be picked up automatically when <see cref="McpServerFactory"/> is used to create |
| 21 | +/// an <see cref="IMcpServer"/>, or added into a <see cref="McpServerPrimitiveCollection{McpServerPrompt}"/>. |
| 22 | +/// </para> |
| 23 | +/// <para> |
| 24 | +/// Most commonly, <see cref="McpServerPrompt"/> instances are created using the static <see cref="M:McpServerPrompt.Create"/> methods. |
| 25 | +/// These methods enable creating an <see cref="McpServerPrompt"/> for a method, specified via a <see cref="Delegate"/> or |
| 26 | +/// <see cref="MethodInfo"/>, and are what are used implicitly by <see cref="McpServerBuilderExtensions.WithPromptsFromAssembly"/> and |
| 27 | +/// <see cref="M:McpServerBuilderExtensions.WithPrompts"/>. The <see cref="M:McpServerPrompt.Create"/> methods |
| 28 | +/// create <see cref="McpServerPrompt"/> instances capable of working with a large variety of .NET method signatures, automatically handling |
| 29 | +/// how parameters are marshaled into the method from the JSON received from the MCP client, and how the return value is marshaled back |
| 30 | +/// into the <see cref="GetPromptResult"/> that's then serialized and sent back to the client. |
| 31 | +/// </para> |
| 32 | +/// <para> |
| 33 | +/// By default, parameters are sourced from the <see cref="GetPromptRequestParams.Arguments"/> dictionary, which is a collection |
| 34 | +/// of key/value pairs. Those parameters are deserialized from the |
| 35 | +/// <see cref="JsonElement"/> values in that collection. There are a few exceptions to this: |
| 36 | +/// <list type="bullet"> |
| 37 | +/// <item> |
| 38 | +/// <description> |
| 39 | +/// <see cref="CancellationToken"/> parameters are automatically bound to a <see cref="CancellationToken"/> provided by the |
| 40 | +/// <see cref="IMcpServer"/> and that respects any <see cref="CancelledNotification"/>s sent by the client for this operation's |
| 41 | +/// <see cref="RequestId"/>. |
| 42 | +/// </description> |
| 43 | +/// </item> |
| 44 | +/// <item> |
| 45 | +/// <description> |
| 46 | +/// <see cref="IServiceProvider"/> parameters are bound from the <see cref="RequestContext{GetPromptRequestParams}"/> for this request. |
| 47 | +/// </description> |
| 48 | +/// </item> |
| 49 | +/// <item> |
| 50 | +/// <description> |
| 51 | +/// <see cref="IMcpServer"/> parameters are bound directly to the <see cref="IMcpServer"/> instance associated |
| 52 | +/// with this request's <see cref="RequestContext{CallPromptRequestParams}"/>. Such parameters may be used to understand |
| 53 | +/// what server is being used to process the request, and to interact with the client issuing the request to that server. |
| 54 | +/// </description> |
| 55 | +/// </item> |
| 56 | +/// <item> |
| 57 | +/// <description> |
| 58 | +/// <see cref="IProgress{ProgressNotificationValue}"/> parameters accepting <see cref="ProgressNotificationValue"/> values |
| 59 | +/// are bound to an <see cref="IProgress{ProgressNotificationValue}"/> instance manufactured to forward progress notifications |
| 60 | +/// from the prompt to the client. If the client included a <see cref="ProgressToken"/> in their request, progress reports issued |
| 61 | +/// to this instance will propagate to the client as <see cref="NotificationMethods.ProgressNotification"/> notifications with |
| 62 | +/// that token. If the client did not include a <see cref="ProgressToken"/>, the instance will ignore any progress reports issued to it. |
| 63 | +/// </description> |
| 64 | +/// </item> |
| 65 | +/// <item> |
| 66 | +/// <description> |
| 67 | +/// When the <see cref="McpServerPrompt"/> is constructed, it may be passed an <see cref="IServiceProvider"/> via |
| 68 | +/// <see cref="McpServerPromptCreateOptions.Services"/>. Any parameter that can be satisfied by that <see cref="IServiceProvider"/> |
| 69 | +/// according to <see cref="IServiceProviderIsService"/> will be resolved from the <see cref="IServiceProvider"/> provided to |
| 70 | +/// <see cref="GetAsync"/> rather than from the argument collection. |
| 71 | +/// </description> |
| 72 | +/// </item> |
| 73 | +/// <item> |
| 74 | +/// <description> |
| 75 | +/// Any parameter attributed with <see cref="FromKeyedServicesAttribute"/> will similarly be resolved from the |
| 76 | +/// <see cref="IServiceProvider"/> provided to <see cref="GetAsync"/> rather than from the argument collection. |
| 77 | +/// </description> |
| 78 | +/// </item> |
| 79 | +/// </list> |
| 80 | +/// </para> |
| 81 | +/// <para> |
| 82 | +/// All other parameters are deserialized from the <see cref="JsonElement"/>s in the <see cref="GetPromptRequestParams.Arguments"/> dictionary. |
| 83 | +/// </para> |
| 84 | +/// <para> |
| 85 | +/// In general, the data supplied via the <see cref="GetPromptRequestParams.Arguments"/>'s dictionary is passed along from the caller and |
| 86 | +/// should thus be considered unvalidated and untrusted. To provide validated and trusted data to the invocation of the prompt, consider having |
| 87 | +/// the prompt be an instance method, referring to data stored in the instance, or using an instance or parameters resolved from the <see cref="IServiceProvider"/> |
| 88 | +/// to provide data to the method. |
| 89 | +/// </para> |
| 90 | +/// <para> |
| 91 | +/// Return values from a method are used to create the <see cref="GetPromptResult"/> that is sent back to the client: |
| 92 | +/// </para> |
| 93 | +/// <list type="table"> |
| 94 | +/// <item> |
| 95 | +/// <term><see cref="string"/></term> |
| 96 | +/// <description>Converted to a list containing a single <see cref="PromptMessage"/> with its <see cref="PromptMessage.Content"/> set to contain the <see cref="string"/>.</description> |
| 97 | +/// </item> |
| 98 | +/// <item> |
| 99 | +/// <term><see cref="PromptMessage"/></term> |
| 100 | +/// <description>Converted to a list containing the single <see cref="PromptMessage"/>.</description> |
| 101 | +/// </item> |
| 102 | +/// <item> |
| 103 | +/// <term><see cref="IEnumerable{PromptMessage}"/> of <see cref="PromptMessage"/></term> |
| 104 | +/// <description>Converted to a list containing all of the returned <see cref="PromptMessage"/> instances.</description> |
| 105 | +/// </item> |
| 106 | +/// <item> |
| 107 | +/// <term><see cref="ChatMessage"/></term> |
| 108 | +/// <description>Converted to a list of <see cref="PromptMessage"/> instances derived from the <see cref="ChatMessage"/> with <see cref="AIContentExtensions.ToPromptMessages"/>.</description> |
| 109 | +/// </item> |
| 110 | +/// <item> |
| 111 | +/// <term><see cref="IEnumerable{PromptMessage}"/> of <see cref="PromptMessage"/></term> |
| 112 | +/// <description>Converted to a list of <see cref="PromptMessage"/> instances derived from all of the <see cref="ChatMessage"/> instances with <see cref="AIContentExtensions.ToPromptMessages"/>.</description> |
| 113 | +/// </item> |
| 114 | +/// </list> |
| 115 | +/// <para> |
| 116 | +/// Other returned types will result in an <see cref="InvalidOperationException"/> being thrown. |
| 117 | +/// </para> |
| 118 | +/// </remarks> |
9 | 119 | public abstract class McpServerPrompt : IMcpServerPrimitive
|
10 | 120 | {
|
11 | 121 | /// <summary>Initializes a new instance of the <see cref="McpServerPrompt"/> class.</summary>
|
|
0 commit comments