|
3 | 3 | // Copyright (C) Leszek Pomianowski and OpenAPI Client Contributors. |
4 | 4 | // All Rights Reserved. |
5 | 5 |
|
6 | | -WebApplicationBuilder builder = WebApplication.CreateBuilder(args); |
| 6 | +ILogger logger = StaticLoggerFactory.New(); |
| 7 | +ServerOptions serverOptions = ConfigurationFactory.CreateServerOptions(args); |
7 | 8 |
|
8 | | -builder.Logging.AddConsole(consoleLogOptions => |
9 | | -{ |
10 | | - // Configure all logs to go to stderr |
11 | | - consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace; |
12 | | -}); |
13 | | - |
14 | | -#if DEBUG |
15 | | -builder |
16 | | - .Services.AddOpenTelemetry() |
17 | | - .WithTracing(b => b.AddSource("*").AddAspNetCoreInstrumentation().AddHttpClientInstrumentation()) |
18 | | - .WithMetrics(b => b.AddMeter("*").AddAspNetCoreInstrumentation().AddHttpClientInstrumentation()) |
19 | | - .WithLogging() |
20 | | - .UseOtlpExporter(); |
21 | | -#endif |
| 9 | +logger.LogInformation("Configuring MCP Server with mode: {Mode}", serverOptions.Mode); |
22 | 10 |
|
23 | | -builder.Services.AddTransient<IOpenApiService, OpenApiService>(); |
| 11 | +// NOTE: Do not use whole ASP.NET stack with just interactive console |
| 12 | +if (serverOptions.Mode == McpMode.Stdio) |
| 13 | +{ |
| 14 | + logger.LogInformation("Adding Stdio transport to MCP Server."); |
24 | 15 |
|
25 | | -builder.Services.AddHttpClient(); |
| 16 | + HostApplicationBuilder builder = Host.CreateApplicationBuilder(args); |
| 17 | + AddMcpServices(builder, serverOptions.Mode).WithStdioServerTransport(); |
26 | 18 |
|
27 | | -ServerOptions serverOptions = new(); |
28 | | -IConfigurationSection section = builder.Configuration.GetSection("Server"); |
29 | | -section.Bind(serverOptions); |
| 19 | + logger.LogInformation("Starting the application."); |
30 | 20 |
|
31 | | -string? mode = Environment.GetEnvironmentVariable("mode") ?? Environment.GetEnvironmentVariable("MODE"); |
| 21 | + await builder.Build().RunAsync(); |
32 | 22 |
|
33 | | -if (mode?.Contains("both", StringComparison.InvariantCultureIgnoreCase) ?? false) |
34 | | -{ |
35 | | - serverOptions.Mode = McpMode.Both; |
36 | | -} |
37 | | -else if (mode?.Contains("http", StringComparison.InvariantCultureIgnoreCase) ?? false) |
38 | | -{ |
39 | | - serverOptions.Mode = McpMode.Http; |
| 23 | + // NOTE: Stop here, as we are running in Stdio mode. |
| 24 | + return; |
40 | 25 | } |
41 | 26 |
|
42 | | -IMcpServerBuilder mcpBuilder = builder.Services.AddMcpServer(); |
| 27 | +logger.LogInformation("Adding HTTP transport to MCP Server."); |
| 28 | + |
| 29 | +WebApplicationBuilder webBuilder = WebApplication.CreateBuilder(args); |
| 30 | +IMcpServerBuilder mcpBuilder = AddMcpServices(webBuilder, serverOptions.Mode).WithHttpTransport(); |
43 | 31 |
|
44 | 32 | if (serverOptions.Mode == McpMode.Both) |
45 | 33 | { |
46 | | - _ = mcpBuilder.WithHttpTransport().WithStdioServerTransport(); |
47 | | -} |
48 | | -else if (serverOptions.Mode == McpMode.Stdio) |
49 | | -{ |
| 34 | + logger.LogInformation("Adding Stdio transport to MCP Server."); |
50 | 35 | _ = mcpBuilder.WithStdioServerTransport(); |
51 | 36 | } |
52 | | -else |
53 | | -{ |
54 | | - _ = mcpBuilder.WithHttpTransport(); |
55 | | -} |
56 | 37 |
|
57 | | -_ = mcpBuilder.WithTools<OpenApiTools>(); |
| 38 | +#if !DEBUG |
| 39 | +webBuilder.WebHost.ConfigureKestrel(options => |
| 40 | +{ |
| 41 | + options.ListenAnyIP(80); |
| 42 | + options.ListenAnyIP(8080); |
| 43 | + options.ListenAnyIP(8000); |
| 44 | +}); |
| 45 | +#endif |
58 | 46 |
|
59 | | -await using WebApplication app = builder.Build(); |
| 47 | +await using WebApplication app = webBuilder.Build(); |
60 | 48 |
|
61 | | -if (serverOptions.Mode is McpMode.Http or McpMode.Both) |
62 | | -{ |
63 | | - app.MapMcp(); |
64 | | -} |
| 49 | +app.MapMcp(); |
| 50 | +app.MapHealthChecks("/healthz"); |
65 | 51 |
|
66 | 52 | await app.RunAsync(); |
67 | 53 |
|
68 | 54 | return; |
| 55 | + |
| 56 | +static IMcpServerBuilder AddMcpServices(IHostApplicationBuilder builder, McpMode mode) |
| 57 | +{ |
| 58 | + builder.Logging.AddConsole(consoleLogOptions => |
| 59 | + { |
| 60 | + // Configure all logs to go to stderr |
| 61 | + consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace; |
| 62 | + }); |
| 63 | + |
| 64 | +#if DEBUG |
| 65 | + builder |
| 66 | + .Services.AddOpenTelemetry() |
| 67 | + .WithTracing(b => b.AddSource("*").AddAspNetCoreInstrumentation().AddHttpClientInstrumentation()) |
| 68 | + .WithMetrics(b => b.AddMeter("*").AddAspNetCoreInstrumentation().AddHttpClientInstrumentation()) |
| 69 | + .WithLogging() |
| 70 | + .UseOtlpExporter(); |
| 71 | +#endif |
| 72 | + |
| 73 | + builder |
| 74 | + .Services.AddHttpClient<IOpenApiService, OpenApiService>() |
| 75 | + .ConfigurePrimaryHttpMessageHandler(() => |
| 76 | + { |
| 77 | + return new HttpClientHandler |
| 78 | + { |
| 79 | + ServerCertificateCustomValidationCallback = (_, _, _, _) => true, |
| 80 | + AllowAutoRedirect = true, |
| 81 | + }; |
| 82 | + }); |
| 83 | + |
| 84 | + if (mode != McpMode.Stdio) |
| 85 | + { |
| 86 | + builder.Services.AddHealthChecks(); |
| 87 | + } |
| 88 | + |
| 89 | + IMcpServerBuilder mcpBuilder = builder |
| 90 | + .Services.AddMcpServer(mcp => |
| 91 | + { |
| 92 | + mcp.ServerInfo = new Implementation { Name = "OpenAPI Toolkit MCP Server", Version = "1.0.0" }; |
| 93 | + mcp.InitializationTimeout = TimeSpan.FromHours(1); |
| 94 | + mcp.ScopeRequests = true; |
| 95 | + }) |
| 96 | + .WithTools<OpenApiTools>(); |
| 97 | + |
| 98 | + return mcpBuilder; |
| 99 | +} |
0 commit comments