Updating to align with quickstart sample (#221)
This commit is contained in:
parent
0e679f9697
commit
27c1519f01
2 changed files with 36 additions and 54 deletions
|
|
@ -1384,7 +1384,7 @@ cd QuickstartClient
|
||||||
|
|
||||||
Then, add the required dependencies to your project:
|
Then, add the required dependencies to your project:
|
||||||
```bash
|
```bash
|
||||||
dotnet add package ModelContextProtocol --preview
|
dotnet add package ModelContextProtocol --prerelease
|
||||||
dotnet add package Anthropic.SDK
|
dotnet add package Anthropic.SDK
|
||||||
dotnet add package Microsoft.Extensions.Hosting
|
dotnet add package Microsoft.Extensions.Hosting
|
||||||
```
|
```
|
||||||
|
|
@ -1423,10 +1423,10 @@ var (command, arguments) = args switch
|
||||||
_ => throw new NotSupportedException("An unsupported server script was provided. Supported scripts are .py, .js, or .csproj")
|
_ => throw new NotSupportedException("An unsupported server script was provided. Supported scripts are .py, .js, or .csproj")
|
||||||
};
|
};
|
||||||
|
|
||||||
var mcpClient = await McpClientFactory.CreateAsync(new()
|
await using var mcpClient = await McpClientFactory.CreateAsync(new()
|
||||||
{
|
{
|
||||||
Id = "demo-client",
|
Id = "demo-server",
|
||||||
Name = "Demo Client",
|
Name = "Demo Server",
|
||||||
TransportType = TransportTypes.StdIo,
|
TransportType = TransportTypes.StdIo,
|
||||||
TransportOptions = new()
|
TransportOptions = new()
|
||||||
{
|
{
|
||||||
|
|
@ -1455,7 +1455,7 @@ This configures a MCP client that will connect to a server that is provided as a
|
||||||
Now let's add the core functionality for processing queries and handling tool calls:
|
Now let's add the core functionality for processing queries and handling tool calls:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
IChatClient anthropicClient = new AnthropicClient(new APIAuthentication(builder.Configuration["ANTHROPIC_API_KEY"]))
|
using IChatClient anthropicClient = new AnthropicClient(new APIAuthentication(builder.Configuration["ANTHROPIC_API_KEY"]))
|
||||||
.Messages
|
.Messages
|
||||||
.AsBuilder()
|
.AsBuilder()
|
||||||
.UseFunctionInvocation()
|
.UseFunctionInvocation()
|
||||||
|
|
@ -1465,7 +1465,7 @@ var options = new ChatOptions
|
||||||
{
|
{
|
||||||
MaxOutputTokens = 1000,
|
MaxOutputTokens = 1000,
|
||||||
ModelId = "claude-3-5-sonnet-20241022",
|
ModelId = "claude-3-5-sonnet-20241022",
|
||||||
Tools = [.. tools.Cast<AITool>()]
|
Tools = [.. tools]
|
||||||
};
|
};
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
|
@ -1484,16 +1484,14 @@ while (true)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var response = await anthropicClient.GetResponseAsync(query, options);
|
var response = anthropicClient.GetStreamingResponseAsync(query, options);
|
||||||
|
|
||||||
foreach (var message in response.Messages)
|
await foreach (var message in response)
|
||||||
{
|
{
|
||||||
Console.WriteLine(message.Text);
|
Console.Write(message.Text);
|
||||||
}
|
}
|
||||||
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
anthropicClient.Dispose();
|
|
||||||
await mcpClient.DisposeAsync();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Key Components Explained
|
## Key Components Explained
|
||||||
|
|
|
||||||
|
|
@ -1450,7 +1450,7 @@ After creating the project, add NuGet package for the Model Context Protocol SDK
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Add the Model Context Protocol SDK NuGet package
|
# Add the Model Context Protocol SDK NuGet package
|
||||||
dotnet add package ModelContextProtocol --preview
|
dotnet add package ModelContextProtocol --prerelease
|
||||||
# Add the .NET Hosting NuGet package
|
# Add the .NET Hosting NuGet package
|
||||||
dotnet add package Microsoft.Extensions.Hosting
|
dotnet add package Microsoft.Extensions.Hosting
|
||||||
```
|
```
|
||||||
|
|
@ -1461,14 +1461,24 @@ Now let’s dive into building your server.
|
||||||
Open the `Program.cs` file in your project and replace its contents with the following code:
|
Open the `Program.cs` file in your project and replace its contents with the following code:
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using ModelContextProtocol;
|
using ModelContextProtocol;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
|
||||||
var builder = Host.CreateEmptyApplicationBuilder(settings: null);
|
var builder = Host.CreateEmptyApplicationBuilder(settings: null);
|
||||||
|
|
||||||
builder.Services.AddMcpServer()
|
builder.Services.AddMcpServer()
|
||||||
.WithStdioServerTransport()
|
.WithStdioServerTransport()
|
||||||
.WithToolsFromAssembly();
|
.WithToolsFromAssembly();
|
||||||
|
|
||||||
|
builder.Services.AddSingleton(_ =>
|
||||||
|
{
|
||||||
|
var client = new HttpClient() { BaseAddress = new Uri("https://api.weather.gov") };
|
||||||
|
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("weather-tool", "1.0"));
|
||||||
|
return client;
|
||||||
|
});
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
await app.RunAsync();
|
await app.RunAsync();
|
||||||
|
|
@ -1485,7 +1495,7 @@ Next, define a class with the tool execution handlers for querying and convertin
|
||||||
```csharp
|
```csharp
|
||||||
using ModelContextProtocol.Server;
|
using ModelContextProtocol.Server;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Json;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace QuickstartWeatherServer.Tools;
|
namespace QuickstartWeatherServer.Tools;
|
||||||
|
|
@ -1495,14 +1505,10 @@ public static class WeatherTools
|
||||||
{
|
{
|
||||||
[McpServerTool, Description("Get weather alerts for a US state.")]
|
[McpServerTool, Description("Get weather alerts for a US state.")]
|
||||||
public static async Task<string> GetAlerts(
|
public static async Task<string> GetAlerts(
|
||||||
|
HttpClient client,
|
||||||
[Description("The US state to get alerts for.")] string state)
|
[Description("The US state to get alerts for.")] string state)
|
||||||
{
|
{
|
||||||
using HttpClient client = GetWeatherClient();
|
var jsonElement = await client.GetFromJsonAsync<JsonElement>($"/alerts/active/area/{state}");
|
||||||
|
|
||||||
var response = await client.GetAsync($"/alerts/active/area/{state}");
|
|
||||||
|
|
||||||
var json = await response.Content.ReadAsStringAsync();
|
|
||||||
var jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
|
|
||||||
var alerts = jsonElement.GetProperty("features").EnumerateArray();
|
var alerts = jsonElement.GetProperty("features").EnumerateArray();
|
||||||
|
|
||||||
if (!alerts.Any())
|
if (!alerts.Any())
|
||||||
|
|
@ -1510,56 +1516,34 @@ public static class WeatherTools
|
||||||
return "No active alerts for this state.";
|
return "No active alerts for this state.";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the alerts and return a formatted string
|
return string.Join("\n--\n", alerts.Select(alert =>
|
||||||
var alertMessages = new List<string>();
|
|
||||||
foreach (var alert in alerts)
|
|
||||||
{
|
{
|
||||||
JsonElement properties = alert.GetProperty("properties");
|
JsonElement properties = alert.GetProperty("properties");
|
||||||
alertMessages.Add($"""
|
return $"""
|
||||||
Event: {properties.GetProperty("event").GetString()}
|
Event: {properties.GetProperty("event").GetString()}
|
||||||
Area: {properties.GetProperty("areaDesc").GetString()}
|
Area: {properties.GetProperty("areaDesc").GetString()}
|
||||||
Severity: {properties.GetProperty("severity").GetString()}
|
Severity: {properties.GetProperty("severity").GetString()}
|
||||||
Description: {properties.GetProperty("description").GetString()}
|
Description: {properties.GetProperty("description").GetString()}
|
||||||
Instruction: {properties.GetProperty("instruction").GetString()}
|
Instruction: {properties.GetProperty("instruction").GetString()}
|
||||||
""");
|
""";
|
||||||
}
|
}));
|
||||||
return string.Join("\n---\n", alertMessages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[McpServerTool, Description("Get weather forecast for a location.")]
|
[McpServerTool, Description("Get weather forecast for a location.")]
|
||||||
public static async Task<string> GetForecast(
|
public static async Task<string> GetForecast(
|
||||||
|
HttpClient client,
|
||||||
[Description("Latitude of the location.")] double latitude,
|
[Description("Latitude of the location.")] double latitude,
|
||||||
[Description("Longitude of the location.")] double longitude)
|
[Description("Longitude of the location.")] double longitude)
|
||||||
{
|
{
|
||||||
using HttpClient client = GetWeatherClient();
|
var jsonElement = await client.GetFromJsonAsync<JsonElement>($"/points/{latitude},{longitude}");
|
||||||
var response = await client.GetAsync($"/points/{latitude},{longitude}");
|
|
||||||
if (!response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
return "Failed to retrieve forecast.";
|
|
||||||
}
|
|
||||||
|
|
||||||
var json = await response.Content.ReadAsStringAsync();
|
|
||||||
var jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
|
|
||||||
var periods = jsonElement.GetProperty("properties").GetProperty("periods").EnumerateArray();
|
var periods = jsonElement.GetProperty("properties").GetProperty("periods").EnumerateArray();
|
||||||
// Process the forecast and return a formatted string
|
|
||||||
var forecastMessages = new List<string>();
|
|
||||||
foreach (var period in periods)
|
|
||||||
{
|
|
||||||
forecastMessages.Add($"""
|
|
||||||
{period.GetProperty("name").GetString()}
|
|
||||||
Temperature: {period.GetProperty("temperature").GetInt32()}°F
|
|
||||||
Wind: {period.GetProperty("windSpeed").GetString()} {period.GetProperty("windDirection").GetString()}
|
|
||||||
Forecast: {period.GetProperty("detailedForecast").GetString()}
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
return string.Join("\n---\n", forecastMessages);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HttpClient GetWeatherClient()
|
return string.Join("\n---\n", periods.Select(period => $"""
|
||||||
{
|
{period.GetProperty("name").GetString()}
|
||||||
var client = new HttpClient() { BaseAddress = new Uri("https://api.weather.gov") };
|
Temperature: {period.GetProperty("temperature").GetInt32()}°F
|
||||||
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("weather-tool", "1.0"));
|
Wind: {period.GetProperty("windSpeed").GetString()} {period.GetProperty("windDirection").GetString()}
|
||||||
return client;
|
Forecast: {period.GetProperty("detailedForecast").GetString()}
|
||||||
|
"""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue