Use strong-typing of params in most remaining McpClientExtensions methods (#224)
This commit is contained in:
parent
faf12b6a94
commit
03dc90aa33
6 changed files with 74 additions and 73 deletions
|
|
@ -52,8 +52,8 @@ public static class McpClientExtensions
|
||||||
{
|
{
|
||||||
var toolResults = await client.SendRequestAsync(
|
var toolResults = await client.SendRequestAsync(
|
||||||
RequestMethods.ToolsList,
|
RequestMethods.ToolsList,
|
||||||
CreateCursorDictionary(cursor)!,
|
new() { Cursor = cursor },
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.ListToolsRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.ListToolsResult,
|
McpJsonUtilities.JsonContext.Default.ListToolsResult,
|
||||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
@ -96,8 +96,8 @@ public static class McpClientExtensions
|
||||||
{
|
{
|
||||||
var toolResults = await client.SendRequestAsync(
|
var toolResults = await client.SendRequestAsync(
|
||||||
RequestMethods.ToolsList,
|
RequestMethods.ToolsList,
|
||||||
CreateCursorDictionary(cursor)!,
|
new() { Cursor = cursor },
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.ListToolsRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.ListToolsResult,
|
McpJsonUtilities.JsonContext.Default.ListToolsResult,
|
||||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
@ -128,8 +128,8 @@ public static class McpClientExtensions
|
||||||
{
|
{
|
||||||
var promptResults = await client.SendRequestAsync(
|
var promptResults = await client.SendRequestAsync(
|
||||||
RequestMethods.PromptsList,
|
RequestMethods.PromptsList,
|
||||||
CreateCursorDictionary(cursor)!,
|
new() { Cursor = cursor },
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.ListPromptsRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.ListPromptsResult,
|
McpJsonUtilities.JsonContext.Default.ListPromptsResult,
|
||||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
@ -166,8 +166,8 @@ public static class McpClientExtensions
|
||||||
{
|
{
|
||||||
var promptResults = await client.SendRequestAsync(
|
var promptResults = await client.SendRequestAsync(
|
||||||
RequestMethods.PromptsList,
|
RequestMethods.PromptsList,
|
||||||
CreateCursorDictionary(cursor)!,
|
new() { Cursor = cursor },
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.ListPromptsRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.ListPromptsResult,
|
McpJsonUtilities.JsonContext.Default.ListPromptsResult,
|
||||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
@ -202,12 +202,10 @@ public static class McpClientExtensions
|
||||||
serializerOptions ??= McpJsonUtilities.DefaultOptions;
|
serializerOptions ??= McpJsonUtilities.DefaultOptions;
|
||||||
serializerOptions.MakeReadOnly();
|
serializerOptions.MakeReadOnly();
|
||||||
|
|
||||||
var parametersTypeInfo = serializerOptions.GetTypeInfo<IReadOnlyDictionary<string, object?>>();
|
|
||||||
|
|
||||||
return client.SendRequestAsync(
|
return client.SendRequestAsync(
|
||||||
RequestMethods.PromptsGet,
|
RequestMethods.PromptsGet,
|
||||||
CreateParametersDictionary(name, arguments),
|
new() { Name = name, Arguments = ToArgumentsDictionary(arguments, serializerOptions) },
|
||||||
parametersTypeInfo,
|
McpJsonUtilities.JsonContext.Default.GetPromptRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.GetPromptResult,
|
McpJsonUtilities.JsonContext.Default.GetPromptResult,
|
||||||
cancellationToken: cancellationToken);
|
cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
@ -230,8 +228,8 @@ public static class McpClientExtensions
|
||||||
{
|
{
|
||||||
var templateResults = await client.SendRequestAsync(
|
var templateResults = await client.SendRequestAsync(
|
||||||
RequestMethods.ResourcesTemplatesList,
|
RequestMethods.ResourcesTemplatesList,
|
||||||
CreateCursorDictionary(cursor)!,
|
new() { Cursor = cursor },
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.ListResourceTemplatesRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.ListResourceTemplatesResult,
|
McpJsonUtilities.JsonContext.Default.ListResourceTemplatesResult,
|
||||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
@ -271,8 +269,8 @@ public static class McpClientExtensions
|
||||||
{
|
{
|
||||||
var templateResults = await client.SendRequestAsync(
|
var templateResults = await client.SendRequestAsync(
|
||||||
RequestMethods.ResourcesTemplatesList,
|
RequestMethods.ResourcesTemplatesList,
|
||||||
CreateCursorDictionary(cursor)!,
|
new() { Cursor = cursor },
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.ListResourceTemplatesRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.ListResourceTemplatesResult,
|
McpJsonUtilities.JsonContext.Default.ListResourceTemplatesResult,
|
||||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
@ -304,8 +302,8 @@ public static class McpClientExtensions
|
||||||
{
|
{
|
||||||
var resourceResults = await client.SendRequestAsync(
|
var resourceResults = await client.SendRequestAsync(
|
||||||
RequestMethods.ResourcesList,
|
RequestMethods.ResourcesList,
|
||||||
CreateCursorDictionary(cursor)!,
|
new() { Cursor = cursor },
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.ListResourcesRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.ListResourcesResult,
|
McpJsonUtilities.JsonContext.Default.ListResourcesResult,
|
||||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
@ -345,8 +343,8 @@ public static class McpClientExtensions
|
||||||
{
|
{
|
||||||
var resourceResults = await client.SendRequestAsync(
|
var resourceResults = await client.SendRequestAsync(
|
||||||
RequestMethods.ResourcesList,
|
RequestMethods.ResourcesList,
|
||||||
CreateCursorDictionary(cursor)!,
|
new() { Cursor = cursor },
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.ListResourcesRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.ListResourcesResult,
|
McpJsonUtilities.JsonContext.Default.ListResourcesResult,
|
||||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
@ -374,8 +372,8 @@ public static class McpClientExtensions
|
||||||
|
|
||||||
return client.SendRequestAsync(
|
return client.SendRequestAsync(
|
||||||
RequestMethods.ResourcesRead,
|
RequestMethods.ResourcesRead,
|
||||||
new Dictionary<string, object> { ["uri"] = uri },
|
new() { Uri = uri },
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.ReadResourceRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.ReadResourceResult,
|
McpJsonUtilities.JsonContext.Default.ReadResourceResult,
|
||||||
cancellationToken: cancellationToken);
|
cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
@ -401,12 +399,12 @@ public static class McpClientExtensions
|
||||||
|
|
||||||
return client.SendRequestAsync(
|
return client.SendRequestAsync(
|
||||||
RequestMethods.CompletionComplete,
|
RequestMethods.CompletionComplete,
|
||||||
new Dictionary<string, object>
|
new()
|
||||||
{
|
{
|
||||||
["ref"] = reference,
|
Ref = reference,
|
||||||
["argument"] = new Argument { Name = argumentName, Value = argumentValue }
|
Argument = new Argument { Name = argumentName, Value = argumentValue }
|
||||||
},
|
},
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.CompleteRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.CompleteResult,
|
McpJsonUtilities.JsonContext.Default.CompleteResult,
|
||||||
cancellationToken: cancellationToken);
|
cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
@ -424,8 +422,8 @@ public static class McpClientExtensions
|
||||||
|
|
||||||
return client.SendRequestAsync(
|
return client.SendRequestAsync(
|
||||||
RequestMethods.ResourcesSubscribe,
|
RequestMethods.ResourcesSubscribe,
|
||||||
new Dictionary<string, object> { ["uri"] = uri },
|
new() { Uri = uri },
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.SubscribeRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.EmptyResult,
|
McpJsonUtilities.JsonContext.Default.EmptyResult,
|
||||||
cancellationToken: cancellationToken);
|
cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
@ -443,8 +441,8 @@ public static class McpClientExtensions
|
||||||
|
|
||||||
return client.SendRequestAsync(
|
return client.SendRequestAsync(
|
||||||
RequestMethods.ResourcesUnsubscribe,
|
RequestMethods.ResourcesUnsubscribe,
|
||||||
new Dictionary<string, object> { ["uri"] = uri },
|
new() { Uri = uri },
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.UnsubscribeRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.EmptyResult,
|
McpJsonUtilities.JsonContext.Default.EmptyResult,
|
||||||
cancellationToken: cancellationToken);
|
cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
@ -470,12 +468,10 @@ public static class McpClientExtensions
|
||||||
serializerOptions ??= McpJsonUtilities.DefaultOptions;
|
serializerOptions ??= McpJsonUtilities.DefaultOptions;
|
||||||
serializerOptions.MakeReadOnly();
|
serializerOptions.MakeReadOnly();
|
||||||
|
|
||||||
var parametersTypeInfo = serializerOptions.GetTypeInfo<IReadOnlyDictionary<string, object?>>();
|
|
||||||
|
|
||||||
return client.SendRequestAsync(
|
return client.SendRequestAsync(
|
||||||
RequestMethods.ToolsCall,
|
RequestMethods.ToolsCall,
|
||||||
CreateParametersDictionary(toolName, arguments),
|
new() { Name = toolName, Arguments = ToArgumentsDictionary(arguments, serializerOptions) },
|
||||||
parametersTypeInfo,
|
McpJsonUtilities.JsonContext.Default.CallToolRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.CallToolResponse,
|
McpJsonUtilities.JsonContext.Default.CallToolResponse,
|
||||||
cancellationToken: cancellationToken);
|
cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
@ -629,28 +625,28 @@ public static class McpClientExtensions
|
||||||
|
|
||||||
return client.SendRequestAsync(
|
return client.SendRequestAsync(
|
||||||
RequestMethods.LoggingSetLevel,
|
RequestMethods.LoggingSetLevel,
|
||||||
new Dictionary<string, object> { ["level"] = level },
|
new() { Level = level },
|
||||||
McpJsonUtilities.JsonContext.Default.DictionaryStringObject,
|
McpJsonUtilities.JsonContext.Default.SetLevelRequestParams,
|
||||||
McpJsonUtilities.JsonContext.Default.EmptyResult,
|
McpJsonUtilities.JsonContext.Default.EmptyResult,
|
||||||
cancellationToken: cancellationToken);
|
cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dictionary<string, object?>? CreateCursorDictionary(string? cursor) =>
|
/// <summary>Convers a dictionary with <see cref="object"/> values to a dictionary with <see cref="JsonElement"/> values.</summary>
|
||||||
cursor != null ? new() { ["cursor"] = cursor } : null;
|
private static IReadOnlyDictionary<string, JsonElement>? ToArgumentsDictionary(
|
||||||
|
IReadOnlyDictionary<string, object?>? arguments, JsonSerializerOptions options)
|
||||||
private static Dictionary<string, object?> CreateParametersDictionary(
|
|
||||||
string nameParameter, IReadOnlyDictionary<string, object?>? arguments)
|
|
||||||
{
|
{
|
||||||
Dictionary<string, object?> parameters = new()
|
var typeInfo = options.GetTypeInfo<object?>();
|
||||||
{
|
|
||||||
["name"] = nameParameter
|
|
||||||
};
|
|
||||||
|
|
||||||
if (arguments != null)
|
Dictionary<string, JsonElement>? result = null;
|
||||||
|
if (arguments is not null)
|
||||||
{
|
{
|
||||||
parameters["arguments"] = arguments;
|
result = new(arguments.Count);
|
||||||
|
foreach (var kvp in arguments)
|
||||||
|
{
|
||||||
|
result.Add(kvp.Key, kvp.Value is JsonElement je ? je : JsonSerializer.SerializeToElement(kvp.Value, typeInfo));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return parameters;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace ModelContextProtocol.Protocol.Types;
|
namespace ModelContextProtocol.Protocol.Types;
|
||||||
|
|
||||||
|
|
@ -11,12 +12,12 @@ public class CallToolRequestParams : RequestParams
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tool name.
|
/// Tool name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Text.Json.Serialization.JsonPropertyName("name")]
|
[JsonPropertyName("name")]
|
||||||
public required string Name { get; init; }
|
public required string Name { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Optional arguments to pass to the tool.
|
/// Optional arguments to pass to the tool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Text.Json.Serialization.JsonPropertyName("arguments")]
|
[JsonPropertyName("arguments")]
|
||||||
public Dictionary<string, JsonElement>? Arguments { get; init; }
|
public IReadOnlyDictionary<string, JsonElement>? Arguments { get; init; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
namespace ModelContextProtocol.Protocol.Types;
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace ModelContextProtocol.Protocol.Types;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used by the client to get a prompt provided by the server.
|
/// Used by the client to get a prompt provided by the server.
|
||||||
|
|
@ -9,12 +12,12 @@ public class GetPromptRequestParams : RequestParams
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// he name of the prompt or prompt template.
|
/// he name of the prompt or prompt template.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Text.Json.Serialization.JsonPropertyName("name")]
|
[JsonPropertyName("name")]
|
||||||
public required string Name { get; init; }
|
public required string Name { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Arguments to use for templating the prompt.
|
/// Arguments to use for templating the prompt.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[System.Text.Json.Serialization.JsonPropertyName("arguments")]
|
[JsonPropertyName("arguments")]
|
||||||
public Dictionary<string, object>? Arguments { get; init; }
|
public IReadOnlyDictionary<string, JsonElement>? Arguments { get; init; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using ModelContextProtocol.Protocol.Types;
|
using ModelContextProtocol.Protocol.Types;
|
||||||
using ModelContextProtocol.Utils;
|
using ModelContextProtocol.Utils;
|
||||||
|
using ModelContextProtocol.Utils.Json;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
@ -207,8 +208,8 @@ internal sealed class AIFunctionMcpServerPrompt : McpServerPrompt
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
// TODO: Once we shift to the real AIFunctionFactory, the request should be passed via AIFunctionArguments.Context.
|
// TODO: Once we shift to the real AIFunctionFactory, the request should be passed via AIFunctionArguments.Context.
|
||||||
Dictionary<string, object?> arguments = request.Params?.Arguments is IDictionary<string, object?> existingArgs ?
|
Dictionary<string, object?> arguments = request.Params?.Arguments is { } paramArgs ?
|
||||||
new(existingArgs) :
|
paramArgs.ToDictionary(entry => entry.Key, entry => entry.Value.AsObject()) :
|
||||||
[];
|
[];
|
||||||
arguments[RequestContextKey] = request;
|
arguments[RequestContextKey] = request;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -249,8 +249,8 @@ internal static class Program
|
||||||
}
|
}
|
||||||
else if (request.Params?.Name == "complex_prompt")
|
else if (request.Params?.Name == "complex_prompt")
|
||||||
{
|
{
|
||||||
string temperature = request.Params.Arguments?["temperature"]?.ToString() ?? "unknown";
|
string temperature = request.Params.Arguments?["temperature"].ToString() ?? "unknown";
|
||||||
string style = request.Params.Arguments?["style"]?.ToString() ?? "unknown";
|
string style = request.Params.Arguments?["style"].ToString() ?? "unknown";
|
||||||
messages.Add(new PromptMessage()
|
messages.Add(new PromptMessage()
|
||||||
{
|
{
|
||||||
Role = Role.User,
|
Role = Role.User,
|
||||||
|
|
|
||||||
|
|
@ -328,8 +328,8 @@ public class Program
|
||||||
}
|
}
|
||||||
else if (request.Params.Name == "complex_prompt")
|
else if (request.Params.Name == "complex_prompt")
|
||||||
{
|
{
|
||||||
string temperature = request.Params.Arguments?["temperature"]?.ToString() ?? "unknown";
|
string temperature = request.Params.Arguments?["temperature"].ToString() ?? "unknown";
|
||||||
string style = request.Params.Arguments?["style"]?.ToString() ?? "unknown";
|
string style = request.Params.Arguments?["style"].ToString() ?? "unknown";
|
||||||
messages.Add(new PromptMessage()
|
messages.Add(new PromptMessage()
|
||||||
{
|
{
|
||||||
Role = Role.User,
|
Role = Role.User,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue