Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f636f4b
Initial plan
Copilot Nov 18, 2025
701597c
Remove internal usages of obsolete capability properties
Copilot Nov 18, 2025
d826cd3
Remove all obsolete API definitions and related tests
Copilot Nov 18, 2025
cd8f7ae
Merge main branch and resolve conflicts
Copilot Nov 19, 2025
3d20111
Merge remote-tracking branch 'origin/main' into copilot/remove-obsole…
Copilot Nov 19, 2025
eb31afb
Remove unused duplicate CreateSamplingHandler and helper methods from…
Copilot Nov 19, 2025
c7deb7f
Delete empty McpEndpointExtensions and McpServerExtensions classes
Copilot Nov 19, 2025
4d6fe0a
Remove obsolete IMcpEndpoint, IMcpClient, IMcpServer interfaces and M…
Copilot Nov 19, 2025
2decb2d
Remove extra newlines before closing braces in capability classes
Copilot Nov 19, 2025
4443cfc
Merge main branch and resolve conflicts (PR #976 integration)
Copilot Nov 20, 2025
44083aa
Revert "Merge main branch and resolve conflicts (PR #976 integration)"
MackinnonBuck Nov 20, 2025
cd9ce13
Merge remote-tracking branch 'origin/main' into copilot/remove-obsole…
MackinnonBuck Nov 20, 2025
93a6877
Remove remaining obsolete EnumSchema and LegacyTitledEnumSchema types…
Copilot Nov 21, 2025
186d85c
Restore EnumSchemaTests.cs and add back valid enum schema tests witho…
Copilot Nov 21, 2025
04e1326
Revert: "Remove remaining obsolete EnumSchema and LegacyTitledEnumSch…
jeffhandley Nov 26, 2025
40df946
Merge branch 'main' into copilot/remove-obsolete-apis
jeffhandley Nov 26, 2025
3c29253
Introduce Obsoletions/Experimentals pattern for custom diagnostics.
jeffhandley Nov 26, 2025
6fcf81c
Fix failing enum schema tests
jeffhandley Nov 26, 2025
981386e
Merge branch 'main' into copilot/remove-obsolete-apis
jeffhandley Nov 27, 2025
95708d6
Revise diagnostic ID ranges for analyzers, obsoletions, experimentals
jeffhandley Nov 27, 2025
7e074f8
Fix XML comment reference to RegisterNotificationHandler
jeffhandley Nov 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 0 additions & 112 deletions src/ModelContextProtocol.Core/Client/McpClient.Methods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -555,118 +555,6 @@ async ValueTask<CallToolResult> SendRequestWithProgressAsync(
}
}

/// <summary>
/// Converts the contents of a <see cref="CreateMessageRequestParams"/> into a pair of
/// <see cref="IEnumerable{ChatMessage}"/> and <see cref="ChatOptions"/> instances to use
/// as inputs into a <see cref="IChatClient"/> operation.
/// </summary>
/// <param name="requestParams"></param>
/// <returns>The created pair of messages and options.</returns>
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
internal static (IList<ChatMessage> Messages, ChatOptions? Options) ToChatClientArguments(
CreateMessageRequestParams requestParams)
{
Throw.IfNull(requestParams);

ChatOptions? options = null;

if (requestParams.MaxTokens is int maxTokens)
{
(options ??= new()).MaxOutputTokens = maxTokens;
}

if (requestParams.Temperature is float temperature)
{
(options ??= new()).Temperature = temperature;
}

if (requestParams.StopSequences is { } stopSequences)
{
(options ??= new()).StopSequences = stopSequences.ToArray();
}

List<ChatMessage> messages =
(from sm in requestParams.Messages
let aiContent = sm.Content.ToAIContent()
where aiContent is not null
select new ChatMessage(sm.Role == Role.Assistant ? ChatRole.Assistant : ChatRole.User, [aiContent]))
.ToList();

return (messages, options);
}

/// <summary>Converts the contents of a <see cref="ChatResponse"/> into a <see cref="CreateMessageResult"/>.</summary>
/// <param name="chatResponse">The <see cref="ChatResponse"/> whose contents should be extracted.</param>
/// <returns>The created <see cref="CreateMessageResult"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="chatResponse"/> is <see langword="null"/>.</exception>
internal static CreateMessageResult ToCreateMessageResult(ChatResponse chatResponse)
{
Throw.IfNull(chatResponse);

// The ChatResponse can include multiple messages, of varying modalities, but CreateMessageResult supports
// only either a single blob of text or a single image. Heuristically, we'll use an image if there is one
// in any of the response messages, or we'll use all the text from them concatenated, otherwise.

ChatMessage? lastMessage = chatResponse.Messages.LastOrDefault();

ContentBlock? content = null;
if (lastMessage is not null)
{
foreach (var lmc in lastMessage.Contents)
{
if (lmc is DataContent dc && (dc.HasTopLevelMediaType("image") || dc.HasTopLevelMediaType("audio")))
{
content = dc.ToContent();
}
}
}

return new()
{
Content = content ?? new TextContentBlock { Text = lastMessage?.Text ?? string.Empty },
Model = chatResponse.ModelId ?? "unknown",
Role = lastMessage?.Role == ChatRole.User ? Role.User : Role.Assistant,
StopReason = chatResponse.FinishReason == ChatFinishReason.Length ? "maxTokens" : "endTurn",
};
}

/// <summary>
/// Creates a sampling handler for use with <see cref="McpClientHandlers.SamplingHandler"/> that will
/// satisfy sampling requests using the specified <see cref="IChatClient"/>.
/// </summary>
/// <param name="chatClient">The <see cref="IChatClient"/> with which to satisfy sampling requests.</param>
/// <returns>The created handler delegate that can be assigned to <see cref="McpClientHandlers.SamplingHandler"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="chatClient"/> is <see langword="null"/>.</exception>
public static Func<CreateMessageRequestParams?, IProgress<ProgressNotificationValue>, CancellationToken, ValueTask<CreateMessageResult>> CreateSamplingHandler(
IChatClient chatClient)
{
Throw.IfNull(chatClient);

return async (requestParams, progress, cancellationToken) =>
{
Throw.IfNull(requestParams);

var (messages, options) = ToChatClientArguments(requestParams);
var progressToken = requestParams.ProgressToken;

List<ChatResponseUpdate> updates = [];
await foreach (var update in chatClient.GetStreamingResponseAsync(messages, options, cancellationToken).ConfigureAwait(false))
{
updates.Add(update);

if (progressToken is not null)
{
progress.Report(new()
{
Progress = updates.Count,
});
}
}

return ToCreateMessageResult(updates.ToChatResponse());
};
}

/// <summary>
/// Sets the logging level for the server to control which log messages are sent to the client.
/// </summary>
Expand Down
Loading
Loading