Skip to content

Commit 2ef38ff

Browse files
committed
Merge branch 'main' into gracefulshutdown
# Conflicts: # src/ModelContextProtocol/Client/McpClient.cs # src/ModelContextProtocol/Protocol/Transport/StdioServerTransport.cs
2 parents 4ae26c0 + 62e92fa commit 2ef38ff

File tree

73 files changed

+700
-426
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+700
-426
lines changed

samples/AspNetCoreSseServer/Tools/SampleLlmTool.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace TestServerWithHosting.Tools;
1010
[McpServerToolType]
1111
public static class SampleLlmTool
1212
{
13-
[McpServerTool("sampleLLM"), Description("Samples from an LLM using MCP's sampling feature")]
13+
[McpServerTool(Name = "sampleLLM"), Description("Samples from an LLM using MCP's sampling feature")]
1414
public static async Task<string> SampleLLM(
1515
IMcpServer thisServer,
1616
[Description("The prompt to send to the LLM")] string prompt,

samples/TestServerWithHosting/Tools/SampleLlmTool.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,17 @@ namespace TestServerWithHosting.Tools;
88
/// This tool uses depenency injection and async method
99
/// </summary>
1010
[McpServerToolType]
11-
public class SampleLlmTool
11+
public static class SampleLlmTool
1212
{
13-
private readonly IMcpServer _server;
14-
15-
public SampleLlmTool(IMcpServer server)
16-
{
17-
_server = server ?? throw new ArgumentNullException(nameof(server));
18-
}
19-
20-
[McpServerTool("sampleLLM"), Description("Samples from an LLM using MCP's sampling feature")]
21-
public async Task<string> SampleLLM(
13+
[McpServerTool(Name = "sampleLLM"), Description("Samples from an LLM using MCP's sampling feature")]
14+
public static async Task<string> SampleLLM(
15+
IMcpServer thisServer,
2216
[Description("The prompt to send to the LLM")] string prompt,
2317
[Description("Maximum number of tokens to generate")] int maxTokens,
2418
CancellationToken cancellationToken)
2519
{
2620
var samplingParams = CreateRequestSamplingParams(prompt ?? string.Empty, "sampleLLM", maxTokens);
27-
var sampleResult = await _server.RequestSamplingAsync(samplingParams, cancellationToken);
21+
var sampleResult = await thisServer.RequestSamplingAsync(samplingParams, cancellationToken);
2822

2923
return $"LLM sampling result: {sampleResult.Content.Text}";
3024
}

src/ModelContextProtocol/AIContentExtensions.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public static AIContent ToAIContent(this Content content)
3333
Throw.IfNull(content);
3434

3535
AIContent ac;
36-
if (content is { Type: "image", MimeType: not null, Data: not null })
36+
if (content is { Type: "image" or "audio", MimeType: not null, Data: not null })
3737
{
3838
ac = new DataContent(Convert.FromBase64String(content.Data), content.MimeType);
3939
}
@@ -112,6 +112,7 @@ internal static Content ToContent(this AIContent content) =>
112112
Text = textContent.Text,
113113
Type = "text",
114114
},
115+
115116
DataContent dataContent => new()
116117
{
117118
Data = dataContent.GetBase64Data(),
@@ -121,6 +122,7 @@ internal static Content ToContent(this AIContent content) =>
121122
dataContent.HasTopLevelMediaType("audio") ? "audio" :
122123
"resource",
123124
},
125+
124126
_ => new()
125127
{
126128
Text = JsonSerializer.Serialize(content, McpJsonUtilities.DefaultOptions.GetTypeInfo(typeof(object))),

src/ModelContextProtocol/Client/McpClient.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,11 @@ public async Task ConnectAsync(CancellationToken cancellationToken = default)
101101
new JsonRpcRequest
102102
{
103103
Method = "initialize",
104-
Params = new
104+
Params = new InitializeRequestParams()
105105
{
106-
protocolVersion = _options.ProtocolVersion,
107-
capabilities = _options.Capabilities ?? new ClientCapabilities(),
108-
clientInfo = _options.ClientInfo
106+
ProtocolVersion = _options.ProtocolVersion,
107+
Capabilities = _options.Capabilities ?? new ClientCapabilities(),
108+
ClientInfo = _options.ClientInfo,
109109
}
110110
},
111111
initializationCts.Token).ConfigureAwait(false);

src/ModelContextProtocol/Client/McpClientExtensions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ internal static (IList<ChatMessage> Messages, ChatOptions? Options) ToChatClient
469469
{
470470
message.Contents.Add(new TextContent(sm.Content.Text));
471471
}
472-
else if (sm.Content is { Type: "image", MimeType: not null, Data: not null })
472+
else if (sm.Content is { Type: "image" or "audio", MimeType: not null, Data: not null })
473473
{
474474
message.Contents.Add(new DataContent(Convert.FromBase64String(sm.Content.Data), sm.Content.MimeType));
475475
}
@@ -512,11 +512,11 @@ internal static CreateMessageResult ToCreateMessageResult(this ChatResponse chat
512512
{
513513
foreach (var lmc in lastMessage.Contents)
514514
{
515-
if (lmc is DataContent dc && dc.HasTopLevelMediaType("image"))
515+
if (lmc is DataContent dc && (dc.HasTopLevelMediaType("image") || dc.HasTopLevelMediaType("audio")))
516516
{
517517
content = new()
518518
{
519-
Type = "image",
519+
Type = dc.HasTopLevelMediaType("image") ? "image" : "audio",
520520
MimeType = dc.MediaType,
521521
Data = dc.GetBase64Data(),
522522
};

src/ModelContextProtocol/Client/McpClientTool.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,24 @@ namespace ModelContextProtocol.Client;
99
public sealed class McpClientTool : AIFunction
1010
{
1111
private readonly IMcpClient _client;
12-
private readonly Tool _tool;
1312

1413
internal McpClientTool(IMcpClient client, Tool tool)
1514
{
1615
_client = client;
17-
_tool = tool;
16+
ProtocolTool = tool;
1817
}
1918

19+
/// <summary>Gets the protocol <see cref="Tool"/> type for this instance.</summary>
20+
public Tool ProtocolTool { get; }
21+
2022
/// <inheritdoc/>
21-
public override string Name => _tool.Name;
23+
public override string Name => ProtocolTool.Name;
2224

2325
/// <inheritdoc/>
24-
public override string Description => _tool.Description ?? string.Empty;
26+
public override string Description => ProtocolTool.Description ?? string.Empty;
2527

2628
/// <inheritdoc/>
27-
public override JsonElement JsonSchema => _tool.InputSchema;
29+
public override JsonElement JsonSchema => ProtocolTool.InputSchema;
2830

2931
/// <inheritdoc/>
3032
public override JsonSerializerOptions JsonSerializerOptions => McpJsonUtilities.DefaultOptions;
@@ -37,7 +39,7 @@ internal McpClientTool(IMcpClient client, Tool tool)
3739
arguments as IReadOnlyDictionary<string, object?> ??
3840
arguments.ToDictionary();
3941

40-
CallToolResponse result = await _client.CallToolAsync(_tool.Name, argDict, cancellationToken).ConfigureAwait(false);
42+
CallToolResponse result = await _client.CallToolAsync(ProtocolTool.Name, argDict, cancellationToken).ConfigureAwait(false);
4143
return JsonSerializer.SerializeToElement(result, McpJsonUtilities.JsonContext.Default.CallToolResponse);
4244
}
4345
}

src/ModelContextProtocol/Configuration/McpServerBuilderExtensions.Tools.cs

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ namespace ModelContextProtocol;
1212
/// </summary>
1313
public static partial class McpServerBuilderExtensions
1414
{
15-
private const string RequiresUnreferencedCodeMessage = "This method requires dynamic lookup of method metadata and might not work in Native AOT.";
15+
private const string WithToolsRequiresUnreferencedCodeMessage =
16+
$"The non-generic {nameof(WithTools)} and {nameof(WithToolsFromAssembly)} methods require dynamic lookup of method metadata" +
17+
$"and may not work in Native AOT. Use the generic {nameof(WithTools)} method instead.";
1618

1719
/// <summary>Adds <see cref="McpServerTool"/> instances to the service collection backing <paramref name="builder"/>.</summary>
1820
/// <typeparam name="TTool">The tool type.</typeparam>
@@ -35,14 +37,9 @@ public static partial class McpServerBuilderExtensions
3537
{
3638
if (toolMethod.GetCustomAttribute<McpServerToolAttribute>() is not null)
3739
{
38-
if (toolMethod.IsStatic)
39-
{
40-
builder.Services.AddSingleton(services => McpServerTool.Create(toolMethod, services: services));
41-
}
42-
else
43-
{
44-
builder.Services.AddSingleton(services => McpServerTool.Create(toolMethod, typeof(TTool), services: services));
45-
}
40+
builder.Services.AddSingleton((Func<IServiceProvider, McpServerTool>)(toolMethod.IsStatic ?
41+
services => McpServerTool.Create(toolMethod, new McpServerToolCreateOptions() { Services = services }) :
42+
services => McpServerTool.Create(toolMethod, typeof(TTool), new() { Services = services })));
4643
}
4744
}
4845

@@ -59,7 +56,7 @@ public static partial class McpServerBuilderExtensions
5956
/// types, where the methods are attributed as <see cref="McpServerToolAttribute"/>, and adds an <see cref="McpServerTool"/>
6057
/// instance for each. For instance methods, an instance will be constructed for each invocation of the tool.
6158
/// </remarks>
62-
[RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
59+
[RequiresUnreferencedCode(WithToolsRequiresUnreferencedCodeMessage)]
6360
public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, params IEnumerable<Type> toolTypes)
6461
{
6562
Throw.IfNull(builder);
@@ -69,18 +66,13 @@ public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, params
6966
{
7067
if (toolType is not null)
7168
{
72-
foreach (var method in toolType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance))
69+
foreach (var toolMethod in toolType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance))
7370
{
74-
if (method.GetCustomAttribute<McpServerToolAttribute>() is not null)
71+
if (toolMethod.GetCustomAttribute<McpServerToolAttribute>() is not null)
7572
{
76-
if (method.IsStatic)
77-
{
78-
builder.Services.AddSingleton(services => McpServerTool.Create(method, services: services));
79-
}
80-
else
81-
{
82-
builder.Services.AddSingleton(services => McpServerTool.Create(method, toolType, services: services));
83-
}
73+
builder.Services.AddSingleton((Func<IServiceProvider, McpServerTool>)(toolMethod.IsStatic ?
74+
services => McpServerTool.Create(toolMethod, new McpServerToolCreateOptions() { Services = services }) :
75+
services => McpServerTool.Create(toolMethod, toolType, new() { Services = services })));
8476
}
8577
}
8678
}
@@ -95,7 +87,7 @@ public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, params
9587
/// <param name="builder">The builder instance.</param>
9688
/// <param name="toolAssembly">The assembly to load the types from. Null to get the current assembly</param>
9789
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
98-
[RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
90+
[RequiresUnreferencedCode(WithToolsRequiresUnreferencedCodeMessage)]
9991
public static IMcpServerBuilder WithToolsFromAssembly(this IMcpServerBuilder builder, Assembly? toolAssembly = null)
10092
{
10193
Throw.IfNull(builder);

src/ModelContextProtocol/Protocol/Messages/JsonRpcMessage.cs renamed to src/ModelContextProtocol/Protocol/Messages/JsonRpcRequest.cs

File renamed without changes.

src/ModelContextProtocol/Protocol/Types/Annotated.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace ModelContextProtocol.Protocol.Types;
44

55
/// <summary>
66
/// Base for objects that include optional annotations for the client. The client can use annotations to inform how objects are used or displayed.
7-
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
7+
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/">See the schema for details</see>
88
/// </summary>
99
public abstract record Annotated
1010
{

src/ModelContextProtocol/Protocol/Types/Annotations.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace ModelContextProtocol.Protocol.Types;
44

55
/// <summary>
66
/// Represents annotations that can be attached to content.
7-
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/2024-11-05/schema.json">See the schema for details</see>
7+
/// <see href="https://github.com/modelcontextprotocol/specification/blob/main/schema/">See the schema for details</see>
88
/// </summary>
99
public record Annotations
1010
{

0 commit comments

Comments
 (0)