| 1 | using System.Text.Json; |
| 2 | using DotNetBuildTest.Core; |
| 3 | using DotnetBuildTestMcp; |
| 4 | using ModelContextProtocol.Protocol; |
| 5 | using ModelContextProtocol.Server; |
| 6 | using Tool = ModelContextProtocol.Protocol.Tool; |
| 7 | |
| 8 | var jobService = new BuildTestJobService(); |
| 9 | var toolsList = ToolCatalog.Build(); |
| 10 | |
| 11 | var options = new McpServerOptions |
| 12 | { |
| 13 | ServerInfo = new Implementation { Name = "DotnetBuildTestMcp", Version = "0.4.0" }, |
| 14 | ProtocolVersion = "2024-11-05", |
| 15 | Capabilities = new ServerCapabilities { Tools = new ToolsCapability { ListChanged = false } }, |
| 16 | Handlers = new McpServerHandlers |
| 17 | { |
| 18 | ListToolsHandler = (_, _) => ValueTask.FromResult(new ListToolsResult { Tools = toolsList }), |
| 19 | |
| 20 | CallToolHandler = async (request, cancellationToken) => |
| 21 | { |
| 22 | var name = request.Params?.Name ?? ""; |
| 23 | var args = request.Params?.Arguments is IReadOnlyDictionary<string, JsonElement> a |
| 24 | ? a |
| 25 | : new Dictionary<string, JsonElement>(); |
| 26 | |
| 27 | try |
| 28 | { |
| 29 | var text = name switch |
| 30 | { |
| 31 | "build_structured" => await jobService.BuildStructuredAsync(args, cancellationToken).ConfigureAwait(false), |
| 32 | "run_tests" => await jobService.RunTestsAsync(args, cancellationToken).ConfigureAwait(false), |
| 33 | "publish_structured" => await jobService.PublishStructuredAsync(args, cancellationToken).ConfigureAwait(false), |
| 34 | "get_job_status" => jobService.GetJobStatus(args), |
| 35 | "get_job_log" => jobService.GetJobLog(args), |
| 36 | "cancel_job" => jobService.CancelJob(args), |
| 37 | _ => throw new ArgumentException($"Unknown tool: {name}.") |
| 38 | }; |
| 39 | |
| 40 | return new CallToolResult { Content = [new TextContentBlock { Text = text }], IsError = false }; |
| 41 | } |
| 42 | catch (ArgumentException ex) |
| 43 | { |
| 44 | return new CallToolResult |
| 45 | { |
| 46 | Content = [new TextContentBlock { Text = $"Error: {ex.Message}" }], |
| 47 | IsError = true |
| 48 | }; |
| 49 | } |
| 50 | catch (Exception ex) |
| 51 | { |
| 52 | return new CallToolResult |
| 53 | { |
| 54 | Content = [new TextContentBlock { Text = "Error: " + ex.Message }], |
| 55 | IsError = true |
| 56 | }; |
| 57 | } |
| 58 | } |
| 59 | } |
| 60 | }; |
| 61 | |
| 62 | var transport = new StdioServerTransport("DotnetBuildTestMcp"); |
| 63 | await using var server = McpServer.Create(transport, options); |
| 64 | await server.RunAsync(); |
| 65 | return 0; |
| 66 | |