diff --git a/McpStudy.Core/EchoTool.cs b/McpStudy.Core/EchoTool.cs deleted file mode 100644 index 9f892f7..0000000 --- a/McpStudy.Core/EchoTool.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.ComponentModel; - -using ModelContextProtocol.Server; - -namespace McpStudy.Core -{ - [McpServerToolType] - public static class EchoTool - { - [McpServerTool, DisplayName("EchoServer"), Description("回传原消息给客户端!")] - public static string Echo(string message) - { - Console.WriteLine($"Echo: {message}"); - - System.IO.File.AppendAllText("Mcplog.txt", $"Echo: {message}\n"); - - return $"hello {message}"; - } - } -} diff --git a/McpStudy.Core/GlobalUsing.cs b/McpStudy.Core/GlobalUsing.cs index e02abfc..7110a57 100644 --- a/McpStudy.Core/GlobalUsing.cs +++ b/McpStudy.Core/GlobalUsing.cs @@ -1 +1,19 @@ - +global using System.Linq; +global using System.ComponentModel; + +global using Microsoft.Net.Http.Headers; +global using Microsoft.Extensions.Hosting; +global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.DependencyInjection; + +global using ModelContextProtocol; +global using ModelContextProtocol.Protocol; +global using ModelContextProtocol.Client; +global using ModelContextProtocol.Server; +global using ModelContextProtocol.SemanticKernel; +global using ModelContextProtocol.AspNetCore; +global using ModelContextProtocolServer; +global using ModelContextProtocolServer.Sse; +global using ModelContextProtocolServer.Stdio; + + diff --git a/McpStudy.Core/Server/EchoTools.cs b/McpStudy.Core/Server/EchoTools.cs new file mode 100644 index 0000000..986c2ef --- /dev/null +++ b/McpStudy.Core/Server/EchoTools.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace McpStudy.Core +{ + public class EchoTools + { + + } +} diff --git a/McpStudy.Core/Server/TimeTools.cs b/McpStudy.Core/Server/TimeTools.cs new file mode 100644 index 0000000..76dc57d --- /dev/null +++ b/McpStudy.Core/Server/TimeTools.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace McpStudy.Core; + +[McpServerToolType] +public static class TimeTools +{ + [McpServerTool, Description("Get the current time for a city")] + public static string GetCurrentTime(string city) + { + var message = $"It is {DateTime.Now.Hour}:{DateTime.Now.Minute} in {city}."; + return message; + } +} diff --git a/McpStudy.Core/Server/WeatherTools.cs b/McpStudy.Core/Server/WeatherTools.cs new file mode 100644 index 0000000..d0c8f5f --- /dev/null +++ b/McpStudy.Core/Server/WeatherTools.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using System.Text.Json; +using System.Net.Http; +using System.Net.Http.Json; +using System.Globalization; + +namespace McpStudy.Core; + +[McpServerToolType] +public sealed class WeatherTools +{ + [McpServerTool, Description("Get weather alerts for a US state.")] + public static async Task GetAlerts( + HttpClient client, + [Description("The US state to get alerts for. Use the 2 letter abbreviation for the state (e.g. NY).")] string state) + { + using var jsonDocument = await ReadJsonDocumentAsync(client,$"/alerts/active/area/{state}"); + var jsonElement = jsonDocument.RootElement; + var alerts = jsonElement.GetProperty("features").EnumerateArray(); + + if (!alerts.Any()) + { + return "No active alerts for this state."; + } + + return string.Join("\n--\n", alerts.Select(alert => + { + JsonElement properties = alert.GetProperty("properties"); + 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()} + """; + })); + } + + [McpServerTool, Description("Get weather forecast for a location.")] + public static async Task GetForecast( + HttpClient client, + [Description("Latitude of the location.")] double latitude, + [Description("Longitude of the location.")] double longitude) + { + var pointUrl = string.Create(CultureInfo.InvariantCulture, $"/points/{latitude},{longitude}"); + using var jsonDocument = await ReadJsonDocumentAsync(client,pointUrl); + var forecastUrl = jsonDocument.RootElement.GetProperty("properties").GetProperty("forecast").GetString() + ?? throw new Exception($"No forecast URL provided by {client.BaseAddress}points/{latitude},{longitude}"); + + using var forecastDocument = await ReadJsonDocumentAsync(client,forecastUrl); + var periods = forecastDocument.RootElement.GetProperty("properties").GetProperty("periods").EnumerateArray(); + + 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()} + """)); + } + + public static async Task ReadJsonDocumentAsync(HttpClient client, string requestUri) + { + using var response = await client.GetAsync(requestUri); + response.EnsureSuccessStatusCode(); + return await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync()); + } +} + diff --git a/McpStudy.McpClient/GlobalUsing.cs b/McpStudy.McpClient/GlobalUsing.cs new file mode 100644 index 0000000..7110a57 --- /dev/null +++ b/McpStudy.McpClient/GlobalUsing.cs @@ -0,0 +1,19 @@ +global using System.Linq; +global using System.ComponentModel; + +global using Microsoft.Net.Http.Headers; +global using Microsoft.Extensions.Hosting; +global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.DependencyInjection; + +global using ModelContextProtocol; +global using ModelContextProtocol.Protocol; +global using ModelContextProtocol.Client; +global using ModelContextProtocol.Server; +global using ModelContextProtocol.SemanticKernel; +global using ModelContextProtocol.AspNetCore; +global using ModelContextProtocolServer; +global using ModelContextProtocolServer.Sse; +global using ModelContextProtocolServer.Stdio; + + diff --git a/McpStudy.McpClient/McpStudy.McpClient.csproj b/McpStudy.McpClient/McpStudy.McpClient.csproj index 0fd40cf..ca7fed3 100644 --- a/McpStudy.McpClient/McpStudy.McpClient.csproj +++ b/McpStudy.McpClient/McpStudy.McpClient.csproj @@ -7,6 +7,14 @@ enable + + + + + + + + diff --git a/McpStudy.McpClient/Program.cs b/McpStudy.McpClient/Program.cs index b4f50f4..0d6174f 100644 --- a/McpStudy.McpClient/Program.cs +++ b/McpStudy.McpClient/Program.cs @@ -1,10 +1,13 @@ -namespace McpStudy.McpClient +using System.Diagnostics; +using System.Threading.Tasks; + +namespace McpStudy.McpClient; +internal class Program { - internal class Program + static async Task Main(string[] args) { - static void Main(string[] args) - { - Console.WriteLine("调用MCP服务器示例"); - } + Console.WriteLine("调用MCP服务器示例"); + + await Task.CompletedTask; } } diff --git a/McpStudy.McpServerStdio/GlobalUsing.cs b/McpStudy.McpServerStdio/GlobalUsing.cs new file mode 100644 index 0000000..7110a57 --- /dev/null +++ b/McpStudy.McpServerStdio/GlobalUsing.cs @@ -0,0 +1,19 @@ +global using System.Linq; +global using System.ComponentModel; + +global using Microsoft.Net.Http.Headers; +global using Microsoft.Extensions.Hosting; +global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.DependencyInjection; + +global using ModelContextProtocol; +global using ModelContextProtocol.Protocol; +global using ModelContextProtocol.Client; +global using ModelContextProtocol.Server; +global using ModelContextProtocol.SemanticKernel; +global using ModelContextProtocol.AspNetCore; +global using ModelContextProtocolServer; +global using ModelContextProtocolServer.Sse; +global using ModelContextProtocolServer.Stdio; + + diff --git a/McpStudy.McpServerStdio/Program.cs b/McpStudy.McpServerStdio/Program.cs index 9ccee04..bd9b5aa 100644 --- a/McpStudy.McpServerStdio/Program.cs +++ b/McpStudy.McpServerStdio/Program.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.DependencyInjection; using ModelContextProtocol.Server; +using System.Runtime.CompilerServices; namespace McpStudy.McpServerStdio { @@ -23,7 +24,8 @@ namespace McpStudy.McpServerStdio builder.Services .AddMcpServer() .WithStdioServerTransport() - .WithToolsFromAssembly(); + .WithToolsFromAssembly(typeof(McpStudy.Core.TimeTools).Assembly) + .WithToolsFromAssembly(typeof(McpStudy.McpServerStdio.Program).Assembly); await builder.Build().RunAsync(); } @@ -38,15 +40,3 @@ namespace McpStudy.McpServerStdio } } } - -[McpServerToolType] -public static class TimeTool -{ - [McpServerTool, Description("Get the current time for a city")] - public static string GetCurrentTime(string city) - { - var message = $"It is {DateTime.Now.Hour}:{DateTime.Now.Minute} in {city}."; - return message; - } - -} diff --git a/McpStudy.UnitTest/McpStudy.UnitTest.csproj b/McpStudy.UnitTest/McpStudy.UnitTest.csproj index 5b9d2c3..2c070d4 100644 --- a/McpStudy.UnitTest/McpStudy.UnitTest.csproj +++ b/McpStudy.UnitTest/McpStudy.UnitTest.csproj @@ -16,6 +16,9 @@ + + +