Skip to content

Commit fd56321

Browse files
Convert InMemoryTransport and QuickstartWeatherServer to file-based projects, delete FileBasedMcpServer
Co-authored-by: eiriktsarpalis <[email protected]>
1 parent 5644a98 commit fd56321

File tree

11 files changed

+176
-205
lines changed

11 files changed

+176
-205
lines changed

ModelContextProtocol.slnx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,9 @@
4343
<Project Path="samples/AspNetCoreMcpServer/AspNetCoreMcpServer.csproj" />
4444
<Project Path="samples/ChatWithTools/ChatWithTools.csproj" />
4545
<Project Path="samples/EverythingServer/EverythingServer.csproj" />
46-
<Project Path="samples/InMemoryTransport/InMemoryTransport.csproj" />
4746
<Project Path="samples/ProtectedMcpClient/ProtectedMcpClient.csproj" />
4847
<Project Path="samples/ProtectedMcpServer/ProtectedMcpServer.csproj" />
4948
<Project Path="samples/QuickstartClient/QuickstartClient.csproj" />
50-
<Project Path="samples/QuickstartWeatherServer/QuickstartWeatherServer.csproj" />
5149
<Project Path="samples/TestServerWithHosting/TestServerWithHosting.csproj" />
5250
</Folder>
5351
<Folder Name="/Solution Items/">

samples/FileBasedMcpServer/Program.cs

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

samples/FileBasedMcpServer/README.md

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

samples/InMemoryTransport/InMemoryTransport.csproj

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

samples/InMemoryTransport/Program.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using ModelContextProtocol.Client;
1+
#!/usr/bin/env -S dotnet run --
2+
#:project ../../src/ModelContextProtocol/ModelContextProtocol.csproj
3+
4+
using ModelContextProtocol.Client;
25
using ModelContextProtocol.Protocol;
36
using ModelContextProtocol.Server;
47
using System.IO.Pipelines;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# InMemoryTransport Sample
2+
3+
This sample demonstrates how to create an MCP client and server connected via an in-memory pipe, without using network sockets or stdio. This is useful for testing and embedding MCP servers directly in your application.
4+
5+
## Requirements
6+
7+
- .NET 8.0 SDK or later
8+
- No project file required!
9+
10+
## Running the Sample
11+
12+
Simply run the Program.cs file directly:
13+
14+
```bash
15+
dotnet run Program.cs
16+
```
17+
18+
Or on Unix-like systems, make the file executable:
19+
20+
```bash
21+
chmod +x Program.cs
22+
./Program.cs
23+
```
24+
25+
## What This Sample Shows
26+
27+
- Creating a server with `StreamServerTransport` over an in-memory pipe
28+
- Connecting a client using `StreamClientTransport` over the same pipe
29+
- Listing available tools from the server
30+
- Invoking tools on the server
31+
32+
The sample creates a simple "Echo" tool that echoes back the input message.
33+
34+
## Reference
35+
36+
- [File-Based Programs Tutorial](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/tutorials/file-based-programs)
37+
- [Model Context Protocol Specification](https://modelcontextprotocol.io/specification/)

samples/QuickstartWeatherServer/Program.cs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1+
#!/usr/bin/env -S dotnet run --
2+
#:package Microsoft.Extensions.Hosting
3+
#:project ../../src/ModelContextProtocol/ModelContextProtocol.csproj
4+
15
using Microsoft.Extensions.DependencyInjection;
26
using Microsoft.Extensions.Hosting;
37
using Microsoft.Extensions.Logging;
4-
using QuickstartWeatherServer.Tools;
8+
using ModelContextProtocol;
9+
using ModelContextProtocol.Server;
10+
using System.ComponentModel;
11+
using System.Globalization;
512
using System.Net.Http.Headers;
13+
using System.Text.Json;
614

715
var builder = Host.CreateApplicationBuilder(args);
816

@@ -20,3 +28,68 @@
2028
builder.Services.AddSingleton(httpClient);
2129

2230
await builder.Build().RunAsync();
31+
32+
// Weather Tools
33+
[McpServerToolType]
34+
file sealed class WeatherTools
35+
{
36+
[McpServerTool, Description("Get weather alerts for a US state.")]
37+
public static async Task<string> GetAlerts(
38+
HttpClient client,
39+
[Description("The US state to get alerts for. Use the 2 letter abbreviation for the state (e.g. NY).")] string state)
40+
{
41+
using var jsonDocument = await client.ReadJsonDocumentAsync($"/alerts/active/area/{state}");
42+
var jsonElement = jsonDocument.RootElement;
43+
var alerts = jsonElement.GetProperty("features").EnumerateArray();
44+
45+
if (!alerts.Any())
46+
{
47+
return "No active alerts for this state.";
48+
}
49+
50+
return string.Join("\n--\n", alerts.Select(alert =>
51+
{
52+
JsonElement properties = alert.GetProperty("properties");
53+
return $"""
54+
Event: {properties.GetProperty("event").GetString()}
55+
Area: {properties.GetProperty("areaDesc").GetString()}
56+
Severity: {properties.GetProperty("severity").GetString()}
57+
Description: {properties.GetProperty("description").GetString()}
58+
Instruction: {properties.GetProperty("instruction").GetString()}
59+
""";
60+
}));
61+
}
62+
63+
[McpServerTool, Description("Get weather forecast for a location.")]
64+
public static async Task<string> GetForecast(
65+
HttpClient client,
66+
[Description("Latitude of the location.")] double latitude,
67+
[Description("Longitude of the location.")] double longitude)
68+
{
69+
var pointUrl = string.Create(CultureInfo.InvariantCulture, $"/points/{latitude},{longitude}");
70+
using var locationDocument = await client.ReadJsonDocumentAsync(pointUrl);
71+
var forecastUrl = locationDocument.RootElement.GetProperty("properties").GetProperty("forecast").GetString()
72+
?? throw new McpException($"No forecast URL provided by {client.BaseAddress}points/{latitude},{longitude}");
73+
74+
using var forecastDocument = await client.ReadJsonDocumentAsync(forecastUrl);
75+
var periods = forecastDocument.RootElement.GetProperty("properties").GetProperty("periods").EnumerateArray();
76+
77+
return string.Join("\n---\n", periods.Select(period => $"""
78+
{period.GetProperty("name").GetString()}
79+
Temperature: {period.GetProperty("temperature").GetInt32()}°F
80+
Wind: {period.GetProperty("windSpeed").GetString()} {period.GetProperty("windDirection").GetString()}
81+
Forecast: {period.GetProperty("detailedForecast").GetString()}
82+
"""));
83+
}
84+
}
85+
86+
// HttpClient Extension Methods
87+
file static class HttpClientExt
88+
{
89+
public static async Task<JsonDocument> ReadJsonDocumentAsync(this HttpClient client, string requestUri)
90+
{
91+
using var response = await client.GetAsync(requestUri);
92+
response.EnsureSuccessStatusCode();
93+
return await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync());
94+
}
95+
}

