Skip to content
This repository was archived by the owner on Apr 8, 2025. It is now read-only.

Updating to align with quickstart sample #221

Merged
merged 1 commit into from
Mar 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions quickstart/client.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1384,7 +1384,7 @@ cd QuickstartClient

Then, add the required dependencies to your project:
```bash
dotnet add package ModelContextProtocol --preview
dotnet add package ModelContextProtocol --prerelease
dotnet add package Anthropic.SDK
dotnet add package Microsoft.Extensions.Hosting
```
Expand Down Expand Up @@ -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")
};

var mcpClient = await McpClientFactory.CreateAsync(new()
await using var mcpClient = await McpClientFactory.CreateAsync(new()
{
Id = "demo-client",
Name = "Demo Client",
Id = "demo-server",
Name = "Demo Server",
TransportType = TransportTypes.StdIo,
TransportOptions = new()
{
Expand Down Expand Up @@ -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:

```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
.AsBuilder()
.UseFunctionInvocation()
Expand All @@ -1465,7 +1465,7 @@ var options = new ChatOptions
{
MaxOutputTokens = 1000,
ModelId = "claude-3-5-sonnet-20241022",
Tools = [.. tools.Cast<AITool>()]
Tools = [.. tools]
};

while (true)
Expand All @@ -1484,16 +1484,14 @@ while (true)
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
Expand Down
68 changes: 26 additions & 42 deletions quickstart/server.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1450,7 +1450,7 @@ After creating the project, add NuGet package for the Model Context Protocol SDK

```bash
# Add the Model Context Protocol SDK NuGet package
dotnet add package ModelContextProtocol --preview
dotnet add package ModelContextProtocol --prerelease
# Add the .NET Hosting NuGet package
dotnet add package Microsoft.Extensions.Hosting
```
Expand All @@ -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:

```csharp
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using ModelContextProtocol;
using System.Net.Http.Headers;

var builder = Host.CreateEmptyApplicationBuilder(settings: null);

builder.Services.AddMcpServer()
.WithStdioServerTransport()
.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();

await app.RunAsync();
Expand All @@ -1485,7 +1495,7 @@ Next, define a class with the tool execution handlers for querying and convertin
```csharp
using ModelContextProtocol.Server;
using System.ComponentModel;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;

namespace QuickstartWeatherServer.Tools;
Expand All @@ -1495,71 +1505,45 @@ public static class WeatherTools
{
[McpServerTool, Description("Get weather alerts for a US state.")]
public static async Task<string> GetAlerts(
HttpClient client,
[Description("The US state to get alerts for.")] string state)
{
using HttpClient client = GetWeatherClient();

var response = await client.GetAsync($"/alerts/active/area/{state}");

var json = await response.Content.ReadAsStringAsync();
var jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
var jsonElement = await client.GetFromJsonAsync<JsonElement>($"/alerts/active/area/{state}");
var alerts = jsonElement.GetProperty("features").EnumerateArray();

if (!alerts.Any())
{
return "No active alerts for this state.";
}

// Process the alerts and return a formatted string
var alertMessages = new List<string>();
foreach (var alert in alerts)
return string.Join("\n--\n", alerts.Select(alert =>
{
JsonElement properties = alert.GetProperty("properties");
alertMessages.Add($"""
return $"""
Event: {properties.GetProperty("event").GetString()}
Area: {properties.GetProperty("areaDesc").GetString()}
Severity: {properties.GetProperty("severity").GetString()}
Description: {properties.GetProperty("description").GetString()}
Instruction: {properties.GetProperty("instruction").GetString()}
""");
}
return string.Join("\n---\n", alertMessages);
""";
}));
}

[McpServerTool, Description("Get weather forecast for a location.")]
public static async Task<string> GetForecast(
HttpClient client,
[Description("Latitude of the location.")] double latitude,
[Description("Longitude of the location.")] double longitude)
{
using HttpClient client = GetWeatherClient();
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 jsonElement = await client.GetFromJsonAsync<JsonElement>($"/points/{latitude},{longitude}");
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()
{
var client = new HttpClient() { BaseAddress = new Uri("https://api.weather.gov") };
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("weather-tool", "1.0"));
return client;
return string.Join("\n---\n", periods.Select(period => $"""
{period.GetProperty("name").GetString()}
Temperature: {period.GetProperty("temperature").GetInt32()}°F
Wind: {period.GetProperty("windSpeed").GetString()} {period.GetProperty("windDirection").GetString()}
Forecast: {period.GetProperty("detailedForecast").GetString()}
"""));
}
}
```
Expand Down