Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -25,7 +25,7 @@
<PackageVersion Include="Dapr.AspNetCore" Version="1.14.0" />
<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 @@ -483,12 +483,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessFramework.Aspire.Tra
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Agents.Bedrock", "src\Agents\Bedrock\Agents.Bedrock.csproj", "{8C658E1E-83C8-4127-B8BF-27A638A45DDD}"
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}") = "SqlServerIntegrationTests", "src\VectorDataIntegrationTests\SqlServerIntegrationTests\SqlServerIntegrationTests.csproj", "{A5E6193C-8431-4C6E-B674-682CB41EAA0C}"
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 @@ -1324,12 +1324,6 @@ Global
{8C658E1E-83C8-4127-B8BF-27A638A45DDD}.Publish|Any CPU.Build.0 = Publish|Any CPU
{8C658E1E-83C8-4127-B8BF-27A638A45DDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C658E1E-83C8-4127-B8BF-27A638A45DDD}.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
{A5E6193C-8431-4C6E-B674-682CB41EAA0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5E6193C-8431-4C6E-B674-682CB41EAA0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5E6193C-8431-4C6E-B674-682CB41EAA0C}.Publish|Any CPU.ActiveCfg = Debug|Any CPU
Expand All @@ -1342,6 +1336,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 @@ -1522,9 +1522,9 @@ Global
{37381352-4F10-427F-AB8A-51FEAB265201} = {3F260A77-B6C9-97FD-1304-4B34DA936CF4}
{DAD5FC6A-8CA0-43AC-87E1-032DFBD6B02A} = {3F260A77-B6C9-97FD-1304-4B34DA936CF4}
{8C658E1E-83C8-4127-B8BF-27A638A45DDD} = {6823CD5E-2ABE-41EB-B865-F86EC13F0CF9}
{B16AC373-3DA8-4505-9510-110347CD635D} = {5D4C0700-BBB5-418F-A7B2-F392B9A18263}
{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
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(KernelFunction.FromAIFunction));

// 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 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) 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
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -13,12 +14,6 @@
namespace Microsoft.SemanticKernel.ChatCompletion;

/// <summary>Provides a <see cref="KernelFunction"/> that wraps an <see cref="AIFunction"/>.</summary>
/// <remarks>
/// The implementation of <see cref="ChatCompletionServiceChatClient"/> only manufactures these to pass along to the underlying
/// <see cref="IChatCompletionService"/> with autoInvoke:false, which means the <see cref="IChatCompletionService"/>
/// implementation shouldn't be invoking these functions at all. As such, the <see cref="InvokeCoreAsync"/> and
/// <see cref="InvokeStreamingCoreAsync"/> methods both unconditionally throw, even though they could be implemented.
/// </remarks>
internal sealed class AIFunctionKernelFunction : KernelFunction
{
private readonly AIFunction _aiFunction;
Expand Down Expand Up @@ -50,16 +45,18 @@ public override KernelFunction Clone(string pluginName)
return new AIFunctionKernelFunction(this, pluginName);
}

protected override ValueTask<FunctionResult> InvokeCoreAsync(Kernel kernel, KernelArguments arguments, CancellationToken cancellationToken)
protected override async ValueTask<FunctionResult> InvokeCoreAsync(
Kernel kernel, KernelArguments arguments, CancellationToken cancellationToken)
{
// This should never be invoked, as instances are always passed with autoInvoke:false.
throw new NotSupportedException();
object? result = await this._aiFunction.InvokeAsync(arguments, cancellationToken).ConfigureAwait(false);
return new FunctionResult(this, result);
}

protected override IAsyncEnumerable<TResult> InvokeStreamingCoreAsync<TResult>(Kernel kernel, KernelArguments arguments, CancellationToken cancellationToken)
protected override async IAsyncEnumerable<TResult> InvokeStreamingCoreAsync<TResult>(
Kernel kernel, KernelArguments arguments, [EnumeratorCancellation] CancellationToken cancellationToken)
{
// This should never be invoked, as instances are always passed with autoInvoke:false.
throw new NotSupportedException();
object? result = await this._aiFunction.InvokeAsync(arguments, cancellationToken).ConfigureAwait(false);
yield return (TResult)result!;
}

private static IReadOnlyList<KernelParameterMetadata> MapParameterMetadata(AIFunction aiFunction)
Expand Down
Loading
Loading