diff --git a/src/ModelContextProtocol.NET.Demo.Calculator/Handlers/CalculatorToolHandler.cs b/src/ModelContextProtocol.NET.Demo.Calculator/Handlers/CalculatorToolHandler.cs index d06b4b3..5397932 100644 --- a/src/ModelContextProtocol.NET.Demo.Calculator/Handlers/CalculatorToolHandler.cs +++ b/src/ModelContextProtocol.NET.Demo.Calculator/Handlers/CalculatorToolHandler.cs @@ -29,7 +29,7 @@ public enum CalculatorOperation Add, Subtract, Multiply, - Divide + Divide, } [JsonSerializable(typeof(CalculatorParameters))] @@ -44,14 +44,12 @@ public class CalculatorToolHandler( ILogger logger ) : ToolHandlerBase(tool, serverContext, sessionFacade) { - private static readonly Tool tool = - new() - { - Name = "Calculator", - Description = "Performs basic arithmetic operations", - InputSchema = - CalculatorParametersJsonContext.Default.CalculatorParameters.GetToolSchema()! - }; + private static readonly Tool tool = new() + { + Name = "Calculator", + Description = "Performs basic arithmetic operations", + InputSchema = CalculatorParametersJsonContext.Default.CalculatorParameters.GetToolSchema()!, + }; public override JsonTypeInfo JsonTypeInfo => CalculatorParametersJsonContext.Default.CalculatorParameters; @@ -68,7 +66,7 @@ protected override Task HandleAsync( CalculatorOperation.Multiply => parameters.A * parameters.B, CalculatorOperation.Divide when parameters.B != 0 => parameters.A / parameters.B, CalculatorOperation.Divide => throw new DivideByZeroException("Cannot divide by zero"), - _ => throw new ArgumentException($"Unknown operation: {parameters.Operation}") + _ => throw new ArgumentException($"Unknown operation: {parameters.Operation}"), }; var content = new TextContent { Text = result.ToString() }; diff --git a/src/ModelContextProtocol.NET.Demo.Calculator/Program.cs b/src/ModelContextProtocol.NET.Demo.Calculator/Program.cs index fb637f6..306a7e9 100644 --- a/src/ModelContextProtocol.NET.Demo.Calculator/Program.cs +++ b/src/ModelContextProtocol.NET.Demo.Calculator/Program.cs @@ -39,17 +39,17 @@ CalculatorOperation.Add => parameters.A + parameters.B, CalculatorOperation.Subtract => parameters.A - parameters.B, CalculatorOperation.Multiply => parameters.A * parameters.B, - CalculatorOperation.Divide when parameters.B != 0 - => parameters.A / parameters.B, - CalculatorOperation.Divide - => throw new DivideByZeroException("Cannot divide by zero"), - _ - => throw new ArgumentException( - $"Unknown operation: {parameters.Operation}" - ), + CalculatorOperation.Divide when parameters.B != 0 => parameters.A + / parameters.B, + CalculatorOperation.Divide => throw new DivideByZeroException( + "Cannot divide by zero" + ), + _ => throw new ArgumentException( + $"Unknown operation: {parameters.Operation}" + ), } ) - ).ToString() + ).ToString(), } ) ); @@ -58,11 +58,17 @@ try { + // You can either use Start/Stop pattern: + /* server.Start(); await Task.Delay(-1); // Wait indefinitely + server.Stop(); + */ + + // Or use the more convenient RunAsync pattern: + await server.RunAsync(); // Runs until cancelled } finally { - server.Stop(); await server.DisposeAsync(); } diff --git a/src/ModelContextProtocol.NET.Server/IMcpServer.cs b/src/ModelContextProtocol.NET.Server/IMcpServer.cs index 44ab034..eb28581 100644 --- a/src/ModelContextProtocol.NET.Server/IMcpServer.cs +++ b/src/ModelContextProtocol.NET.Server/IMcpServer.cs @@ -1,5 +1,6 @@ using System; using System.Threading; +using System.Threading.Tasks; using ModelContextProtocol.NET.Core.Models.Protocol.Common; namespace ModelContextProtocol.NET.Server; @@ -23,4 +24,11 @@ public interface IMcpServer : IAsyncDisposable /// Stops the server. /// void Stop(CancellationToken cancellationToken = default); + + /// + /// Runs the server and blocks until the cancellation token is triggered. + /// This is a convenience method that combines Start(), waiting for cancellation, and Stop(). + /// + /// Optional token to cancel server execution + Task RunAsync(CancellationToken cancellationToken = default); } diff --git a/src/ModelContextProtocol.NET.Server/McpServer.cs b/src/ModelContextProtocol.NET.Server/McpServer.cs index 5948528..feb0181 100644 --- a/src/ModelContextProtocol.NET.Server/McpServer.cs +++ b/src/ModelContextProtocol.NET.Server/McpServer.cs @@ -60,6 +60,27 @@ public void Stop(CancellationToken cancellationToken = default) logger.LogInformation("MCP server stopped"); } + public async Task RunAsync(CancellationToken cancellationToken = default) + { + try + { + // Start the server + Start(cancellationToken); + + // Create a TaskCompletionSource to wait for cancellation + var tcs = new TaskCompletionSource(); + using var registration = cancellationToken.Register(() => tcs.SetResult()); + + // Wait for cancellation + await tcs.Task; + } + finally + { + // Stop the server + Stop(cancellationToken); + } + } + public async ValueTask DisposeAsync() { if (!isDisposed)