Skip to content

Commit 4242aed

Browse files
committed
Fix samples again post merge
1 parent ba5aa83 commit 4242aed

5 files changed

Lines changed: 91 additions & 22 deletions

File tree

samples/AspNetCoreMcpServer/Program.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
using OpenTelemetry.Trace;
44
using AspNetCoreMcpServer.Tools;
55
using AspNetCoreMcpServer.Resources;
6+
using System.Net.Http.Headers;
67

78
var builder = WebApplication.CreateBuilder(args);
89
builder.Services.AddMcpServer()
910
.WithHttpTransport()
1011
.WithTools<EchoTool>()
1112
.WithTools<SampleLlmTool>()
12-
.WithResources<SimpleResourceType>()
13-
.WithTools<WeatherTools>();
13+
.WithTools<WeatherTools>()
14+
.WithResources<SimpleResourceType>();
1415

1516
builder.Services.AddOpenTelemetry()
1617
.WithTracing(b => b.AddSource("*")
@@ -21,7 +22,14 @@
2122
.AddHttpClientInstrumentation())
2223
.WithLogging()
2324
.UseOtlpExporter();
24-
builder.Services.AddHttpClient();
25+
26+
// Configure HttpClientFactory for weather.gov API
27+
builder.Services.AddHttpClient("WeatherApi", client =>
28+
{
29+
client.BaseAddress = new Uri("https://api.weather.gov");
30+
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("weather-tool", "1.0"));
31+
});
32+
2533
var app = builder.Build();
2634

2735
app.MapMcp();
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using ModelContextProtocol;
2+
using ModelContextProtocol.Server;
3+
using System.ComponentModel;
4+
using System.Globalization;
5+
using System.Text.Json;
6+
7+
namespace AspNetCoreMcpServer.Tools;
8+
9+
[McpServerToolType]
10+
public sealed class WeatherTools
11+
{
12+
private readonly IHttpClientFactory _httpClientFactory;
13+
14+
public WeatherTools(IHttpClientFactory httpClientFactory)
15+
{
16+
_httpClientFactory = httpClientFactory;
17+
}
18+
19+
[McpServerTool, Description("Get weather alerts for a US state.")]
20+
public async Task<string> GetAlerts(
21+
[Description("The US state to get alerts for. Use the 2 letter abbreviation for the state (e.g. NY).")] string state)
22+
{
23+
var client = _httpClientFactory.CreateClient("WeatherApi");
24+
using var responseStream = await client.GetStreamAsync($"/alerts/active/area/{state}");
25+
using var jsonDocument = await JsonDocument.ParseAsync(responseStream)
26+
?? throw new McpException("No JSON returned from alerts endpoint");
27+
28+
var alerts = jsonDocument.RootElement.GetProperty("features").EnumerateArray();
29+
30+
if (!alerts.Any())
31+
{
32+
return "No active alerts for this state.";
33+
}
34+
35+
return string.Join("\n--\n", alerts.Select(alert =>
36+
{
37+
JsonElement properties = alert.GetProperty("properties");
38+
return $"""
39+
Event: {properties.GetProperty("event").GetString()}
40+
Area: {properties.GetProperty("areaDesc").GetString()}
41+
Severity: {properties.GetProperty("severity").GetString()}
42+
Description: {properties.GetProperty("description").GetString()}
43+
Instruction: {properties.GetProperty("instruction").GetString()}
44+
""";
45+
}));
46+
}
47+
48+
[McpServerTool, Description("Get weather forecast for a location.")]
49+
public async Task<string> GetForecast(
50+
[Description("Latitude of the location.")] double latitude,
51+
[Description("Longitude of the location.")] double longitude)
52+
{
53+
var client = _httpClientFactory.CreateClient("WeatherApi");
54+
var pointUrl = string.Create(CultureInfo.InvariantCulture, $"/points/{latitude},{longitude}");
55+
56+
using var locationResponseStream = await client.GetStreamAsync(pointUrl);
57+
using var locationDocument = await JsonDocument.ParseAsync(locationResponseStream);
58+
var forecastUrl = locationDocument?.RootElement.GetProperty("properties").GetProperty("forecast").GetString()
59+
?? throw new McpException($"No forecast URL provided by {client.BaseAddress}points/{latitude},{longitude}");
60+
61+
using var forecastResponseStream = await client.GetStreamAsync(forecastUrl);
62+
using var forecastDocument = await JsonDocument.ParseAsync(forecastResponseStream);
63+
var periods = forecastDocument?.RootElement.GetProperty("properties").GetProperty("periods").EnumerateArray()
64+
?? throw new McpException("No JSON returned from forecast endpoint");
65+
66+
return string.Join("\n---\n", periods.Select(period => $"""
67+
{period.GetProperty("name").GetString()}
68+
Temperature: {period.GetProperty("temperature").GetInt32()}°F
69+
Wind: {period.GetProperty("windSpeed").GetString()} {period.GetProperty("windDirection").GetString()}
70+
Forecast: {period.GetProperty("detailedForecast").GetString()}
71+
"""));
72+
}
73+
}

samples/QuickstartClient/Program.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
IClientTransport? clientTransport = null;
1818
if (command == "http")
1919
{
20-
// make sure AspNetCoreSseServer is running
21-
clientTransport = new SseClientTransport(new SseClientTransportOptions { Endpoint = new Uri("https://localhost:7133"), TransportMode = HttpTransportMode.StreamableHttp});
20+
// make sure AspNetCoreMcpServer is running
21+
clientTransport = new SseClientTransport(new SseClientTransportOptions { Endpoint = new Uri("http://localhost:3001"), TransportMode = HttpTransportMode.StreamableHttp});
2222
}
2323
else
2424
{
@@ -73,7 +73,6 @@
7373
Console.WriteLine();
7474

7575
PromptForInput();
76-
7776
}
7877

7978
static void PromptForInput()
@@ -91,9 +90,9 @@ static void PromptForInput()
9190
/// <remarks>
9291
/// This method uses the file extension of the first argument to determine the command, if it's py, it'll run python,
9392
/// if it's js, it'll run node, if it's a directory or a csproj file, it'll run dotnet.
94-
///
93+
///
9594
/// If no arguments are provided, it defaults to running the QuickstartWeatherServer project from the current repo.
96-
///
95+
///
9796
/// This method would only be required if you're creating a generic client, such as we use for the quickstart.
9897
/// </remarks>
9998
static (string command, string[] arguments) GetCommandAndArguments(string[] args)

samples/QuickstartClient/Properties/launchSettings.json

Lines changed: 0 additions & 8 deletions
This file was deleted.

samples/QuickstartWeatherServer/Program.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,8 @@
1515
options.LogToStandardErrorThreshold = LogLevel.Trace;
1616
});
1717

18-
builder.Services.AddSingleton(_ =>
19-
{
20-
var client = new HttpClient { BaseAddress = new Uri("https://api.weather.gov") };
21-
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("weather-tool", "1.0"));
22-
return client;
23-
});
18+
using var httpClient = new HttpClient { BaseAddress = new Uri("https://api.weather.gov") };
19+
httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("weather-tool", "1.0"));
20+
builder.Services.AddSingleton(httpClient);
2421

2522
await builder.Build().RunAsync();

0 commit comments

Comments
 (0)