samples/QuickstartWeatherServer/QuickstartWeatherServer.csproj

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# QuickstartWeatherServer Sample
2+
3+
This sample demonstrates how to create an MCP server that provides weather-related tools using the weather.gov API. This is a file-based program that runs without a traditional project file.
4+
5+
## Requirements
6+
7+
- .NET 8.0 SDK or later
8+
- No project file required!
9+
10+
## Running the Sample
11+
12+
Simply run the Program.cs file directly:
13+
14+
```bash
15+
dotnet run Program.cs
16+
```
17+
18+
Or on Unix-like systems, make the file executable:
19+
20+
```bash
21+
chmod +x Program.cs
22+
./Program.cs
23+
```
24+
25+
The server will start and listen for MCP messages on stdin/stdout (stdio transport).
26+
27+
## Available Tools
28+
29+
The server provides two weather tools:
30+
31+
1. **GetAlerts** - Get weather alerts for a US state (use 2-letter abbreviation like "NY")
32+
2. **GetForecast** - Get weather forecast for a location (requires latitude and longitude)
33+
34+
## Testing the Server
35+
36+
You can test the server using the QuickstartClient or any MCP-compatible client:
37+
38+
```bash
39+
# From the repository root
40+
dotnet run --project samples/QuickstartClient samples/QuickstartWeatherServer
41+
```
42+
43+
Or test with the MCP inspector:
44+
45+
```bash
46+
npx @modelcontextprotocol/inspector dotnet run samples/QuickstartWeatherServer/Program.cs
47+
```
48+
49+
## What This Sample Shows
50+
51+
- Creating an MCP server using `Host.CreateApplicationBuilder`
52+
- Registering tools with `WithTools<T>()`
53+
- Using dependency injection to provide HttpClient to tools
54+
- Configuring logging to stderr for MCP compatibility
55+
- Using file-scoped classes for tool implementations
56+
57+
## Reference
58+
59+
- [File-Based Programs Tutorial](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/tutorials/file-based-programs)
60+
- [Model Context Protocol Specification](https://modelcontextprotocol.io/specification/)
61+
- [Weather.gov API](https://www.weather.gov/documentation/services-web-api)

samples/QuickstartWeatherServer/Tools/HttpClientExt.cs

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

0 commit comments

Comments
 (0)