Add 3-arg RequestContext constructor and obsolete 2-arg to eliminate null-forgiving operator usage (#1462)
This commit is contained in:
parent
afc40d1e2e
commit
7dcdbafe9d
33 changed files with 190 additions and 219 deletions
|
|
@ -317,7 +317,7 @@ Execution flow: `filter1 -> filter2 -> filter3 -> baseHandler -> filter3 -> filt
|
|||
{
|
||||
var logger = context.Services?.GetService<ILogger<Program>>();
|
||||
|
||||
logger?.LogInformation($"Processing request from {context.Params?.ProgressToken}");
|
||||
logger?.LogInformation($"Processing request from {context.Params.ProgressToken}");
|
||||
var result = await next(context, cancellationToken);
|
||||
logger?.LogInformation($"Returning {result.Tools?.Count ?? 0} tools");
|
||||
return result;
|
||||
|
|
@ -339,7 +339,7 @@ Execution flow: `filter1 -> filter2 -> filter3 -> baseHandler -> filter3 -> filt
|
|||
catch (Exception ex)
|
||||
{
|
||||
var logger = context.Services?.GetService<ILogger<Program>>();
|
||||
logger?.LogError(ex, "Error while processing CallTool request for {ProgressToken}", context.Params?.ProgressToken);
|
||||
logger?.LogError(ex, "Error while processing CallTool request for {ProgressToken}", context.Params.ProgressToken);
|
||||
|
||||
return new CallToolResult
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ public class LoggingTools
|
|||
int duration = 10,
|
||||
int steps = 10)
|
||||
{
|
||||
var progressToken = context.Params?.ProgressToken;
|
||||
var progressToken = context.Params.ProgressToken;
|
||||
var stepDuration = duration / steps;
|
||||
|
||||
// <snippet_LoggingConfiguration >
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ builder.Services.AddMcpServer()
|
|||
int startIndex = 0;
|
||||
|
||||
// Parse cursor to determine starting position
|
||||
if (ctx.Params?.Cursor is { } cursor)
|
||||
if (ctx.Params.Cursor is { } cursor)
|
||||
{
|
||||
startIndex = int.Parse(cursor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public class LongRunningTools
|
|||
int duration = 10,
|
||||
int steps = 5)
|
||||
{
|
||||
var progressToken = context.Params?.ProgressToken;
|
||||
var progressToken = context.Params.ProgressToken;
|
||||
var stepDuration = duration / steps;
|
||||
|
||||
for (int i = 1; i <= steps; i++)
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ builder.Services.AddMcpServer()
|
|||
.WithResources<MyResources>()
|
||||
.WithSubscribeToResourcesHandler(async (ctx, ct) =>
|
||||
{
|
||||
if (ctx.Params?.Uri is { } uri)
|
||||
if (ctx.Params.Uri is { } uri)
|
||||
{
|
||||
// Track the subscription (e.g., in a concurrent dictionary)
|
||||
subscriptions[ctx.Server.SessionId].TryAdd(uri, 0);
|
||||
|
|
@ -221,7 +221,7 @@ builder.Services.AddMcpServer()
|
|||
})
|
||||
.WithUnsubscribeFromResourcesHandler(async (ctx, ct) =>
|
||||
{
|
||||
if (ctx.Params?.Uri is { } uri)
|
||||
if (ctx.Params.Uri is { } uri)
|
||||
{
|
||||
subscriptions[ctx.Server.SessionId].TryRemove(uri, out _);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,3 +36,4 @@ When APIs are marked as obsolete, a diagnostic is emitted to warn users that the
|
|||
| :------------ | :----- | :---------- |
|
||||
| `MCP9001` | In place | The `EnumSchema` and `LegacyTitledEnumSchema` APIs are deprecated as of specification version 2025-11-25. Use the current schema APIs instead. |
|
||||
| `MCP9002` | Removed | The `AddXxxFilter` extension methods on `IMcpServerBuilder` (e.g., `AddListToolsFilter`, `AddCallToolFilter`, `AddIncomingMessageFilter`) were superseded by `WithRequestFilters()` and `WithMessageFilters()`. |
|
||||
| `MCP9003` | In place | The `RequestContext<TParams>(McpServer, JsonRpcRequest)` constructor is obsolete. Use the overload that accepts a `parameters` argument: `RequestContext<TParams>(McpServer, JsonRpcRequest, TParams)`. |
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ builder.Services
|
|||
{
|
||||
throw new McpException("Cannot add subscription for server with null SessionId");
|
||||
}
|
||||
if (ctx.Params?.Uri is { } uri)
|
||||
if (ctx.Params.Uri is { } uri)
|
||||
{
|
||||
subscriptions[ctx.Server.SessionId].TryAdd(uri, 0);
|
||||
|
||||
|
|
@ -154,7 +154,7 @@ builder.Services
|
|||
{
|
||||
throw new McpException("Cannot remove subscription for server with null SessionId");
|
||||
}
|
||||
if (ctx.Params?.Uri is { } uri)
|
||||
if (ctx.Params.Uri is { } uri)
|
||||
{
|
||||
subscriptions[ctx.Server.SessionId].TryRemove(uri, out _);
|
||||
}
|
||||
|
|
@ -212,11 +212,6 @@ builder.Services
|
|||
})
|
||||
.WithSetLoggingLevelHandler(async (ctx, ct) =>
|
||||
{
|
||||
if (ctx.Params?.Level is null)
|
||||
{
|
||||
throw new McpProtocolException("Missing required argument 'level'", McpErrorCode.InvalidParams);
|
||||
}
|
||||
|
||||
// The SDK updates the LoggingLevel field of the IMcpServer
|
||||
|
||||
await ctx.Server.SendNotificationAsync("notifications/message", new
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public class SimpleResourceType
|
|||
int index = id - 1;
|
||||
if ((uint)index >= ResourceGenerator.Resources.Count)
|
||||
{
|
||||
throw new NotSupportedException($"Unknown resource: {requestContext.Params?.Uri}");
|
||||
throw new NotSupportedException($"Unknown resource: {requestContext.Params.Uri}");
|
||||
}
|
||||
|
||||
var resource = ResourceGenerator.Resources[index];
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public class LongRunningTool
|
|||
int duration = 10,
|
||||
int steps = 5)
|
||||
{
|
||||
var progressToken = context.Params?.ProgressToken;
|
||||
var progressToken = context.Params.ProgressToken;
|
||||
var stepDuration = duration / steps;
|
||||
|
||||
for (int i = 1; i <= steps + 1; i++)
|
||||
|
|
|
|||
|
|
@ -25,4 +25,8 @@ internal static class Obsoletions
|
|||
|
||||
// MCP9002 was used for the AddXxxFilter extension methods on IMcpServerBuilder that were superseded by
|
||||
// WithMessageFilters() and WithRequestFilters(). The APIs were removed; do not reuse this diagnostic ID.
|
||||
|
||||
public const string RequestContextParamsConstructor_DiagnosticId = "MCP9003";
|
||||
public const string RequestContextParamsConstructor_Message = "Use the constructor overload that accepts a parameters argument.";
|
||||
public const string RequestContextParamsConstructor_Url = "https://github.com/modelcontextprotocol/csharp-sdk/blob/main/docs/list-of-diagnostics.md#mcp9003";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ internal sealed class RequestHandlers : Dictionary<string, Func<JsonRpcRequest,
|
|||
/// </remarks>
|
||||
public void Set<TParams, TResult>(
|
||||
string method,
|
||||
Func<TParams?, JsonRpcRequest, CancellationToken, ValueTask<TResult>> handler,
|
||||
Func<TParams, JsonRpcRequest, CancellationToken, ValueTask<TResult>> handler,
|
||||
JsonTypeInfo<TParams> requestTypeInfo,
|
||||
JsonTypeInfo<TResult> responseTypeInfo)
|
||||
{
|
||||
|
|
@ -40,7 +40,7 @@ internal sealed class RequestHandlers : Dictionary<string, Func<JsonRpcRequest,
|
|||
|
||||
this[method] = async (request, cancellationToken) =>
|
||||
{
|
||||
TParams? typedRequest = JsonSerializer.Deserialize(request.Params, requestTypeInfo);
|
||||
TParams typedRequest = JsonSerializer.Deserialize(request.Params, requestTypeInfo)!;
|
||||
object? result = await handler(typedRequest, request, cancellationToken).ConfigureAwait(false);
|
||||
return JsonSerializer.SerializeToNode(result, responseTypeInfo);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -386,14 +386,14 @@ internal sealed class AIFunctionMcpServerResource : McpServerResource
|
|||
|
||||
TextContent tc => new()
|
||||
{
|
||||
Contents = [new TextResourceContents { Uri = request.Params!.Uri, MimeType = ProtocolResourceTemplate.MimeType, Text = tc.Text }],
|
||||
Contents = [new TextResourceContents { Uri = request.Params.Uri, MimeType = ProtocolResourceTemplate.MimeType, Text = tc.Text }],
|
||||
},
|
||||
|
||||
DataContent dc => new()
|
||||
{
|
||||
Contents = [new BlobResourceContents
|
||||
{
|
||||
Uri = request.Params!.Uri,
|
||||
Uri = request.Params.Uri,
|
||||
MimeType = dc.MediaType,
|
||||
Blob = EncodingUtilities.GetUtf8Bytes(dc.Base64Data.Span)
|
||||
}],
|
||||
|
|
@ -401,7 +401,7 @@ internal sealed class AIFunctionMcpServerResource : McpServerResource
|
|||
|
||||
string text => new()
|
||||
{
|
||||
Contents = [new TextResourceContents { Uri = request.Params!.Uri, MimeType = ProtocolResourceTemplate.MimeType, Text = text }],
|
||||
Contents = [new TextResourceContents { Uri = request.Params.Uri, MimeType = ProtocolResourceTemplate.MimeType, Text = text }],
|
||||
},
|
||||
|
||||
IEnumerable<ResourceContents> contents => new()
|
||||
|
|
@ -416,14 +416,14 @@ internal sealed class AIFunctionMcpServerResource : McpServerResource
|
|||
{
|
||||
TextContent tc => new TextResourceContents
|
||||
{
|
||||
Uri = request.Params!.Uri,
|
||||
Uri = request.Params.Uri,
|
||||
MimeType = ProtocolResourceTemplate.MimeType,
|
||||
Text = tc.Text
|
||||
},
|
||||
|
||||
DataContent dc => new BlobResourceContents
|
||||
{
|
||||
Uri = request.Params!.Uri,
|
||||
Uri = request.Params.Uri,
|
||||
MimeType = dc.MediaType,
|
||||
Blob = EncodingUtilities.GetUtf8Bytes(dc.Base64Data.Span)
|
||||
},
|
||||
|
|
@ -436,7 +436,7 @@ internal sealed class AIFunctionMcpServerResource : McpServerResource
|
|||
{
|
||||
Contents = strings.Select<string, ResourceContents>(text => new TextResourceContents
|
||||
{
|
||||
Uri = request.Params!.Uri,
|
||||
Uri = request.Params.Uri,
|
||||
MimeType = ProtocolResourceTemplate.MimeType,
|
||||
Text = text
|
||||
}).ToList(),
|
||||
|
|
|
|||
|
|
@ -954,7 +954,7 @@ internal sealed partial class McpServerImpl : McpServer
|
|||
// If a handler was provided, now delegate to it.
|
||||
if (setLoggingLevelHandler is not null)
|
||||
{
|
||||
return InvokeHandlerAsync(setLoggingLevelHandler, request, jsonRpcRequest, cancellationToken);
|
||||
return InvokeHandlerAsync(setLoggingLevelHandler, request!, jsonRpcRequest, cancellationToken);
|
||||
}
|
||||
|
||||
// Otherwise, consider it handled.
|
||||
|
|
@ -966,17 +966,17 @@ internal sealed partial class McpServerImpl : McpServer
|
|||
|
||||
private ValueTask<TResult> InvokeHandlerAsync<TParams, TResult>(
|
||||
McpRequestHandler<TParams, TResult> handler,
|
||||
TParams? args,
|
||||
TParams args,
|
||||
JsonRpcRequest jsonRpcRequest,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
return _servicesScopePerRequest ?
|
||||
InvokeScopedAsync(handler, args, jsonRpcRequest, cancellationToken) :
|
||||
handler(new(new DestinationBoundMcpServer(this, jsonRpcRequest.Context?.RelatedTransport), jsonRpcRequest) { Params = args }, cancellationToken);
|
||||
handler(new(new DestinationBoundMcpServer(this, jsonRpcRequest.Context?.RelatedTransport), jsonRpcRequest, args), cancellationToken);
|
||||
|
||||
async ValueTask<TResult> InvokeScopedAsync(
|
||||
McpRequestHandler<TParams, TResult> handler,
|
||||
TParams? args,
|
||||
TParams args,
|
||||
JsonRpcRequest jsonRpcRequest,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
@ -984,10 +984,9 @@ internal sealed partial class McpServerImpl : McpServer
|
|||
try
|
||||
{
|
||||
return await handler(
|
||||
new RequestContext<TParams>(new DestinationBoundMcpServer(this, jsonRpcRequest.Context?.RelatedTransport), jsonRpcRequest)
|
||||
new RequestContext<TParams>(new DestinationBoundMcpServer(this, jsonRpcRequest.Context?.RelatedTransport), jsonRpcRequest, args)
|
||||
{
|
||||
Services = scope?.ServiceProvider ?? Services,
|
||||
Params = args
|
||||
},
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,19 +13,34 @@ namespace ModelContextProtocol.Server;
|
|||
/// </remarks>
|
||||
public sealed class RequestContext<TParams> : MessageContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestContext{TParams}"/> class with the specified server, JSON-RPC request, and request parameters.
|
||||
/// </summary>
|
||||
/// <param name="server">The server with which this instance is associated.</param>
|
||||
/// <param name="jsonRpcRequest">The JSON-RPC request associated with this context.</param>
|
||||
/// <param name="parameters">The parameters associated with this request.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="server"/> or <paramref name="jsonRpcRequest"/> is <see langword="null"/>.</exception>
|
||||
public RequestContext(McpServer server, JsonRpcRequest jsonRpcRequest, TParams parameters)
|
||||
: base(server, jsonRpcRequest)
|
||||
{
|
||||
Params = parameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestContext{TParams}"/> class with the specified server and JSON-RPC request.
|
||||
/// </summary>
|
||||
/// <param name="server">The server with which this instance is associated.</param>
|
||||
/// <param name="jsonRpcRequest">The JSON-RPC request associated with this context.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="server"/> or <paramref name="jsonRpcRequest"/> is <see langword="null"/>.</exception>
|
||||
[Obsolete(Obsoletions.RequestContextParamsConstructor_Message, DiagnosticId = Obsoletions.RequestContextParamsConstructor_DiagnosticId, UrlFormat = Obsoletions.RequestContextParamsConstructor_Url)]
|
||||
public RequestContext(McpServer server, JsonRpcRequest jsonRpcRequest)
|
||||
: base(server, jsonRpcRequest)
|
||||
{
|
||||
Params = default!;
|
||||
}
|
||||
|
||||
/// <summary>Gets or sets the parameters associated with this request.</summary>
|
||||
public TParams? Params { get; set; }
|
||||
public TParams Params { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the primitive that matched the request.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public class Program
|
|||
// For the test_reconnection tool, enable polling mode after the tool runs.
|
||||
// This stores the result and closes the SSE stream, so the client
|
||||
// must reconnect via GET with Last-Event-ID to retrieve the result.
|
||||
if (request.Params?.Name == "test_reconnection")
|
||||
if (request.Params.Name == "test_reconnection")
|
||||
{
|
||||
await request.EnablePollingAsync(TimeSpan.FromMilliseconds(500), cancellationToken);
|
||||
}
|
||||
|
|
@ -54,7 +54,7 @@ public class Program
|
|||
{
|
||||
throw new McpException("Cannot add subscription for server with null SessionId");
|
||||
}
|
||||
if (ctx.Params?.Uri is { } uri)
|
||||
if (ctx.Params.Uri is { } uri)
|
||||
{
|
||||
var sessionSubscriptions = subscriptions.GetOrAdd(ctx.Server.SessionId, _ => new());
|
||||
sessionSubscriptions.TryAdd(uri, 0);
|
||||
|
|
@ -68,7 +68,7 @@ public class Program
|
|||
{
|
||||
throw new McpException("Cannot remove subscription for server with null SessionId");
|
||||
}
|
||||
if (ctx.Params?.Uri is { } uri)
|
||||
if (ctx.Params.Uri is { } uri)
|
||||
{
|
||||
subscriptions[ctx.Server.SessionId].TryRemove(uri, out _);
|
||||
}
|
||||
|
|
@ -91,11 +91,6 @@ public class Program
|
|||
})
|
||||
.WithSetLoggingLevelHandler(async (ctx, ct) =>
|
||||
{
|
||||
if (ctx.Params?.Level is null)
|
||||
{
|
||||
throw new McpProtocolException("Missing required argument 'level'", McpErrorCode.InvalidParams);
|
||||
}
|
||||
|
||||
// The SDK updates the LoggingLevel field of the McpServer
|
||||
// Send a log notification to confirm the level was set
|
||||
await ctx.Server.SendNotificationAsync("notifications/message", new LoggingMessageNotificationParams
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ public class ConformanceTools
|
|||
RequestContext<CallToolRequestParams> context,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var progressToken = context.Params?.ProgressToken;
|
||||
var progressToken = context.Params.ProgressToken;
|
||||
|
||||
if (progressToken is not null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -204,9 +204,9 @@ internal static class Program
|
|||
};
|
||||
options.Handlers.CallToolHandler = async (request, cancellationToken) =>
|
||||
{
|
||||
if (request.Params?.Name == "echo")
|
||||
if (request.Params.Name == "echo")
|
||||
{
|
||||
if (request.Params?.Arguments is null || !request.Params.Arguments.TryGetValue("message", out var message))
|
||||
if (request.Params.Arguments is null || !request.Params.Arguments.TryGetValue("message", out var message))
|
||||
{
|
||||
throw new McpProtocolException("Missing required argument 'message'", McpErrorCode.InvalidParams);
|
||||
}
|
||||
|
|
@ -215,16 +215,16 @@ internal static class Program
|
|||
Content = [new TextContentBlock { Text = $"Echo: {message}" }]
|
||||
};
|
||||
}
|
||||
else if (request.Params?.Name == "echoSessionId")
|
||||
else if (request.Params.Name == "echoSessionId")
|
||||
{
|
||||
return new CallToolResult
|
||||
{
|
||||
Content = [new TextContentBlock { Text = request.Server.SessionId ?? string.Empty }]
|
||||
};
|
||||
}
|
||||
else if (request.Params?.Name == "trigger-sampling-request")
|
||||
else if (request.Params.Name == "trigger-sampling-request")
|
||||
{
|
||||
if (request.Params?.Arguments is null ||
|
||||
if (request.Params.Arguments is null ||
|
||||
!request.Params.Arguments.TryGetValue("prompt", out var prompt) ||
|
||||
!request.Params.Arguments.TryGetValue("maxTokens", out var maxTokens))
|
||||
{
|
||||
|
|
@ -238,16 +238,16 @@ internal static class Program
|
|||
Content = [new TextContentBlock { Text = $"LLM sampling result: {sampleResult.Content.OfType<TextContentBlock>().FirstOrDefault()?.Text}" }]
|
||||
};
|
||||
}
|
||||
else if (request.Params?.Name == "echoCliArg")
|
||||
else if (request.Params.Name == "echoCliArg")
|
||||
{
|
||||
return new CallToolResult
|
||||
{
|
||||
Content = [new TextContentBlock { Text = cliArg ?? "null" }]
|
||||
};
|
||||
}
|
||||
else if (request.Params?.Name == "longRunning")
|
||||
else if (request.Params.Name == "longRunning")
|
||||
{
|
||||
if (request.Params?.Arguments is null || !request.Params.Arguments.TryGetValue("durationMs", out var durationMsValue))
|
||||
if (request.Params.Arguments is null || !request.Params.Arguments.TryGetValue("durationMs", out var durationMsValue))
|
||||
{
|
||||
throw new McpProtocolException("Missing required argument 'durationMs'", McpErrorCode.InvalidParams);
|
||||
}
|
||||
|
|
@ -258,9 +258,9 @@ internal static class Program
|
|||
Content = [new TextContentBlock { Text = $"Long-running operation completed after {durationMs}ms" }]
|
||||
};
|
||||
}
|
||||
else if (request.Params?.Name == "crash")
|
||||
else if (request.Params.Name == "crash")
|
||||
{
|
||||
if (request.Params?.Arguments is null || !request.Params.Arguments.TryGetValue("exitCode", out var exitCodeValue))
|
||||
if (request.Params.Arguments is null || !request.Params.Arguments.TryGetValue("exitCode", out var exitCodeValue))
|
||||
{
|
||||
throw new McpProtocolException("Missing required argument 'exitCode'", McpErrorCode.InvalidParams);
|
||||
}
|
||||
|
|
@ -271,7 +271,7 @@ internal static class Program
|
|||
}
|
||||
else
|
||||
{
|
||||
throw new McpProtocolException($"Unknown tool: {request.Params?.Name}", McpErrorCode.InvalidParams);
|
||||
throw new McpProtocolException($"Unknown tool: {request.Params.Name}", McpErrorCode.InvalidParams);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -335,7 +335,7 @@ internal static class Program
|
|||
options.Handlers.GetPromptHandler = async (request, cancellationToken) =>
|
||||
{
|
||||
List<PromptMessage> messages = [];
|
||||
if (request.Params?.Name == "simple-prompt")
|
||||
if (request.Params.Name == "simple-prompt")
|
||||
{
|
||||
messages.Add(new PromptMessage
|
||||
{
|
||||
|
|
@ -343,7 +343,7 @@ internal static class Program
|
|||
Content = new TextContentBlock { Text = "This is a simple prompt without arguments." },
|
||||
});
|
||||
}
|
||||
else if (request.Params?.Name == "args-prompt")
|
||||
else if (request.Params.Name == "args-prompt")
|
||||
{
|
||||
string city = request.Params.Arguments?["city"].ToString() ?? "unknown";
|
||||
string state = request.Params.Arguments?["state"].ToString() ?? "";
|
||||
|
|
@ -354,7 +354,7 @@ internal static class Program
|
|||
Content = new TextContentBlock { Text = $"What's weather in {location}?" },
|
||||
});
|
||||
}
|
||||
else if (request.Params?.Name == "completable-prompt")
|
||||
else if (request.Params.Name == "completable-prompt")
|
||||
{
|
||||
string department = request.Params.Arguments?["department"].ToString() ?? "unknown";
|
||||
string name = request.Params.Arguments?["name"].ToString() ?? "unknown";
|
||||
|
|
@ -366,7 +366,7 @@ internal static class Program
|
|||
}
|
||||
else
|
||||
{
|
||||
throw new McpProtocolException($"Unknown prompt: {request.Params?.Name}", McpErrorCode.InvalidParams);
|
||||
throw new McpProtocolException($"Unknown prompt: {request.Params.Name}", McpErrorCode.InvalidParams);
|
||||
}
|
||||
|
||||
return new GetPromptResult
|
||||
|
|
@ -382,11 +382,6 @@ internal static class Program
|
|||
{
|
||||
options.Handlers.SetLoggingLevelHandler = async (request, cancellationToken) =>
|
||||
{
|
||||
if (request.Params?.Level is null)
|
||||
{
|
||||
throw new McpProtocolException("Missing required argument 'level'", McpErrorCode.InvalidParams);
|
||||
}
|
||||
|
||||
_minimumLoggingLevel = request.Params.Level;
|
||||
|
||||
return new EmptyResult();
|
||||
|
|
@ -452,7 +447,7 @@ internal static class Program
|
|||
options.Handlers.ListResourcesHandler = async (request, cancellationToken) =>
|
||||
{
|
||||
int startIndex = 0;
|
||||
if (request.Params?.Cursor is not null)
|
||||
if (request.Params.Cursor is not null)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -481,7 +476,7 @@ internal static class Program
|
|||
|
||||
options.Handlers.ReadResourceHandler = async (request, cancellationToken) =>
|
||||
{
|
||||
if (request.Params?.Uri is null)
|
||||
if (request.Params.Uri is null)
|
||||
{
|
||||
throw new McpProtocolException("Missing required argument 'uri'", McpErrorCode.InvalidParams);
|
||||
}
|
||||
|
|
@ -518,7 +513,7 @@ internal static class Program
|
|||
|
||||
options.Handlers.SubscribeToResourcesHandler = async (request, cancellationToken) =>
|
||||
{
|
||||
if (request?.Params?.Uri is null)
|
||||
if (request?.Params.Uri is null)
|
||||
{
|
||||
throw new McpProtocolException("Missing required argument 'uri'", McpErrorCode.InvalidParams);
|
||||
}
|
||||
|
|
@ -535,7 +530,7 @@ internal static class Program
|
|||
|
||||
options.Handlers.UnsubscribeFromResourcesHandler = async (request, cancellationToken) =>
|
||||
{
|
||||
if (request?.Params?.Uri is null)
|
||||
if (request?.Params.Uri is null)
|
||||
{
|
||||
throw new McpProtocolException("Missing required argument 'uri'", McpErrorCode.InvalidParams);
|
||||
}
|
||||
|
|
@ -563,7 +558,7 @@ internal static class Program
|
|||
options.Handlers.CompleteHandler = async (request, cancellationToken) =>
|
||||
{
|
||||
string[]? values;
|
||||
switch (request.Params?.Ref)
|
||||
switch (request.Params.Ref)
|
||||
{
|
||||
case ResourceTemplateReference rtr:
|
||||
var resourceId = rtr.Uri?.Split('/').LastOrDefault();
|
||||
|
|
@ -571,7 +566,7 @@ internal static class Program
|
|||
return new CompleteResult { Completion = new() { Values = [] } };
|
||||
|
||||
// Filter resource IDs that start with the input value
|
||||
values = sampleResourceIds.Where(id => id.StartsWith(request.Params!.Argument.Value)).ToArray();
|
||||
values = sampleResourceIds.Where(id => id.StartsWith(request.Params.Argument.Value)).ToArray();
|
||||
return new CompleteResult { Completion = new() { Values = values, HasMore = false, Total = values.Length } };
|
||||
|
||||
case PromptReference pr:
|
||||
|
|
@ -583,7 +578,7 @@ internal static class Program
|
|||
return new CompleteResult { Completion = new() { Values = values, HasMore = false, Total = values.Length } };
|
||||
|
||||
default:
|
||||
throw new McpProtocolException($"Unknown reference type: '{request.Params?.Ref.Type}'", McpErrorCode.InvalidParams);
|
||||
throw new McpProtocolException($"Unknown reference type: '{request.Params.Ref.Type}'", McpErrorCode.InvalidParams);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ public class Program
|
|||
|
||||
ReadResourceHandler = async (request, cancellationToken) =>
|
||||
{
|
||||
if (request.Params?.Uri is null)
|
||||
if (request.Params.Uri is null)
|
||||
{
|
||||
throw new McpProtocolException("Missing required argument 'uri'", McpErrorCode.InvalidParams);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public class McpClientMetaTests : ClientServerTestBase
|
|||
async (RequestContext<CallToolRequestParams> context) =>
|
||||
{
|
||||
// Access the foo property of _meta field from the request parameters
|
||||
var metaFoo = context.Params?.Meta?["foo"]?.ToString();
|
||||
var metaFoo = context.Params.Meta?["foo"]?.ToString();
|
||||
|
||||
// Assert that the meta foo is correctly passed
|
||||
Assert.NotNull(metaFoo);
|
||||
|
|
@ -73,7 +73,7 @@ public class McpClientMetaTests : ClientServerTestBase
|
|||
(RequestContext<ReadResourceRequestParams> context) =>
|
||||
{
|
||||
// Access the foo property of _meta field from the request parameters
|
||||
var metaFoo = context.Params?.Meta?["foo"]?.ToString();
|
||||
var metaFoo = context.Params.Meta?["foo"]?.ToString();
|
||||
|
||||
// Assert that the meta foo is correctly passed
|
||||
Assert.NotNull(metaFoo);
|
||||
|
|
@ -109,7 +109,7 @@ public class McpClientMetaTests : ClientServerTestBase
|
|||
(RequestContext<GetPromptRequestParams> context) =>
|
||||
{
|
||||
// Access the foo property of _meta field from the request parameters
|
||||
var metaFoo = context.Params?.Meta?["foo"]?.ToString();
|
||||
var metaFoo = context.Params.Meta?["foo"]?.ToString();
|
||||
|
||||
// Assert that the meta foo is correctly passed
|
||||
Assert.NotNull(metaFoo);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ public class McpClientPromptTests : ClientServerTestBase
|
|||
|
||||
[McpServerPrompt, Description("Echoes back the metadata it receives")]
|
||||
public static ChatMessage MetadataEcho(RequestContext<GetPromptRequestParams> context) =>
|
||||
new(ChatRole.User, context.Params?.Meta?.ToJsonString() ?? "{}");
|
||||
new(ChatRole.User, context.Params.Meta?.ToJsonString() ?? "{}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue