diff --git a/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs b/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs index a48e41b6..0f55fa2e 100644 --- a/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs +++ b/src/ModelContextProtocol.Core/Server/McpServer.Methods.cs @@ -153,7 +153,7 @@ public async Task SampleAsync( var result = await SampleAsync(new() { Messages = samplingMessages, - MaxTokens = options?.MaxOutputTokens ?? int.MaxValue, + MaxTokens = options?.MaxOutputTokens ?? ServerOptions.DefaultSamplingMaxTokens, StopSequences = options?.StopSequences?.ToArray(), SystemPrompt = systemPrompt?.ToString(), Temperature = options?.Temperature, diff --git a/src/ModelContextProtocol.Core/Server/McpServerOptions.cs b/src/ModelContextProtocol.Core/Server/McpServerOptions.cs index 618e87d5..e7bf1cf6 100644 --- a/src/ModelContextProtocol.Core/Server/McpServerOptions.cs +++ b/src/ModelContextProtocol.Core/Server/McpServerOptions.cs @@ -152,4 +152,17 @@ public McpServerHandlers Handlers /// /// public McpServerPrimitiveCollection? PromptCollection { get; set; } + + /// + /// Gets or sets the default maximum number of tokens to use for sampling requests when not explicitly specified. + /// + /// + /// + /// This value is used when is not set in the request options. + /// + /// + /// The default value is 1000 tokens. + /// + /// + public int DefaultSamplingMaxTokens { get; set; } = 1000; } diff --git a/tests/ModelContextProtocol.Tests/Server/McpServerExtensionsTests.cs b/tests/ModelContextProtocol.Tests/Server/McpServerExtensionsTests.cs index 2bfbb098..55fcc0ea 100644 --- a/tests/ModelContextProtocol.Tests/Server/McpServerExtensionsTests.cs +++ b/tests/ModelContextProtocol.Tests/Server/McpServerExtensionsTests.cs @@ -125,12 +125,25 @@ public async Task SampleAsync_Messages_Forwards_To_McpServer_SendRequestAsync() StopReason = "endTurn", }; + const int customDefaultMaxTokens = 500; + mockServer .Setup(s => s.ClientCapabilities) .Returns(new ClientCapabilities() { Sampling = new() }); + mockServer + .Setup(s => s.ServerOptions) + .Returns(new McpServerOptions { DefaultSamplingMaxTokens = customDefaultMaxTokens }); + + CreateMessageRequestParams? capturedRequest = null; mockServer .Setup(s => s.SendRequestAsync(It.IsAny(), It.IsAny())) + .Callback((request, _) => + { + capturedRequest = JsonSerializer.Deserialize( + request.Params ?? throw new InvalidOperationException(), + McpJsonUtilities.DefaultOptions); + }) .ReturnsAsync(new JsonRpcResponse { Id = default, @@ -146,6 +159,10 @@ public async Task SampleAsync_Messages_Forwards_To_McpServer_SendRequestAsync() Assert.Equal(ChatRole.Assistant, last.Role); Assert.Equal("resp", last.Text); mockServer.Verify(s => s.SendRequestAsync(It.IsAny(), It.IsAny()), Times.Once); + + // Verify that the default value was used + Assert.NotNull(capturedRequest); + Assert.Equal(customDefaultMaxTokens, capturedRequest.MaxTokens); } [Fact]