1
1
// Copyright (c) Microsoft. All rights reserved.
2
2
3
3
using System ;
4
+ using System . Collections . Generic ;
4
5
using System . IO ;
5
6
using System . Linq ;
6
7
using System . Threading . Tasks ;
7
8
using Microsoft . Extensions . Configuration ;
8
- using Microsoft . Extensions . DependencyInjection ;
9
- using Microsoft . Extensions . Logging ;
10
9
using Microsoft . SemanticKernel ;
11
10
using Microsoft . SemanticKernel . Connectors . OpenAI ;
12
11
using ModelContextProtocol ;
@@ -18,21 +17,71 @@ namespace MCPClient;
18
17
internal sealed class Program
19
18
{
20
19
public static async Task Main ( string [ ] args )
20
+ {
21
+ // Create an MCP client
22
+ await using IMcpClient mcpClient = await CreateMcpClientAsync ( ) ;
23
+
24
+ // Retrieve and display the list provided by the MCP server
25
+ IList < McpClientTool > tools = await mcpClient . ListToolsAsync ( ) ;
26
+ DisplayTools ( tools ) ;
27
+
28
+ // Create a kernel and register the MCP tools
29
+ Kernel kernel = CreateKernelWithChatCompletionService ( ) ;
30
+ kernel . Plugins . AddFromFunctions ( "Tools" , tools . Select ( aiFunction => aiFunction . AsKernelFunction ( ) ) ) ;
31
+
32
+ // Enable automatic function calling
33
+ OpenAIPromptExecutionSettings executionSettings = new ( )
34
+ {
35
+ Temperature = 0 ,
36
+ FunctionChoiceBehavior = FunctionChoiceBehavior . Auto ( options : new ( ) { RetainArgumentTypes = true } )
37
+ } ;
38
+
39
+ string prompt = "What is the likely color of the sky in Boston today?" ;
40
+ Console . WriteLine ( prompt ) ;
41
+
42
+ // Execute a prompt using the MCP tools. The AI model will automatically call the appropriate MCP tools to answer the prompt.
43
+ FunctionResult result = await kernel . InvokePromptAsync ( prompt , new ( executionSettings ) ) ;
44
+
45
+ Console . WriteLine ( result ) ;
46
+
47
+ // The expected output is: The likely color of the sky in Boston today is gray, as it is currently rainy.
48
+ }
49
+
50
+ /// <summary>
51
+ /// Creates an instance of <see cref="Kernel"/> with the OpenAI chat completion service registered.
52
+ /// </summary>
53
+ /// <returns>An instance of <see cref="Kernel"/>.</returns>
54
+ private static Kernel CreateKernelWithChatCompletionService ( )
21
55
{
22
56
// Load and validate configuration
23
- var config = new ConfigurationBuilder ( )
57
+ IConfigurationRoot config = new ConfigurationBuilder ( )
24
58
. AddUserSecrets < Program > ( )
25
59
. AddEnvironmentVariables ( )
26
60
. Build ( ) ;
27
61
28
62
if ( config [ "OpenAI:ApiKey" ] is not { } apiKey )
29
63
{
30
- Console . Error . WriteLine ( "Please provide a valid OpenAI:ApiKey to run this sample. See the associated README.md for more details." ) ;
31
- return ;
64
+ const string Message = "Please provide a valid OpenAI:ApiKey to run this sample. See the associated README.md for more details." ;
65
+ Console . Error . WriteLine ( Message ) ;
66
+ throw new InvalidOperationException ( Message ) ;
32
67
}
33
68
34
- // Create an MCP client
35
- await using var mcpClient = await McpClientFactory . CreateAsync (
69
+ string modelId = config [ "OpenAI:ChatModelId" ] ?? "gpt-4o-mini" ;
70
+
71
+ // Create kernel
72
+ var kernelBuilder = Kernel . CreateBuilder ( ) ;
73
+ kernelBuilder . Services . AddOpenAIChatCompletion ( serviceId : "openai" , modelId : modelId , apiKey : apiKey ) ;
74
+
75
+ return kernelBuilder . Build ( ) ;
76
+ }
77
+
78
+ /// <summary>
79
+ /// Creates an MCP client and connects it to the MCPServer server.
80
+ /// </summary>
81
+ /// <returns>An instance of <see cref="IMcpClient"/>.</returns>
82
+ private static Task < IMcpClient > CreateMcpClientAsync ( )
83
+ {
84
+ return McpClientFactory . CreateAsync (
36
85
new McpServerConfig ( )
37
86
{
38
87
Id = "MCPServer" ,
@@ -48,40 +97,7 @@ public static async Task Main(string[] args)
48
97
{
49
98
ClientInfo = new ( ) { Name = "MCPClient" , Version = "1.0.0" }
50
99
}
51
- ) ;
52
-
53
- // Retrieve and display the list of tools available on the MCP server
54
- Console . WriteLine ( "Available MCP tools:" ) ;
55
- var tools = await mcpClient . ListToolsAsync ( ) . ConfigureAwait ( false ) ;
56
- foreach ( var tool in tools )
57
- {
58
- Console . WriteLine ( $ "{ tool . Name } : { tool . Description } ") ;
59
- }
60
-
61
- // Prepare and build kernel with the MCP tools as Kernel functions
62
- var kernelBuilder = Kernel . CreateBuilder ( ) ;
63
- kernelBuilder . Plugins . AddFromFunctions ( "Tools" , tools . Select ( aiFunction => aiFunction . AsKernelFunction ( ) ) ) ;
64
- kernelBuilder . Services
65
- . AddLogging ( c => c . AddDebug ( ) . SetMinimumLevel ( Microsoft . Extensions . Logging . LogLevel . Trace ) )
66
- . AddOpenAIChatCompletion ( serviceId : "openai" , modelId : config [ "OpenAI:ChatModelId" ] ?? "gpt-4o-mini" , apiKey : apiKey ) ;
67
-
68
- Kernel kernel = kernelBuilder . Build ( ) ;
69
-
70
- // Enable automatic function calling
71
- OpenAIPromptExecutionSettings executionSettings = new ( )
72
- {
73
- Temperature = 0 ,
74
- FunctionChoiceBehavior = FunctionChoiceBehavior . Auto ( options : new ( ) { RetainArgumentTypes = true } )
75
- } ;
76
-
77
- // Execute a prompt using the MCP tools. The AI model will automatically call the appropriate MCP tools to answer the prompt.
78
- var prompt = "What is the likely color of the sky in Boston today?" ;
79
- var result = await kernel . InvokePromptAsync ( prompt , new ( executionSettings ) ) . ConfigureAwait ( false ) ;
80
- Console . WriteLine ( $ "\n \n { prompt } \n { result } ") ;
81
-
82
- // The expected output is:
83
- // What is the likely color of the sky in Boston today?
84
- // The likely color of the sky in Boston today is gray, as it is currently rainy.
100
+ ) ;
85
101
}
86
102
87
103
/// <summary>
@@ -101,4 +117,17 @@ private static string GetMCPServerPath()
101
117
102
118
return Path . Combine ( ".." , ".." , ".." , ".." , "MCPServer" , "bin" , configuration , "net8.0" , "MCPServer.exe" ) ;
103
119
}
120
+
121
+ /// <summary>
122
+ /// Displays the list of available MCP tools.
123
+ /// </summary>
124
+ /// <param name="tools">The list of the tools to display.</param>
125
+ private static void DisplayTools ( IList < McpClientTool > tools )
126
+ {
127
+ Console . WriteLine ( "Available MCP tools:" ) ;
128
+ foreach ( var tool in tools )
129
+ {
130
+ Console . WriteLine ( $ "- { tool . Name } : { tool . Description } ") ;
131
+ }
132
+ }
104
133
}
0 commit comments