forked from microsoft/semantic-kernel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
132 lines (112 loc) · 4.56 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using ModelContextProtocol;
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol.Transport;
namespace MCPClient;
internal sealed class Program
{
public static async Task Main(string[] args)
{
// Create an MCP client
await using IMcpClient mcpClient = await CreateMcpClientAsync();
// Retrieve and display the list provided by the MCP server
IList<McpClientTool> tools = await mcpClient.ListToolsAsync();
DisplayTools(tools);
// Create a kernel and register the MCP tools
Kernel kernel = CreateKernelWithChatCompletionService();
kernel.Plugins.AddFromFunctions("Tools", tools.Select(aiFunction => aiFunction.AsKernelFunction()));
// Enable automatic function calling
OpenAIPromptExecutionSettings executionSettings = new()
{
Temperature = 0,
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(options: new() { RetainArgumentTypes = true })
};
string prompt = "What is the likely color of the sky in Boston today?";
// Execute a prompt using the MCP tools. The AI model will automatically call the appropriate MCP tools to answer the prompt.
FunctionResult result = await kernel.InvokePromptAsync(prompt, new(executionSettings));
Console.WriteLine(result);
// The expected output is: The likely color of the sky in Boston today is gray, as it is currently rainy.
}
/// <summary>
/// Creates an instance of <see cref="Kernel"/> with the OpenAI chat completion service registered.
/// </summary>
/// <returns>An instance of <see cref="Kernel"/>.</returns>
private static Kernel CreateKernelWithChatCompletionService()
{
// Load and validate configuration
IConfigurationRoot config = new ConfigurationBuilder()
.AddUserSecrets<Program>()
.AddEnvironmentVariables()
.Build();
if (config["OpenAI:ApiKey"] is not { } apiKey)
{
string message = "Please provide a valid OpenAI:ApiKey to run this sample. See the associated README.md for more details.";
Console.Error.WriteLine(message);
throw new InvalidOperationException(message);
}
// Create kernel
var kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.Services.AddOpenAIChatCompletion(serviceId: "openai", modelId: config["OpenAI:ChatModelId"] ?? "gpt-4o-mini", apiKey: config["OpenAI:ApiKey"]!);
return kernelBuilder.Build();
}
/// <summary>
/// Creates an MCP client and connects it to the MCPServer server.
/// </summary>
/// <returns>An instance of <see cref="IMcpClient"/>.</returns>
private static async Task<IMcpClient> CreateMcpClientAsync()
{
var mcpClient = await McpClientFactory.CreateAsync(
new McpServerConfig()
{
Id = "MCPServer",
Name = "MCPServer",
TransportType = TransportTypes.StdIo,
TransportOptions = new()
{
// Point the client to the MCPServer server executable
["command"] = GetMCPServerPath()
}
},
new McpClientOptions()
{
ClientInfo = new() { Name = "MCPClient", Version = "1.0.0" }
}
);
return mcpClient;
}
/// <summary>
/// Returns the path to the MCPServer server executable.
/// </summary>
/// <returns>The path to the MCPServer server executable.</returns>
private static string GetMCPServerPath()
{
// Determine the configuration (Debug or Release)
string configuration;
#if DEBUG
configuration = "Debug";
#else
configuration = "Release";
#endif
return Path.Combine("..", "..", "..", "..", "MCPServer", "bin", configuration, "net8.0", "MCPServer.exe");
}
/// <summary>
/// Displays the list of available MCP tools.
/// </summary>
/// <param name="tools">The list of the tools to display.</param>
private static void DisplayTools(IList<McpClientTool> tools)
{
Console.WriteLine("Available MCP tools:");
foreach (var tool in tools)
{
Console.WriteLine($"{tool.Name}: {tool.Description}");
}
}
}