Skip to content

Commit 7c9bcc3

Browse files
committed
Merge branch 'main' into improving-resources
2 parents 3ed3b99 + d47c834 commit 7c9bcc3

File tree

77 files changed

+721
-441
lines changed

Some content is hidden

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

77 files changed

+721
-441
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ var client = await McpClientFactory.CreateAsync(new()
4444
});
4545

4646
// Print the list of tools available from the server.
47-
await foreach (var tool in client.ListToolsAsync())
47+
foreach (var tool in await client.ListToolsAsync())
4848
{
4949
Console.WriteLine($"{tool.Name} ({tool.Description})");
5050
}

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: 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,

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
}
@@ -111,6 +111,7 @@ internal static Content ToContent(this AIContent content) =>
111111
Text = textContent.Text,
112112
Type = "text",
113113
},
114+
114115
DataContent dataContent => new()
115116
{
116117
Data = dataContent.GetBase64Data(),
@@ -120,6 +121,7 @@ internal static Content ToContent(this AIContent content) =>
120121
dataContent.HasTopLevelMediaType("audio") ? "audio" :
121122
"resource",
122123
},
124+
123125
_ => new()
124126
{
125127
Text = JsonSerializer.Serialize(content, McpJsonUtilities.DefaultOptions.GetTypeInfo(typeof(object))),

src/ModelContextProtocol/Client/McpClient.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using ModelContextProtocol.Shared;
77
using ModelContextProtocol.Utils.Json;
88
using Microsoft.Extensions.Logging;
9-
using Microsoft.Extensions.Logging.Abstractions;
109
using System.Text.Json;
1110

1211
namespace ModelContextProtocol.Client;
@@ -126,11 +125,11 @@ private async Task InitializeAsync(CancellationToken cancellationToken)
126125
new JsonRpcRequest
127126
{
128127
Method = "initialize",
129-
Params = new
128+
Params = new InitializeRequestParams()
130129
{
131-
protocolVersion = _options.ProtocolVersion,
132-
capabilities = _options.Capabilities ?? new ClientCapabilities(),
133-
clientInfo = _options.ClientInfo
130+
ProtocolVersion = _options.ProtocolVersion,
131+
Capabilities = _options.Capabilities ?? new ClientCapabilities(),
132+
ClientInfo = _options.ClientInfo
134133
}
135134
},
136135
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
}
@@ -502,11 +502,11 @@ internal static CreateMessageResult ToCreateMessageResult(this ChatResponse chat
502502
{
503503
foreach (var lmc in lastMessage.Contents)
504504
{
505-
if (lmc is DataContent dc && dc.HasTopLevelMediaType("image"))
505+
if (lmc is DataContent dc && (dc.HasTopLevelMediaType("image") || dc.HasTopLevelMediaType("audio")))
506506
{
507507
content = new()
508508
{
509-
Type = "image",
509+
Type = dc.HasTopLevelMediaType("image") ? "image" : "audio",
510510
MimeType = dc.MediaType,
511511
Data = dc.GetBase64Data(),
512512
};

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/Configuration/McpServerOptionsSetup.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ public void Configure(McpServerOptions options)
2727
// if it otherwise lacks server information.
2828
if (options.ServerInfo is not { } serverInfo)
2929
{
30-
var assemblyName = (Assembly.GetEntryAssembly() ?? Assembly.GetCallingAssembly()).GetName();
30+
var assemblyName = Assembly.GetEntryAssembly()?.GetName();
3131
options.ServerInfo = new()
3232
{
33-
Name = assemblyName.Name ?? "McpServer",
34-
Version = assemblyName.Version?.ToString() ?? "1.0.0",
33+
Name = assemblyName?.Name ?? "McpServer",
34+
Version = assemblyName?.Version?.ToString() ?? "1.0.0",
3535
};
3636
}
3737

0 commit comments

Comments
 (0)