Skip to content

.Net: Update MCP sample with ModelContextProtocol #11121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dotnet/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<PackageVersion Include="EntityFramework" Version="6.5.1" />
<PackageVersion Include="FastBertTokenizer" Version="1.0.28" />
<PackageVersion Include="Google.Apis.Auth" Version="1.69.0" />
<PackageVersion Include="mcpdotnet" Version="1.0.1.3" />
<PackageVersion Include="ModelContextProtocol" Version="0.1.0-preview.1.25171.12" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.13" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.13" />
<PackageVersion Include="Microsoft.ML.Tokenizers.Data.Cl100kBase" Version="1.0.1" />
Expand Down
18 changes: 9 additions & 9 deletions dotnet/SK-dotnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -498,8 +498,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatWithAgent.ServiceDefaul
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatWithAgent.Web", "samples\Demos\AgentFrameworkWithAspire\ChatWithAgent.Web\ChatWithAgent.Web.csproj", "{543879BF-E2CD-6521-8322-8FBCD6EC57A0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModelContextProtocol", "samples\Demos\ModelContextProtocol\ModelContextProtocol.csproj", "{B16AC373-3DA8-4505-9510-110347CD635D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StructuredDataPlugin", "samples\Demos\StructuredDataPlugin\StructuredDataPlugin.csproj", "{BEDAC050-016A-46F4-9173-339C46DFD3ED}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugins.StructuredData.EntityFramework", "src\Plugins\Plugins.StructuredData.EntityFramework\Plugins.StructuredData.EntityFramework.csproj", "{0C81C377-3CDC-46A8-BED1-4B50BDA2202E}"
Expand All @@ -508,6 +506,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlServerIntegrationTests",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PineconeIntegrationTests", "src\VectorDataIntegrationTests\PineconeIntegrationTests\PineconeIntegrationTests.csproj", "{E9A74E0C-BC02-4DDD-A487-89847EDF8026}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModelContextProtocolPlugin", "samples\Demos\ModelContextProtocolPlugin\ModelContextProtocolPlugin.csproj", "{801C9CE4-53AF-D2DB-E0D6-9A6BB47E9654}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1373,12 +1373,6 @@ Global
{543879BF-E2CD-6521-8322-8FBCD6EC57A0}.Publish|Any CPU.Build.0 = Release|Any CPU
{543879BF-E2CD-6521-8322-8FBCD6EC57A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{543879BF-E2CD-6521-8322-8FBCD6EC57A0}.Release|Any CPU.Build.0 = Release|Any CPU
{B16AC373-3DA8-4505-9510-110347CD635D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B16AC373-3DA8-4505-9510-110347CD635D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B16AC373-3DA8-4505-9510-110347CD635D}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
{B16AC373-3DA8-4505-9510-110347CD635D}.Publish|Any CPU.Build.0 = Debug|Any CPU
{B16AC373-3DA8-4505-9510-110347CD635D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B16AC373-3DA8-4505-9510-110347CD635D}.Release|Any CPU.Build.0 = Release|Any CPU
{BEDAC050-016A-46F4-9173-339C46DFD3ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BEDAC050-016A-46F4-9173-339C46DFD3ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BEDAC050-016A-46F4-9173-339C46DFD3ED}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
Expand All @@ -1403,6 +1397,12 @@ Global
{E9A74E0C-BC02-4DDD-A487-89847EDF8026}.Publish|Any CPU.Build.0 = Release|Any CPU
{E9A74E0C-BC02-4DDD-A487-89847EDF8026}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9A74E0C-BC02-4DDD-A487-89847EDF8026}.Release|Any CPU.Build.0 = Release|Any CPU
{801C9CE4-53AF-D2DB-E0D6-9A6BB47E9654}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{801C9CE4-53AF-D2DB-E0D6-9A6BB47E9654}.Debug|Any CPU.Build.0 = Debug|Any CPU
{801C9CE4-53AF-D2DB-E0D6-9A6BB47E9654}.Publish|Any CPU.ActiveCfg = Release|Any CPU
{801C9CE4-53AF-D2DB-E0D6-9A6BB47E9654}.Publish|Any CPU.Build.0 = Release|Any CPU
{801C9CE4-53AF-D2DB-E0D6-9A6BB47E9654}.Release|Any CPU.ActiveCfg = Release|Any CPU
{801C9CE4-53AF-D2DB-E0D6-9A6BB47E9654}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1589,11 +1589,11 @@ Global
{758457BF-87EF-D8A0-4045-9F03D3DAD0BF} = {41AC66EE-B656-4CDF-A512-C7259C2F6CF7}
{8C6EC8E2-4DC1-5B2E-F22A-CB4FD96DEF50} = {41AC66EE-B656-4CDF-A512-C7259C2F6CF7}
{543879BF-E2CD-6521-8322-8FBCD6EC57A0} = {41AC66EE-B656-4CDF-A512-C7259C2F6CF7}
{B16AC373-3DA8-4505-9510-110347CD635D} = {5D4C0700-BBB5-418F-A7B2-F392B9A18263}
{BEDAC050-016A-46F4-9173-339C46DFD3ED} = {5D4C0700-BBB5-418F-A7B2-F392B9A18263}
{0C81C377-3CDC-46A8-BED1-4B50BDA2202E} = {D6D598DF-C17C-46F4-B2B9-CDE82E2DE132}
{A5E6193C-8431-4C6E-B674-682CB41EAA0C} = {4F381919-F1BE-47D8-8558-3187ED04A84F}
{E9A74E0C-BC02-4DDD-A487-89847EDF8026} = {4F381919-F1BE-47D8-8558-3187ED04A84F}
{801C9CE4-53AF-D2DB-E0D6-9A6BB47E9654} = {5D4C0700-BBB5-418F-A7B2-F392B9A18263}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FBDC56A3-86AD-4323-AA0F-201E59123B83}
Expand Down

This file was deleted.

159 changes: 0 additions & 159 deletions dotnet/samples/Demos/ModelContextProtocol/McpDotNetExtensions.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,17 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>5ee045b0-aea3-4f08-8d31-32d1a6f8fed0</UserSecretsId>
<NoWarn>$(NoWarn);CA2249;CS0612</NoWarn>
<NoWarn>$(NoWarn);CA2249;CS0612;SKEXP0001;VSTHRD111;CA2007</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="mcpdotnet" />
<PackageReference Include="ModelContextProtocol" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" />
<PackageReference Include="Microsoft.Extensions.Logging" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" />
</ItemGroup>

<ItemGroup>
<None Update="SimpleToolsConsole.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\Connectors\Connectors.AzureOpenAI\Connectors.AzureOpenAI.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,54 @@
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using ModelContextProtocol;
using ModelContextProtocol.Client;

var config = new ConfigurationBuilder()
.AddUserSecrets<Program>()
.AddEnvironmentVariables()
.Build();

// Prepare and build kernel
var builder = Kernel.CreateBuilder();
builder.Services.AddLogging(c => c.AddDebug().SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace));

