Skip to content

Commit 6b48562

Browse files
committed
Add extension to register a tool individually
This does away with the need to have a type for the individual tools at all.
1 parent 75b600b commit 6b48562

File tree

2 files changed

+53
-39
lines changed

2 files changed

+53
-39
lines changed

src/MCPDemo/Program.cs

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,47 @@
1-
using ModelContextProtocol.Server;
2-
using SixLabors.ImageSharp;
1+
using SixLabors.ImageSharp;
32
using SixLabors.ImageSharp.PixelFormats;
43

54
var builder = App.CreateBuilder(args);
65
builder.Services.AddHttpClient();
7-
builder.Logging.AddConsole(consoleLogOptions =>
8-
{
9-
// Configure all logs to go to stderr
10-
consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
11-
});
126

137
builder.Services
148
.AddMcpServer()
159
.WithStdioServerTransport()
16-
.WithToolsFromAssembly();
17-
18-
await builder.Build().RunAsync();
19-
20-
[McpServerToolType]
21-
public class LaTeX(IHttpClientFactory httpFactory)
22-
{
23-
[McpServerTool, Description("Converts LaTeX equations into markdown-formatted images for display inline.")]
24-
public async Task<string> LatexMarkdown(
10+
.WithTool(
11+
[Description("Converts LaTeX equations into markdown-formatted images for display inline.")] async
12+
(IHttpClientFactory httpFactory,
2513
[Description("The LaTeX equation to render.")] string latex,
26-
[Description("Use dark mode by inverting the colors in the output.")] bool darkMode)
27-
{
28-
var colors = darkMode ? @"\bg{black}\fg{white}" : @"\bg{white}\fg{black}";
29-
var query = WebUtility.UrlEncode(@"\small\dpi{300}" + colors + latex);
30-
var url = $"https://latex.codecogs.com/png.image?{query}";
31-
using var client = httpFactory.CreateClient();
32-
using var response = await client.GetAsync(url);
33-
34-
if (response.IsSuccessStatusCode)
14+
[Description("Use dark mode by inverting the colors in the output.")] bool darkMode) =>
3515
{
36-
using var image = Image.Load<Rgba32>(await response.Content.ReadAsStreamAsync());
37-
using var ms = new MemoryStream();
38-
image.SaveAsPng(ms);
39-
var base64 = Convert.ToBase64String(ms.ToArray());
40-
return
41-
$"""
16+
var colors = darkMode ? @"\bg{black}\fg{white}" : @"\bg{white}\fg{black}";
17+
var query = WebUtility.UrlEncode(@"\small\dpi{300}" + colors + latex);
18+
var url = $"https://latex.codecogs.com/png.image?{query}";
19+
using var client = httpFactory.CreateClient();
20+
using var response = await client.GetAsync(url);
21+
22+
if (response.IsSuccessStatusCode)
23+
{
24+
using var image = Image.Load<Rgba32>(await response.Content.ReadAsStreamAsync());
25+
using var ms = new MemoryStream();
26+
image.SaveAsPng(ms);
27+
var base64 = Convert.ToBase64String(ms.ToArray());
28+
return
29+
$"""
4230
![{latex}](
4331
data:image/png;base64,{base64}
4432
)
4533
""";
46-
}
47-
else
48-
{
49-
return
50-
$"""
34+
}
35+
else
36+
{
37+
return
38+
$"""
5139
```latex
5240
{latex}
5341
```
5442
> {response.ReasonPhrase}
5543
""";
56-
}
57-
}
58-
}
44+
}
45+
});
46+
47+
await builder.Build().RunAsync();

src/Smith/McpExtensions.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Text.Json;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using ModelContextProtocol.Server;
4+
5+
namespace Smith;
6+
7+
/// <summary>
8+
/// Usability extensions for working with MCP.
9+
/// </summary>
10+
public static class McpExtensions
11+
{
12+
extension(IMcpServerBuilder builder)
13+
{
14+
/// <summary>
15+
/// Registers a specific method as a server tool.
16+
/// </summary>
17+
public IMcpServerBuilder WithTool(Delegate tool, JsonSerializerOptions? options = null)
18+
{
19+
builder.Services.AddSingleton(services
20+
=> McpServerTool.Create(tool, new() { Services = services, SerializerOptions = options }));
21+
22+
return builder;
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)