Posted in:

I posted recently about how to allow LLMs to call tools using the Microsoft.Extensions.AI NuGet package in C#.

Obviously, a common usage scenario would be to expose MCP servers as tools for your LLM to call. Thankfully, the new ModelContextProtocol NuGet package makes this straightforward.

Note: This package is still in pre-release (as is Microsoft.Extensions.AI), so do check the release notes for any breaking changes to the API.

I've updated my demo application to support calling MCP tools, following the techniques demonstrated in Microsoft's Chat With Tools sample.

The first step is simply to reference the ModelContextProtocol NuGet package. I had to also update the Microsoft.Extensions.AI versions as well. Here's the versions I used for my test:

<PackageReference Include="Microsoft.Extensions.AI" Version="9.4.0-preview.1.25207.5" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="9.4.0-preview.1.25207.5" />
<PackageReference Include="ModelContextProtocol" Version="0.1.0-preview.8" />

The next step is simply to connect to an MCP server. You can do this with the McpClientFactory. Here, we're using npx (which comes with Node) to run a simple example MCP server called the "Everything" server as it demonstrates the range of capabilities of an MCP server.

var mcpClient = await McpClientFactory.CreateAsync(
    new StdioClientTransport(new()
    {
        Command = "npx",
        Arguments = ["-y", "--verbose", "@modelcontextprotocol/server-everything"],
        Name = "Everything",
    }));

We can then use the MCP client to list the available tools:

var tools = await mcpClient.ListToolsAsync();
Console.WriteLine("Available tools:");
foreach (var tool in tools)
{
    Console.WriteLine($"  {tool.Name}: {tool.Description}");
}

These tools are instances of McpClientTool, which inherits from AIFunction, meaning that we can pass them directly in as tools to an instance of ChatOptions:

var chatOptions = new ChatOptions
{
    Tools = [..tools]
};

And then using the tools is simply a case of passing those options into the call to GetStreamingResponseAsync.

 await foreach (var item in chatClient.GetStreamingResponseAsync(
        chatHistory, chatOptions))

Although it's early days for the MCP protocol, it's very pleasing to see how easy it is to get your LLM calling tools provided by an MCP server. For the full code sample, showing how to get this working with Azure OpenAI service, check my demo repo here.