.NET: AI agent as an MCP tool (#612)

* add sample demostrating how to expose ai-agent as an mcp tool

* Update dotnet/samples/GettingStarted/Agents/Agent_Step10_AsMcpTool/Program.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update dotnet/samples/GettingStarted/Agents/README.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* remove threadId parameter

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
SergeyMenshykh
2025-09-05 10:57:30 +01:00
committed by GitHub
Unverified
parent 40ab6e9d67
commit dbc961c869
7 changed files with 137 additions and 0 deletions
+1
View File
@@ -76,6 +76,7 @@
<PackageVersion Include="Microsoft.Agents.CopilotStudio.Client" Version="1.1.151" />
<PackageVersion Include="A2A" Version="0.1.0-preview.2" />
<PackageVersion Include="A2A.AspNetCore" Version="0.1.0-preview.2" />
<PackageVersion Include="ModelContextProtocol" Version="0.3.0-preview.4" />
<!-- Inference SDKs -->
<PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI" Version="0.9.0" />
<!-- Identity -->
+1
View File
@@ -40,6 +40,7 @@
<Project Path="samples/GettingStarted/Agents/Agent_Step07_3rdPartyThreadStorage/Agent_Step07_3rdPartyThreadStorage.csproj" />
<Project Path="samples/GettingStarted/Agents/Agent_Step08_Telemetry/Agent_Step08_Telemetry.csproj" />
<Project Path="samples/GettingStarted/Agents/Agent_Step09_DependencyInjection/Agent_Step09_DependencyInjection.csproj" />
<Project Path="samples/GettingStarted/Agents/Agent_Step10_AsMcpTool/Agent_Step10_AsMcpTool.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/AgentWithOpenAI/">
<Project Path="samples/GettingStarted/AgentWithOpenAI/Agent_OpenAI_Step01_Running/Agent_OpenAI_Step01_Running.csproj" />
@@ -0,0 +1,42 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.AI.Agents;
using ModelContextProtocol.Server;
namespace Agent_Step10_AsMcpTool;
/// <summary>
/// Contains extension methods for <see cref="AIAgent"/>.
/// </summary>
internal static class AIAgentExtensions
{
/// <summary>
/// Exposes an <see cref="AIAgent"/> as a <see cref="McpServerTool"/> that can be registered with an MCP server.
/// </summary>
/// <param name="agent">The agent to expose as an MCP tool.</param>
/// <param name="title">A human-readable title for the tool that can be displayed to users. If not provided, the tool name or agent name will be used.</param>
/// <param name="name">The tool name to use. If not provided, the agent's name will be used.</param>
/// <param name="description">The tool description to use. If not provided, the agent's description will be used.</param>
/// <returns>The <see cref="McpServerTool"/> that wraps the agent.</returns>
public static McpServerTool AsMcpTool(this AIAgent agent, string? title = null, string? name = null, string? description = null)
{
async Task<string> RunAgentAsync(
[Description("Available information that will guide in performing this operation.")] string query,
CancellationToken cancellationToken = default)
{
AgentRunResponse response = await agent.RunAsync(query, cancellationToken: cancellationToken);
return response.ToString();
}
return McpServerTool.Create(RunAgentAsync, new McpServerToolCreateOptions()
{
Title = title ?? name ?? agent.Name,
Name = name ?? agent.Name,
Description = description ?? agent.Description
});
}
}
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>12</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<UserSecretsId>3afc9b74-af74-4d8e-ae96-fa1c511d11ac</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.Agents.Persistent" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="ModelContextProtocol" />
<PackageReference Include="System.Net.ServerSentEvents" VersionOverride="10.0.0-preview.4.25258.110" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Extensions.AI.Agents.AzureAI\Microsoft.Extensions.AI.Agents.AzureAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Extensions.AI.Agents\Microsoft.Extensions.AI.Agents.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,37 @@
// Copyright (c) Microsoft. All rights reserved.
// This sample shows how to expose an AI agent as an MCP tool.
using System;
using Agent_Step10_AsMcpTool;
using Azure.AI.Agents.Persistent;
using Azure.Identity;
using Microsoft.Extensions.AI.Agents;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
const string JokerName = "Joker";
const string JokerInstructions = "You are good at telling jokes, and you always start each joke with 'Aye aye, captain!'.";
var persistentAgentsClient = new PersistentAgentsClient(endpoint, new AzureCliCredential());
// Create a server side persistent agent
var agentMetadata = await persistentAgentsClient.Administration.CreateAgentAsync(
model: deploymentName,
name: JokerName,
instructions: JokerInstructions);
// Retrieve the server side persistent agent as an AIAgent.
AIAgent agent = await persistentAgentsClient.GetAIAgentAsync(agentMetadata.Value.Id);
// Register the MCP server with StdIO transport and expose the agent as an MCP tool.
HostApplicationBuilder builder = Host.CreateEmptyApplicationBuilder(settings: null);
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithTools([agent.AsMcpTool()]);
await builder.Build().RunAsync();
@@ -0,0 +1,29 @@
This sample demonstrates how to expose an existing AI agent as an MCP tool.
## Run the sample
To run the sample, please use one of the following MCP clients: https://modelcontextprotocol.io/clients
Alternatively, use the QuickstartClient sample from this repository: https://github.com/modelcontextprotocol/csharp-sdk/tree/main/samples/QuickstartClient
## Run the sample using MCP Inspector
To use the [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector), follow these steps:
1. Open a terminal in the Agent_Step10_AsMcpTool project directory.
1. Run the `npx @modelcontextprotocol/inspector dotnet run` command to start the MCP Inspector. Make sure you have [node.js](https://nodejs.org/en/download/) and npm installed.
```bash
npx @modelcontextprotocol/inspector dotnet run
```
1. When the inspector is running, it will display a URL in the terminal, like this:
```
MCP Inspector is up and running at http://127.0.0.1:6274
```
1. Open a web browser and navigate to the URL displayed in the terminal. If not opened automatically, this will open the MCP Inspector interface.
1. In the MCP Inspector interface, add the following environment variables to allow your MCP server to access Azure AI Foundry Project to create and run the agent:
- AZURE_FOUNDRY_PROJECT_ENDPOINT = https://your-resource.openai.azure.com/ # Replace with your Azure AI Foundry Project endpoint
- AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME = gpt-4o-mini # Replace with your model deployment name
1. Find and click the `Connect` button in the MCP Inspector interface to connect to the MCP server.
1. As soon as the connection is established, open the `Tools` tab in the MCP Inspector interface and select the `Joker` tool from the list.
1. Specify your prompt as a value for the `query` argument, for example: `Tell me a joke about a pirate` and click the `Run Tool` button to run the tool.
1. The agent will process the request and return a response in accordance with the provided instructions that instruct it to always start each joke with 'Aye aye, captain!'.
@@ -35,6 +35,7 @@ Before you begin, ensure you have the following prerequisites:
|[3rd party thread storage with a simple agent](./Agent_Step07_3rdPartyThreadStorage/)|This sample demonstrates how to store conversation history in a 3rd party storage solution|
|[Telemetry with a simple agent](./Agent_Step08_Telemetry/)|This sample demonstrates how to add telemetry to a simple agent|
|[Dependency injection with a simple agent](./Agent_Step09_DependencyInjection/)|This sample demonstrates how to add and resolve an agent with a dependency injection container|
|[Exposing a simple agent as MCP tool](./Agent_Step10_AsMcpTool/)|This sample demonstrates how to expose an agent as an MCP tool|
## Running the samples from the console