.NET: Response & foundry agent hosted MCP sample (#1568)

* Adding sample demonstrating hosted MCP with Responses

* Add mcp readme.md to slnx

* Update FoundryAgent sample to use MCP types from abstraction and to show how to do approval

* Fix param name after package update.

* Fix environment variable name for consistency

* Apply suggestion from @Copilot

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

---------

Co-authored-by: Chris <66376200+crickman@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
westey
2025-11-04 15:54:20 +00:00
committed by GitHub
Unverified
parent 50d9b13bfc
commit 64fc3f381f
6 changed files with 220 additions and 31 deletions
+2
View File
@@ -68,9 +68,11 @@
<Project Path="samples/GettingStarted/AgentWithOpenAI/Agent_OpenAI_Step02_Reasoning/Agent_OpenAI_Step02_Reasoning.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/ModelContextProtocol/">
<File Path="samples/GettingStarted/ModelContextProtocol/README.md" />
<Project Path="samples/GettingStarted/ModelContextProtocol/Agent_MCP_Server/Agent_MCP_Server.csproj" />
<Project Path="samples/GettingStarted/ModelContextProtocol/Agent_MCP_Server_Auth/Agent_MCP_Server_Auth.csproj" />
<Project Path="samples/GettingStarted/ModelContextProtocol/FoundryAgent_Hosted_MCP/FoundryAgent_Hosted_MCP.csproj" />
<Project Path="samples/GettingStarted/ModelContextProtocol/ResponseAgent_Hosted_MCP/ResponseAgent_Hosted_MCP.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/Observability/">
<Project Path="samples/GettingStarted/AgentOpenTelemetry/AgentOpenTelemetry.csproj" />
@@ -1,52 +1,106 @@
// Copyright (c) Microsoft. All rights reserved.
// This sample shows how to create and use a simple AI agent with Azure Foundry Agents as the backend.
// This sample shows how to create and use a simple AI agent with Azure Foundry Agents as the backend, that uses a Hosted MCP Tool.
// In this case the Azure Foundry Agents service will invoke any MCP tools as required. MCP tools are not invoked by the Agent Framework.
// The sample first shows how to use MCP tools with auto approval, and then how to set up a tool that requires approval before it can be invoked and how to approve such a tool.
using Azure.AI.Agents.Persistent;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
var endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
var model = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_MODEL_ID") ?? "gpt-4.1-mini";
var model = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4.1-mini";
// Get a client to create/retrieve server side agents with.
var persistentAgentsClient = new PersistentAgentsClient(endpoint, new AzureCliCredential());
// **** MCP Tool with Auto Approval ****
// *************************************
// Create an MCP tool definition that the agent can use.
var mcpTool = new MCPToolDefinition(
serverLabel: "microsoft_learn",
serverUrl: "https://learn.microsoft.com/api/mcp");
mcpTool.AllowedTools.Add("microsoft_docs_search");
// Create a server side persistent agent with the Azure.AI.Agents.Persistent SDK.
var agentMetadata = await persistentAgentsClient.Administration.CreateAgentAsync(
model: model,
name: "MicrosoftLearnAgent",
instructions: "You answer questions by searching the Microsoft Learn content only.",
tools: [mcpTool]);
// Retrieve an already created server side persistent agent as an AIAgent.
AIAgent agent = await persistentAgentsClient.GetAIAgentAsync(agentMetadata.Value.Id);
// Create run options to configure the agent invocation.
var runOptions = new ChatClientAgentRunOptions()
// In this case we allow the tool to always be called without approval.
var mcpTool = new HostedMcpServerTool(
serverName: "microsoft_learn",
serverAddress: "https://learn.microsoft.com/api/mcp")
{
ChatOptions = new()
{
RawRepresentationFactory = (_) => new ThreadAndRunOptions()
{
ToolResources = new MCPToolResource(serverLabel: "microsoft_learn")
{
RequireApproval = new MCPApproval("never"),
}.ToToolResources()
}
}
AllowedTools = ["microsoft_docs_search"],
ApprovalMode = HostedMcpServerToolApprovalMode.NeverRequire
};
// Create a server side persistent agent with the mcp tool, and expose it as an AIAgent.
AIAgent agent = await persistentAgentsClient.CreateAIAgentAsync(
model: model,
options: new()
{
Name = "MicrosoftLearnAgent",
Instructions = "You answer questions by searching the Microsoft Learn content only.",
ChatOptions = new()
{
Tools = [mcpTool]
},
});
// You can then invoke the agent like any other AIAgent.
AgentThread thread = agent.GetNewThread();
var response = await agent.RunAsync("Please summarize the Azure AI Agent documentation related to MCP Tool calling?", thread, runOptions);
Console.WriteLine(response);
Console.WriteLine(await agent.RunAsync("Please summarize the Azure AI Agent documentation related to MCP Tool calling?", thread));
// Cleanup for sample purposes.
await persistentAgentsClient.Administration.DeleteAgentAsync(agent.Id);
// **** MCP Tool with Approval Required ****
// *****************************************
// Create an MCP tool definition that the agent can use.
// In this case we require approval before the tool can be called.
var mcpToolWithApproval = new HostedMcpServerTool(
serverName: "microsoft_learn",
serverAddress: "https://learn.microsoft.com/api/mcp")
{
AllowedTools = ["microsoft_docs_search"],
ApprovalMode = HostedMcpServerToolApprovalMode.AlwaysRequire
};
// Create an agent based on Azure OpenAI Responses as the backend.
AIAgent agentWithRequiredApproval = await persistentAgentsClient.CreateAIAgentAsync(
model: model,
options: new()
{
Name = "MicrosoftLearnAgentWithApproval",
Instructions = "You answer questions by searching the Microsoft Learn content only.",
ChatOptions = new()
{
Tools = [mcpToolWithApproval]
},
});
// You can then invoke the agent like any other AIAgent.
var threadWithRequiredApproval = agentWithRequiredApproval.GetNewThread();
var response = await agentWithRequiredApproval.RunAsync("Please summarize the Azure AI Agent documentation related to MCP Tool calling?", threadWithRequiredApproval);
var userInputRequests = response.UserInputRequests.ToList();
while (userInputRequests.Count > 0)
{
// Ask the user to approve each MCP call request.
// For simplicity, we are assuming here that only MCP approval requests are being made.
var userInputResponses = userInputRequests
.OfType<McpServerToolApprovalRequestContent>()
.Select(approvalRequest =>
{
Console.WriteLine($"""
The agent would like to invoke the following MCP Tool, please reply Y to approve.
ServerName: {approvalRequest.ToolCall.ServerName}
Name: {approvalRequest.ToolCall.ToolName}
Arguments: {string.Join(", ", approvalRequest.ToolCall.Arguments?.Select(x => $"{x.Key}: {x.Value}") ?? [])}
""");
return new ChatMessage(ChatRole.User, [approvalRequest.CreateResponse(Console.ReadLine()?.Equals("Y", StringComparison.OrdinalIgnoreCase) ?? false)]);
})
.ToList();
// Pass the user input responses back to the agent for further processing.
response = await agentWithRequiredApproval.RunAsync(userInputResponses, threadWithRequiredApproval);
userInputRequests = response.UserInputRequests.ToList();
}
Console.WriteLine($"\nAgent: {response}");
@@ -21,6 +21,7 @@ Before you begin, ensure you have the following prerequisites:
|---|---|
|[Agent with MCP server tools](./Agent_MCP_Server/)|This sample demonstrates how to use MCP server tools with a simple agent|
|[Agent with MCP server tools and authorization](./Agent_MCP_Server_Auth/)|This sample demonstrates how to use MCP Server tools from a protected MCP server with a simple agent|
|[Responses Agent with Hosted MCP tool](./ResponseAgent_Hosted_MCP/)|This sample demonstrates how to use the Hosted MCP tool with the Responses Service, where the service invokes any MCP tools directly|
## Running the samples from the console
@@ -0,0 +1,95 @@
// Copyright (c) Microsoft. All rights reserved.
// This sample shows how to create and use a simple AI agent with OpenAI Responses as the backend, that uses a Hosted MCP Tool.
// In this case the OpenAI responses service will invoke any MCP tools as required. MCP tools are not invoked by the Agent Framework.
// The sample first shows how to use MCP tools with auto approval, and then how to set up a tool that requires approval before it can be invoked and how to approve such a tool.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
// **** MCP Tool with Auto Approval ****
// *************************************
// Create an MCP tool definition that the agent can use.
// In this case we allow the tool to always be called without approval.
var mcpTool = new HostedMcpServerTool(
serverName: "microsoft_learn",
serverAddress: "https://learn.microsoft.com/api/mcp")
{
AllowedTools = ["microsoft_docs_search"],
ApprovalMode = HostedMcpServerToolApprovalMode.NeverRequire
};
// Create an agent based on Azure OpenAI Responses as the backend.
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName)
.CreateAIAgent(
instructions: "You answer questions by searching the Microsoft Learn content only.",
name: "MicrosoftLearnAgent",
tools: [mcpTool]);
// You can then invoke the agent like any other AIAgent.
AgentThread thread = agent.GetNewThread();
Console.WriteLine(await agent.RunAsync("Please summarize the Azure AI Agent documentation related to MCP Tool calling?", thread));
// **** MCP Tool with Approval Required ****
// *****************************************
// Create an MCP tool definition that the agent can use.
// In this case we require approval before the tool can be called.
var mcpToolWithApproval = new HostedMcpServerTool(
serverName: "microsoft_learn",
serverAddress: "https://learn.microsoft.com/api/mcp")
{
AllowedTools = ["microsoft_docs_search"],
ApprovalMode = HostedMcpServerToolApprovalMode.AlwaysRequire
};
// Create an agent based on Azure OpenAI Responses as the backend.
AIAgent agentWithRequiredApproval = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName)
.CreateAIAgent(
instructions: "You answer questions by searching the Microsoft Learn content only.",
name: "MicrosoftLearnAgentWithApproval",
tools: [mcpToolWithApproval]);
// You can then invoke the agent like any other AIAgent.
var threadWithRequiredApproval = agentWithRequiredApproval.GetNewThread();
var response = await agentWithRequiredApproval.RunAsync("Please summarize the Azure AI Agent documentation related to MCP Tool calling?", threadWithRequiredApproval);
var userInputRequests = response.UserInputRequests.ToList();
while (userInputRequests.Count > 0)
{
// Ask the user to approve each MCP call request.
// For simplicity, we are assuming here that only MCP approval requests are being made.
var userInputResponses = userInputRequests
.OfType<McpServerToolApprovalRequestContent>()
.Select(approvalRequest =>
{
Console.WriteLine($"""
The agent would like to invoke the following MCP Tool, please reply Y to approve.
ServerName: {approvalRequest.ToolCall.ServerName}
Name: {approvalRequest.ToolCall.ToolName}
Arguments: {string.Join(", ", approvalRequest.ToolCall.Arguments?.Select(x => $"{x.Key}: {x.Value}") ?? [])}
""");
return new ChatMessage(ChatRole.User, [approvalRequest.CreateResponse(Console.ReadLine()?.Equals("Y", StringComparison.OrdinalIgnoreCase) ?? false)]);
})
.ToList();
// Pass the user input responses back to the agent for further processing.
response = await agentWithRequiredApproval.RunAsync(userInputResponses, threadWithRequiredApproval);
userInputRequests = response.UserInputRequests.ToList();
}
Console.WriteLine($"\nAgent: {response}");
@@ -0,0 +1,17 @@
# Prerequisites
Before you begin, ensure you have the following prerequisites:
- .NET 8.0 SDK or later
- Azure OpenAI service endpoint and deployment configured
- Azure CLI installed and authenticated (for Azure credential authentication)
- User has the `Cognitive Services OpenAI Contributor` role for the Azure OpenAI resource.
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure OpenAI resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
Set the following environment variables:
```powershell
$env:AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/" # Replace with your Azure OpenAI resource endpoint
$env:AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4.1-mini" # Optional, defaults to gpt-4.1-mini
```
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>