if (config["OpenAI:ApiKey"] is not null)
{
builder.Services.AddOpenAIChatCompletion(
serviceId: "openai",
modelId: config["OpenAI:ChatModelId"] ?? "gpt-4o",
apiKey: config["OpenAI:ApiKey"]!);
}
else
if (config["OpenAI:ApiKey"] is not { } apiKey)
{
Console.Error.WriteLine("Please provide a valid OpenAI:ApiKey to run this sample. See the associated README.md for more details.");
return;
}

Kernel kernel = builder.Build();

// Create an MCPClient for the GitHub server
var mcpClient = await McpDotNetExtensions.GetGitHubToolsAsync().ConfigureAwait(false);
await using var mcpClient = await McpClientFactory.CreateAsync(
new()
{
Id = "github",
Name = "GitHub",
TransportType = "stdio",
TransportOptions = new Dictionary<string, string>
{
["command"] = "npx",
["arguments"] = "-y @modelcontextprotocol/server-github",
}
},
new() { ClientInfo = new() { Name = "GitHub", Version = "1.0.0" } }).ConfigureAwait(false);

// Retrieve the list of tools available on the GitHub server
var tools = await mcpClient.ListToolsAsync().ConfigureAwait(false);
foreach (var tool in tools.Tools)
var tools = await mcpClient.GetAIFunctionsAsync().ConfigureAwait(false);
foreach (var tool in tools)
{
Console.WriteLine($"{tool.Name}: {tool.Description}");
}

// Add the MCP tools as Kernel functions
var functions = await mcpClient.MapToFunctionsAsync().ConfigureAwait(false);
kernel.Plugins.AddFromFunctions("GitHub", functions);
// Prepare and build kernel with the MCP tools as Kernel functions
var builder = Kernel.CreateBuilder();
builder.Services
.AddLogging(c => c.AddDebug().SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace))
.AddOpenAIChatCompletion(
serviceId: "openai",
modelId: config["OpenAI:ChatModelId"] ?? "gpt-4o-mini",
apiKey: apiKey);
Kernel kernel = builder.Build();
kernel.Plugins.AddFromFunctions("GitHub", tools.Select(aiFunction => aiFunction.AsKernelFunction()));

// Enable automatic function calling
var executionSettings = new OpenAIPromptExecutionSettings
OpenAIPromptExecutionSettings executionSettings = new()
{
Temperature = 0,
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ MCP is an open protocol that standardizes how applications provide context to LL

For information on Model Context Protocol (MCP) please refer to the [documentation](https://modelcontextprotocol.io/introduction).

This sample uses [mcpdotnet](https://www.nuget.org/packages/mcpdotnet) and is heavily influenced by the [samples](https://github.com/PederHP/mcpdotnet/tree/main/samples) from that repository.

The sample shows:

1. How to connect to an MCP Server using [mcpdotnet](https://www.nuget.org/packages/mcpdotnet)
1. How to connect to an MCP Server using [ModelContextProtocol](https://www.nuget.org/packages/ModelContextProtocol)
2. Retrieve the list of tools the MCP Server makes available
3. Convert the MCP tools to Semantic Kernel functions so they can be added to a Kernel instance
4. Invoke the tools from Semantic Kernel using function calling
Expand All @@ -24,7 +22,7 @@ If you have set up those credentials as secrets within Secret Manager or through
### To set your secrets with Secret Manager

```text
cd dotnet/samples/Demos/ModelContextProtocol
cd dotnet/samples/Demos/ModelContextProtocolPlugin

dotnet user-secrets init

Expand Down
Loading
Loading