Skip to content

Commit 64da739

Browse files
committed
Convert EverythingServer to use Streamable HTTP
1 parent 70960e1 commit 64da739

File tree

5 files changed

+82
-33
lines changed

5 files changed

+82
-33
lines changed
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
44
<TargetFramework>net9.0</TargetFramework>
@@ -8,14 +8,13 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.Extensions.Hosting" />
1211
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" />
1312
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
1413
<PackageReference Include="OpenTelemetry.Instrumentation.Http" />
1514
</ItemGroup>
1615

1716
<ItemGroup>
18-
<ProjectReference Include="..\..\src\ModelContextProtocol\ModelContextProtocol.csproj" />
17+
<ProjectReference Include="..\..\src\ModelContextProtocol.AspNetCore\ModelContextProtocol.AspNetCore.csproj" />
1918
</ItemGroup>
2019

2120
</Project>

samples/EverythingServer/LoggingUpdateMessageSender.cs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
using Microsoft.Extensions.Hosting;
2-
using ModelContextProtocol;
1+
using ModelContextProtocol;
32
using ModelContextProtocol.Protocol;
43
using ModelContextProtocol.Server;
54

65
namespace EverythingServer;
76

8-
public class LoggingUpdateMessageSender(IMcpServer server, Func<LoggingLevel> getMinLevel) : BackgroundService
7+
public class LoggingUpdateMessageSender(IServiceProvider serviceProvider, Func<LoggingLevel> getMinLevel) : BackgroundService
98
{
109
readonly Dictionary<LoggingLevel, string> _loggingLevelMap = new()
1110
{
@@ -21,19 +20,35 @@ public class LoggingUpdateMessageSender(IMcpServer server, Func<LoggingLevel> ge
2120

2221
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
2322
{
23+
// Wait for the application to fully start before trying to access the MCP server
24+
await Task.Delay(2000, stoppingToken);
25+
2426
while (!stoppingToken.IsCancellationRequested)
2527
{
26-
var newLevel = (LoggingLevel)Random.Shared.Next(_loggingLevelMap.Count);
27-
28-
var message = new
28+
try
29+
{
30+
// Try to get the server from the service provider
31+
var server = serviceProvider.GetService<IMcpServer>();
32+
if (server != null)
2933
{
30-
Level = newLevel.ToString().ToLower(),
31-
Data = _loggingLevelMap[newLevel],
32-
};
34+
var newLevel = (LoggingLevel)Random.Shared.Next(_loggingLevelMap.Count);
3335

34-
if (newLevel > getMinLevel())
36+
var message = new
37+
{
38+
Level = newLevel.ToString().ToLower(),
39+
Data = _loggingLevelMap[newLevel],
40+
};
41+
42+
if (newLevel > getMinLevel())
43+
{
44+
await server.SendNotificationAsync("notifications/message", message, cancellationToken: stoppingToken);
45+
}
46+
}
47+
}
48+
catch (Exception ex)
3549
{
36-
await server.SendNotificationAsync("notifications/message", message, cancellationToken: stoppingToken);
50+
// Log the exception but don't crash the service
51+
Console.WriteLine($"Error in LoggingUpdateMessageSender: {ex.Message}");
3752
}
3853

3954
await Task.Delay(15000, stoppingToken);

samples/EverythingServer/Program.cs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
using EverythingServer.Resources;
44
using EverythingServer.Tools;
55
using Microsoft.Extensions.AI;
6-
using Microsoft.Extensions.DependencyInjection;
7-
using Microsoft.Extensions.Hosting;
8-
using Microsoft.Extensions.Logging;
96
using ModelContextProtocol;
7+
using ModelContextProtocol.AspNetCore;
108
using ModelContextProtocol.Protocol;
119
using ModelContextProtocol.Server;
1210
using OpenTelemetry;
@@ -15,19 +13,14 @@
1513
using OpenTelemetry.Resources;
1614
using OpenTelemetry.Trace;
1715

18-
var builder = Host.CreateApplicationBuilder(args);
19-
builder.Logging.AddConsole(consoleLogOptions =>
20-
{
21-
// Configure all logs to go to stderr
22-
consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
23-
});
16+
var builder = WebApplication.CreateBuilder(args);
2417

2518
HashSet<string> subscriptions = [];
2619
var _minimumLoggingLevel = LoggingLevel.Debug;
2720

2821
builder.Services
2922
.AddMcpServer()
30-
.WithStdioServerTransport()
23+
.WithHttpTransport()
3124
.WithTools<AddTool>()
3225
.WithTools<AnnotatedMessageTool>()
3326
.WithTools<EchoTool>()
@@ -151,4 +144,10 @@ await ctx.Server.SampleAsync([
151144

152145
builder.Services.AddSingleton<Func<LoggingLevel>>(_ => () => _minimumLoggingLevel);
153146

154-
await builder.Build().RunAsync();
147+
var app = builder.Build();
148+
149+
app.UseHttpsRedirection();
150+
151+
app.MapMcp();
152+
153+
app.Run();
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"http": {
5+
"commandName": "Project",
6+
"dotnetRunMessages": true,
7+
"applicationUrl": "http://localhost:3001",
8+
"environmentVariables": {
9+
"ASPNETCORE_ENVIRONMENT": "Development",
10+
}
11+
},
12+
"https": {
13+
"commandName": "Project",
14+
"dotnetRunMessages": true,
15+
"applicationUrl": "https://localhost:7133;http://localhost:3001",
16+
"environmentVariables": {
17+
"ASPNETCORE_ENVIRONMENT": "Development",
18+
}
19+
}
20+
}
21+
}

samples/EverythingServer/SubscriptionMessageSender.cs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,35 @@
1-
using Microsoft.Extensions.Hosting;
2-
using ModelContextProtocol;
1+
using ModelContextProtocol;
32
using ModelContextProtocol.Server;
43

5-
internal class SubscriptionMessageSender(IMcpServer server, HashSet<string> subscriptions) : BackgroundService
4+
internal class SubscriptionMessageSender(IServiceProvider serviceProvider, HashSet<string> subscriptions) : BackgroundService
65
{
76
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
87
{
8+
// Wait for the application to fully start before trying to access the MCP server
9+
await Task.Delay(2000, stoppingToken);
10+
911
while (!stoppingToken.IsCancellationRequested)
1012
{
11-
foreach (var uri in subscriptions)
13+
try
1214
{
13-
await server.SendNotificationAsync("notifications/resource/updated",
14-
new
15+
// Try to get the server from the service provider
16+
var server = serviceProvider.GetService<IMcpServer>();
17+
if (server != null)
18+
{
19+
foreach (var uri in subscriptions)
1520
{
16-
Uri = uri,
17-
}, cancellationToken: stoppingToken);
21+
await server.SendNotificationAsync("notifications/resource/updated",
22+
new
23+
{
24+
Uri = uri,
25+
}, cancellationToken: stoppingToken);
26+
}
27+
}
28+
}
29+
catch (Exception ex)
30+
{
31+
// Log the exception but don't crash the service
32+
Console.WriteLine($"Error in SubscriptionMessageSender: {ex.Message}");
1833
}
1934

2035
await Task.Delay(5000, stoppingToken);

0 commit comments

Comments
 (0)