Skip to content

Commit abacb03

Browse files
mcp usage sample
1 parent 94608bb commit abacb03

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

docs/guides/mcp/chat_with_mcp.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// SAMPLE: call the official MCP library for .NET
2+
3+
#:package OpenAI@2.2.*-*
4+
#:package ModelContextProtocol.Core@*-*
5+
#:property PublishAot=false
6+
7+
using ModelContextProtocol.Client;
8+
using OpenAI.Chat;
9+
10+
string mcpCommand = Environment.GetEnvironmentVariable("MCP_SERVER_COMMAND")!; // path to a stdio mcp server
11+
string key = Environment.GetEnvironmentVariable("OPENAI_KEY")!;
12+
13+
ChatClient chatClient = new("gpt-4.1", key);
14+
15+
// Create MCP client to connect to the server
16+
IMcpClient mcpClient = await McpClientFactory.CreateAsync(new StdioClientTransport(new StdioClientTransportOptions
17+
{
18+
Name = "MyServer",
19+
Command = mcpCommand,
20+
Arguments = [],
21+
}));
22+
23+
// get avaliable tools and add them to completion options
24+
ChatCompletionOptions options = new();
25+
await foreach (McpClientTool chatTool in mcpClient.EnumerateToolsAsync())
26+
{
27+
options.Tools.Add(chatTool.AsOpenAIChatTool());
28+
}
29+
30+
// conversation thread
31+
List<ChatMessage> conversation = new()
32+
{
33+
ChatMessage.CreateUserMessage("Use an MCP tool")
34+
};
35+
36+
start:
37+
ChatCompletion chatCompletion = chatClient.CompleteChat(conversation, options);
38+
conversation.Add(ChatMessage.CreateAssistantMessage(chatCompletion));
39+
switch (chatCompletion.FinishReason)
40+
{
41+
case ChatFinishReason.ToolCalls:
42+
foreach(var call in chatCompletion.ToolCalls)
43+
{
44+
var mcpArguments = call.FunctionArguments.ToObjectFromJson<Dictionary<string, object>>();
45+
Console.WriteLine("Tool call detected, calling MCP server...");
46+
ModelContextProtocol.Protocol.CallToolResult result = await mcpClient.CallToolAsync(call.FunctionName, mcpArguments!);
47+
Console.WriteLine($"tool call result {result.Content[0]}");
48+
ChatMessage message = result.ToMessage(call);
49+
conversation.Add(message);
50+
}
51+
goto start;
52+
case ChatFinishReason.Stop:
53+
Console.WriteLine(chatCompletion.Content[0].Text);
54+
break;
55+
default:
56+
throw new NotImplementedException();
57+
}
58+
59+
#region TEMPORARY
60+
// this is temporary. all these APIs will endup being in one of the packages used here.
61+
public static class TemporaryExtensions
62+
{
63+
public static ChatMessage ToMessage(this ModelContextProtocol.Protocol.CallToolResult mcpCallResult, ChatToolCall openaiCall)
64+
{
65+
List<ChatMessageContentPart> parts = new();
66+
var sc = mcpCallResult.StructuredContent;
67+
68+
foreach (ModelContextProtocol.Protocol.ContentBlock block in mcpCallResult.Content)
69+
{
70+
if (block is ModelContextProtocol.Protocol.TextContentBlock textContent)
71+
{
72+
parts.Add(ChatMessageContentPart.CreateTextPart(textContent.Text));
73+
}
74+
else
75+
{
76+
throw new NotImplementedException();
77+
}
78+
}
79+
ToolChatMessage message = ChatMessage.CreateToolMessage(openaiCall.Id, parts);
80+
return message;
81+
}
82+
83+
// this is in the adapter package; waiting for package to be dropped.
84+
public static ChatTool AsOpenAIChatTool(this Microsoft.Extensions.AI.AIFunction mcpTool)
85+
{
86+
return ChatTool.CreateFunctionTool(
87+
mcpTool.Name,
88+
mcpTool.Description,
89+
BinaryData.FromString(mcpTool.JsonSchema.GetRawText()));
90+
}
91+
}
92+
#endregion

0 commit comments

Comments
 (0)