diff --git a/McpStudy.Core/Server/EchoTools.cs b/McpStudy.Core/Server/EchoTools.cs index 986c2ef..c78d6b9 100644 --- a/McpStudy.Core/Server/EchoTools.cs +++ b/McpStudy.Core/Server/EchoTools.cs @@ -6,8 +6,15 @@ using System.Threading.Tasks; namespace McpStudy.Core { + + [McpServerToolType] public class EchoTools { + [McpServerTool, Description("Echoes the input back to the client.")] + public static string Echo(string message) + { + return "hello " + message; + } } } diff --git a/McpStudy.Core/Server/TimeTools.cs b/McpStudy.Core/Server/TimeTools.cs index 76dc57d..a7bdf24 100644 --- a/McpStudy.Core/Server/TimeTools.cs +++ b/McpStudy.Core/Server/TimeTools.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace McpStudy.Core; [McpServerToolType] -public static class TimeTools +public class TimeTools { [McpServerTool, Description("Get the current time for a city")] public static string GetCurrentTime(string city) diff --git a/McpStudy.McpClient/Program.cs b/McpStudy.McpClient/Program.cs index 0d6174f..0596563 100644 --- a/McpStudy.McpClient/Program.cs +++ b/McpStudy.McpClient/Program.cs @@ -1,6 +1,13 @@ using System.Diagnostics; using System.Threading.Tasks; +using ModelContextProtocol; +using ModelContextProtocol.Client; + +using ModelContextProtocol.AspNetCore; + + + namespace McpStudy.McpClient; internal class Program { @@ -10,4 +17,31 @@ internal class Program await Task.CompletedTask; } + + static async Task CallStdio() + { + var clientTransport = new StdioClientTransport(new StdioClientTransportOptions + { + Name = "Everything", + Command = "npx", + Arguments = ["-y", "@modelcontextprotocol/server-everything"], + }); + + var client = await McpClientFactory.CreateAsync(clientTransport); + + // Print the list of tools available from the server. + foreach (var tool in await client.ListToolsAsync()) + { + Console.WriteLine($"{tool.Name} ({tool.Description})"); + } + + // Execute a tool (this would normally be driven by LLM tool invocations). + var result = await client.CallToolAsync( + "echo", + new Dictionary() { ["message"] = "Hello MCP!" }, + cancellationToken: CancellationToken.None); + + // echo always returns one and only one text content object + Console.WriteLine(result.Content.First(c => c.Type == "text").ToString()); + } } diff --git a/McpStudy.McpServerSSE/GlobalUsing.cs b/McpStudy.McpServerSSE/GlobalUsing.cs new file mode 100644 index 0000000..1c0020f --- /dev/null +++ b/McpStudy.McpServerSSE/GlobalUsing.cs @@ -0,0 +1,19 @@ +global using System.Linq; +global using System.ComponentModel; +global using System.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.McpServerSSE/McpStudy.McpServerSSE.csproj b/McpStudy.McpServerSSE/McpStudy.McpServerSSE.csproj index 6b1e620..3efdcb9 100644 --- a/McpStudy.McpServerSSE/McpStudy.McpServerSSE.csproj +++ b/McpStudy.McpServerSSE/McpStudy.McpServerSSE.csproj @@ -8,6 +8,8 @@ + + diff --git a/McpStudy.McpServerSSE/Program.cs b/McpStudy.McpServerSSE/Program.cs index d1f9856..26828ff 100644 --- a/McpStudy.McpServerSSE/Program.cs +++ b/McpStudy.McpServerSSE/Program.cs @@ -1,32 +1,45 @@ +namespace McpStudy.McpServerSSE; -namespace McpStudy.McpServerSSE +public class Program { - public class Program + public static void Main(string[] args) { - public static void Main(string[] args) - { - var builder = WebApplication.CreateBuilder(args); + var builder = WebApplication.CreateBuilder(args); - // Add services to the container. + // Add services to the container. - builder.Services.AddControllers(); - // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi - builder.Services.AddOpenApi(); + builder.Services.AddControllers(); - var app = builder.Build(); + // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi + builder.Services.AddOpenApi(); - // Configure the HTTP request pipeline. - if (app.Environment.IsDevelopment()) - { - app.MapOpenApi(); - } + builder.Services + .AddMcpServer() + .WithHttpTransport() + .WithToolsFromAssembly(typeof(McpStudy.Core.TimeTools).Assembly) + .WithToolsFromAssembly(typeof(McpStudy.McpServerSSE.Program).Assembly); - app.UseAuthorization(); + var app = builder.Build(); - app.MapControllers(); + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + app.MapOpenApi(); - app.Run(); + app.UseSwaggerUI(options => + { + options.SwaggerEndpoint("/openapi/v1.json", "v1"); + }); } + + app.UseAuthorization(); + + + app.MapControllers(); + + app.MapMcp(); + + app.Run(); } } diff --git a/McpStudy.McpServerSSE/Properties/launchSettings.json b/McpStudy.McpServerSSE/Properties/launchSettings.json index 0b4b9f7..b97e392 100644 --- a/McpStudy.McpServerSSE/Properties/launchSettings.json +++ b/McpStudy.McpServerSSE/Properties/launchSettings.json @@ -4,7 +4,8 @@ "http": { "commandName": "Project", "dotnetRunMessages": true, - "launchBrowser": false, + "launchBrowser": true, + "launchUrl": "swagger/index.html", "applicationUrl": "http://localhost:5027", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" diff --git a/McpStudy.McpServerStdio/GlobalUsing.cs b/McpStudy.McpServerStdio/GlobalUsing.cs index 7110a57..ff999d4 100644 --- a/McpStudy.McpServerStdio/GlobalUsing.cs +++ b/McpStudy.McpServerStdio/GlobalUsing.cs @@ -1,5 +1,7 @@ global using System.Linq; global using System.ComponentModel; +global using System.Net.Http; +global using System.Net.Http.Headers; global using Microsoft.Net.Http.Headers; global using Microsoft.Extensions.Hosting;