From 406a8560c6df0cc0d4050565b5bfbfb90cffc8b1 Mon Sep 17 00:00:00 2001 From: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com> Date: Wed, 12 Nov 2025 19:52:05 +0000 Subject: [PATCH] .NET: Add AgentWithHostedMCP sample (#2129) * add AgentWithHostedMCP sample * Update dotnet/samples/HostedAgents/AgentWithHostedMCP/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/samples/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/samples/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/samples/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Use explicit type for mcpTool --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- dotnet/agent-framework-dotnet.slnx | 1 + .../AgentWithHostedMCP.csproj | 69 +++++++++++++++++++ .../AgentWithHostedMCP/Dockerfile | 20 ++++++ .../AgentWithHostedMCP/Program.cs | 34 +++++++++ .../HostedAgents/AgentWithHostedMCP/README.md | 43 ++++++++++++ .../AgentWithHostedMCP/agent.yaml | 29 ++++++++ .../AgentWithHostedMCP/run-requests.http | 30 ++++++++ .../AgentWithTextSearchRag/agent.yaml | 5 +- .../HostedAgents/AgentsInWorkflows/agent.yaml | 7 +- 9 files changed, 232 insertions(+), 6 deletions(-) create mode 100644 dotnet/samples/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj create mode 100644 dotnet/samples/HostedAgents/AgentWithHostedMCP/Dockerfile create mode 100644 dotnet/samples/HostedAgents/AgentWithHostedMCP/Program.cs create mode 100644 dotnet/samples/HostedAgents/AgentWithHostedMCP/README.md create mode 100644 dotnet/samples/HostedAgents/AgentWithHostedMCP/agent.yaml create mode 100644 dotnet/samples/HostedAgents/AgentWithHostedMCP/run-requests.http diff --git a/dotnet/agent-framework-dotnet.slnx b/dotnet/agent-framework-dotnet.slnx index 6009e00f00..25030bedcc 100644 --- a/dotnet/agent-framework-dotnet.slnx +++ b/dotnet/agent-framework-dotnet.slnx @@ -162,6 +162,7 @@ + diff --git a/dotnet/samples/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj b/dotnet/samples/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj new file mode 100644 index 0000000000..3130cda647 --- /dev/null +++ b/dotnet/samples/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj @@ -0,0 +1,69 @@ + + + + Exe + net9.0 + + enable + enable + + + false + + + + + + + + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/dotnet/samples/HostedAgents/AgentWithHostedMCP/Dockerfile b/dotnet/samples/HostedAgents/AgentWithHostedMCP/Dockerfile new file mode 100644 index 0000000000..776f81041e --- /dev/null +++ b/dotnet/samples/HostedAgents/AgentWithHostedMCP/Dockerfile @@ -0,0 +1,20 @@ +# Build the application +FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build +WORKDIR /src + +# Copy files from the current directory on the host to the working directory in the container +COPY . . + +RUN dotnet restore +RUN dotnet build -c Release --no-restore +RUN dotnet publish -c Release --no-build -o /app + +# Run the application +FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final +WORKDIR /app + +# Copy everything needed to run the app from the "build" stage. +COPY --from=build /app . + +EXPOSE 8088 +ENTRYPOINT ["dotnet", "AgentWithHostedMCP.dll"] diff --git a/dotnet/samples/HostedAgents/AgentWithHostedMCP/Program.cs b/dotnet/samples/HostedAgents/AgentWithHostedMCP/Program.cs new file mode 100644 index 0000000000..d6bfca7bf7 --- /dev/null +++ b/dotnet/samples/HostedAgents/AgentWithHostedMCP/Program.cs @@ -0,0 +1,34 @@ +// 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 demonstrates how to use MCP tools with auto approval by setting ApprovalMode to NeverRequire. + +using Azure.AI.AgentServer.AgentFramework.Extensions; +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"; + +// Create an MCP tool that can be called without approval. +AITool mcpTool = new HostedMcpServerTool(serverName: "microsoft_learn", serverAddress: "https://learn.microsoft.com/api/mcp") +{ + AllowedTools = ["microsoft_docs_search"], + ApprovalMode = HostedMcpServerToolApprovalMode.NeverRequire +}; + +// Create an agent with the MCP tool using Azure OpenAI Responses. +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]); + +await agent.RunAIAgentAsync(); diff --git a/dotnet/samples/HostedAgents/AgentWithHostedMCP/README.md b/dotnet/samples/HostedAgents/AgentWithHostedMCP/README.md new file mode 100644 index 0000000000..a5648d7ac9 --- /dev/null +++ b/dotnet/samples/HostedAgents/AgentWithHostedMCP/README.md @@ -0,0 +1,43 @@ +# What this sample demonstrates + +This sample demonstrates how to use a Hosted Model Context Protocol (MCP) server with an AI agent. +The agent connects to the Microsoft Learn MCP server to search documentation and answer questions using official Microsoft content. + +Key features: +- Configuring MCP tools with automatic approval (no user confirmation required) +- Filtering available tools from an MCP server +- Using Azure OpenAI Responses with MCP tools + +## Prerequisites + +Before running this sample, ensure you have: + +1. An Azure OpenAI endpoint configured +2. A deployment of a chat model (e.g., gpt-4o-mini) +3. Azure CLI installed and authenticated + +**Note**: This sample uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure OpenAI resource. + +## Environment Variables + +Set the following environment variables: + +```powershell +# Replace with your Azure OpenAI endpoint +$env:AZURE_OPENAI_ENDPOINT="https://your-openai-resource.openai.azure.com/" + +# Optional, defaults to gpt-4o-mini +$env:AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini" +``` + +## How It Works + +The sample connects to the Microsoft Learn MCP server and uses its documentation search capabilities: + +1. The agent is configured with a HostedMcpServerTool pointing to `https://learn.microsoft.com/api/mcp` +2. Only the `microsoft_docs_search` tool is enabled from the available MCP tools +3. Approval mode is set to `NeverRequire`, allowing automatic tool execution +4. When you ask questions, Azure OpenAI Responses automatically invokes the MCP tool to search documentation +5. The agent returns answers based on the Microsoft Learn content + +In this configuration, the OpenAI Responses service manages tool invocation directly - the Agent Framework does not handle MCP tool calls. diff --git a/dotnet/samples/HostedAgents/AgentWithHostedMCP/agent.yaml b/dotnet/samples/HostedAgents/AgentWithHostedMCP/agent.yaml new file mode 100644 index 0000000000..1a484bfade --- /dev/null +++ b/dotnet/samples/HostedAgents/AgentWithHostedMCP/agent.yaml @@ -0,0 +1,29 @@ +name: AgentWithHostedMCP +displayName: "Microsoft Learn Response Agent with MCP" +description: > + An AI agent that uses Azure OpenAI Responses with a Hosted Model Context Protocol (MCP) server. + The agent answers questions by searching Microsoft Learn documentation using MCP tools. + This demonstrates how MCP tools can be integrated with Azure OpenAI Responses where the service + itself handles tool invocation. +metadata: + authors: + - Microsoft Agent Framework Team + tags: + - Microsoft Agent Framework + - Model Context Protocol + - MCP +template: + kind: hosted + name: AgentWithHostedMCP + protocols: + - protocol: responses + version: v1 + environment_variables: + - name: AZURE_OPENAI_ENDPOINT + value: ${AZURE_OPENAI_ENDPOINT} + - name: AZURE_OPENAI_DEPLOYMENT_NAME + value: gpt-4o-mini +resources: + - name: "gpt-4o-mini" + kind: model + id: gpt-4o-mini diff --git a/dotnet/samples/HostedAgents/AgentWithHostedMCP/run-requests.http b/dotnet/samples/HostedAgents/AgentWithHostedMCP/run-requests.http new file mode 100644 index 0000000000..cc26f43b90 --- /dev/null +++ b/dotnet/samples/HostedAgents/AgentWithHostedMCP/run-requests.http @@ -0,0 +1,30 @@ +@host = http://localhost:8088 +@endpoint = {{host}}/responses + +### Health Check +GET {{host}}/readiness + +### Simple string input - Ask about MCP Tools +POST {{endpoint}} +Content-Type: application/json +{ + "input": "Please summarize the Azure AI Agent documentation related to MCP Tool calling?" +} + +### Explicit input - Ask about Agent Framework +POST {{endpoint}} +Content-Type: application/json +{ + "input": [ + { + "type": "message", + "role": "user", + "content": [ + { + "type": "input_text", + "text": "What is the Microsoft Agent Framework?" + } + ] + } + ] +} diff --git a/dotnet/samples/HostedAgents/AgentWithTextSearchRag/agent.yaml b/dotnet/samples/HostedAgents/AgentWithTextSearchRag/agent.yaml index 35a8582c1a..78e45e9c56 100644 --- a/dotnet/samples/HostedAgents/AgentWithTextSearchRag/agent.yaml +++ b/dotnet/samples/HostedAgents/AgentWithTextSearchRag/agent.yaml @@ -10,8 +10,9 @@ metadata: authors: - Microsoft Agent Framework Team tags: - - example - - Agent Framework + - Microsoft Agent Framework + - Retrieval-Augmented Generation + - RAG template: kind: hosted name: AgentWithTextSearchRag diff --git a/dotnet/samples/HostedAgents/AgentsInWorkflows/agent.yaml b/dotnet/samples/HostedAgents/AgentsInWorkflows/agent.yaml index bf706f9925..5e9360efd9 100644 --- a/dotnet/samples/HostedAgents/AgentsInWorkflows/agent.yaml +++ b/dotnet/samples/HostedAgents/AgentsInWorkflows/agent.yaml @@ -6,11 +6,10 @@ description: > to English, leveraging AI-powered translation capabilities in a pipeline workflow. metadata: authors: - - Agent Framework Team - tags: - - example - Microsoft Agent Framework Team - - workflows + tags: + - Microsoft Agent Framework + - Workflows template: kind: hosted name: AgentsInWorkflows