In the previous post, we added a function tool to a Microsoft Agent Framework agent. The function was implemented inside our .NET application, which works well when the capability belongs to the application itself.
But what if the capability is provided by another service? This is where the Model Context Protocol (MCP) is useful. An MCP server can expose tools and their descriptions through a standard protocol. Our agent can discover those tools at runtime and invoke them without us writing a separate integration for every tool.
In this post, we are going to connect our Agent Framework agent to the public Microsoft Learn MCP Server. The agent will discover the available documentation tools and use them to answer a Microsoft Graph question with current information from Microsoft Learn.
What we are building
- Create a .NET console application.
- Connect an MCP client to a remote MCP server.
- Discover the tools exposed by the server.
- Make those tools available to an Agent Framework agent.
- Ask a question that requires current Microsoft documentation.
- Let Agent Framework handle the MCP tool call and its result.
Before you start
You will need:
- .NET 10 SDK. Agent Framework supports .NET 8 or later; I am using .NET 10 for this example.
- An Azure subscription.
- A Microsoft Foundry project.
- A model deployment that supports function calling.
- An identity with permission to use the Foundry project and model.
We will use the public Microsoft Learn MCP Server at
https://learn.microsoft.com/api/mcp. It uses
Streamable HTTP and does not require authentication.
1) Create the .NET project
Create a new console application:
dotnet new console -n AgentWithMCP --framework net10.0
cd AgentWithMCP
2) Install the required packages
Install the Agent Framework Foundry integration, Azure authentication, and the official MCP C# SDK:
dotnet add package Microsoft.Agents.AI.Foundry
dotnet add package Azure.Identity
dotnet add package ModelContextProtocol
ModelContextProtocol provides the MCP client and
transports. The MCP tools it discovers are compatible with the
AITool abstraction from
Microsoft.Extensions.AI.
3) Where MCP fits
The request in this example follows this path:
User
-> Microsoft Agent Framework agent
-> MCP client
-> Microsoft Learn MCP Server
-> Microsoft Learn content
The agent still decides when a tool is needed. The difference from our previous post is where the tool comes from. Instead of defining the function in our application, we discover it from an MCP server.
MCP is the capability boundary. The agent does not need custom code for the Microsoft Learn search, fetch, and code sample operations.
4) Connect to the MCP server
Create an HttpClientTransport with the MCP endpoint,
then use it to create an McpClient:
const string mcpEndpoint = "https://learn.microsoft.com/api/mcp?maxTokenBudget=2000";
await using McpClient mcpClient = await McpClient.CreateAsync(
new HttpClientTransport(new()
{
Endpoint = new Uri(mcpEndpoint),
Name = "Microsoft Learn MCP"
}));
The Microsoft Learn MCP Server uses Streamable HTTP. The C# SDK negotiates the connection and handles the MCP protocol messages for us.
I have also added maxTokenBudget=2000 to limit the
amount of content returned by search operations. This is useful when tools
are called inside an agent loop because tool results consume context tokens.
5) Discover the MCP tools
MCP tools should be discovered at runtime rather than hardcoded. Call
ListToolsAsync after connecting:
IList<McpClientTool> mcpTools = await mcpClient.ListToolsAsync();
Console.WriteLine("MCP tools available:");
foreach (McpClientTool tool in mcpTools)
{
Console.WriteLine($"- {tool.Name}: {tool.Description}");
}
At the time of writing, the server returns these tools:
microsoft_docs_searchmicrosoft_docs_fetchmicrosoft_code_sample_search
The important part is that our application does not define this list. The MCP server supplies each tool's name, description, and input schema. If the server adds or changes tools, the client can discover the current contract the next time it connects.
6) Make the MCP tools available to the agent
Convert the discovered tools to AITool and pass them
to the agent:
AIAgent agent = projectClient.AsAIAgent(
model: modelDeployment,
instructions: instructions,
name: "MicrosoftLearnAssistant",
tools: [.. mcpTools.Cast<AITool>()]);
This is the bridge between MCP and Agent Framework. The model sees the tool descriptions discovered from the server and can decide which tool to call based on the user's question.
We will use the following instructions:
const string instructions = """
You help developers find current information in Microsoft Learn.
Always use the available Microsoft Learn tools before answering.
Base the answer on the tool results and include relevant Microsoft Learn links.
""";
7) Complete working example
Here is the complete Program.cs:
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using ModelContextProtocol.Client;
string endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
string modelDeployment = Environment.GetEnvironmentVariable("FOUNDRY_MODEL")
?? throw new InvalidOperationException("FOUNDRY_MODEL is not set.");
const string mcpEndpoint = "https://learn.microsoft.com/api/mcp?maxTokenBudget=2000";
Console.WriteLine($"Connecting to MCP server at {mcpEndpoint} ...");
await using McpClient mcpClient = await McpClient.CreateAsync(
new HttpClientTransport(new()
{
Endpoint = new Uri(mcpEndpoint),
Name = "Microsoft Learn MCP"
}));
IList<McpClientTool> mcpTools = await mcpClient.ListToolsAsync();
Console.WriteLine("MCP tools available:");
foreach (McpClientTool tool in mcpTools)
{
Console.WriteLine($"- {tool.Name}: {tool.Description}");
}
DefaultAzureCredential credential = new(new DefaultAzureCredentialOptions
{
ExcludeManagedIdentityCredential = true
});
AIProjectClient projectClient = new(new Uri(endpoint), credential);
const string instructions = """
You help developers find current information in Microsoft Learn.
Always use the available Microsoft Learn tools before answering.
Base the answer on the tool results and include relevant Microsoft Learn links.
""";
AIAgent agent = projectClient.AsAIAgent(
model: modelDeployment,
instructions: instructions,
name: "MicrosoftLearnAssistant",
tools: [.. mcpTools.Cast<AITool>()]);
const string prompt = "How do I authenticate a .NET application to Microsoft Graph? Summarize the recommended options.";
Console.WriteLine($"\nUser: {prompt}\n");
Console.WriteLine($"Agent: {await agent.RunAsync(prompt)}");
8) Configure and run the application
The sample reads the Foundry project endpoint and model deployment name from environment variables. In PowerShell, set them like this:
$env:FOUNDRY_PROJECT_ENDPOINT="YOUR_FOUNDRY_PROJECT_ENDPOINT"
$env:FOUNDRY_MODEL="YOUR_MODEL_DEPLOYMENT_NAME"
The model must support function calling. The sample uses
DefaultAzureCredential, so sign in with the Azure CLI
for local development:
az login
dotnet run
The console first shows the tools discovered from the MCP server:
Connecting to MCP server at https://learn.microsoft.com/api/mcp?maxTokenBudget=2000 ...
MCP tools available:
- microsoft_docs_search: Search official Microsoft/Azure documentation...
- microsoft_code_sample_search: Search for code snippets and examples...
- microsoft_docs_fetch: Fetch a Microsoft Learn documentation webpage...
The agent then uses those tools and returns a summary with links to the relevant Microsoft Learn pages. The exact response and tools selected can vary based on the model and the current tool descriptions.
9) What happens during the MCP tool call
The request goes through the following steps:
- The MCP client connects to the Microsoft Learn MCP Server.
-
ListToolsAsyncretrieves the current tool names, descriptions, and parameter schemas. - The discovered tools are supplied to the Agent Framework agent.
- The user asks a question about Microsoft Graph authentication.
- The model selects a Microsoft Learn tool and supplies its arguments.
- The MCP client sends the tool call to the remote server.
- The server returns the tool result to the MCP client.
- Agent Framework gives the result back to the model.
- The model uses the result to produce the final answer.
We do not need to call microsoft_docs_search directly
or parse its response in our application. The discovered
McpClientTool handles the MCP invocation, and Agent
Framework includes the result in the agent's function-calling loop.
Local and remote MCP servers
This example uses a remote server over Streamable HTTP. MCP also supports local servers over standard input and output, usually called stdio transport.
- Streamable HTTP: useful for remote services shared by multiple clients.
- stdio: useful when the client starts and communicates with a local server process.
The tools still reach the agent as AITool instances.
Only the transport and connection configuration change.
Authentication and security
The Microsoft Learn MCP Server does not require authentication, which keeps
this first example small. Business-system MCP servers commonly require OAuth,
bearer tokens, API keys, or custom headers. The MCP C# SDK supports configuring
authentication through the HTTP transport and a configured
HttpClient.
Treat an MCP server like any other external integration. Only connect to servers you trust, expose only the tools the agent needs, validate sensitive tool arguments, and require approval before actions that create, update, delete, or send data. Never place access tokens directly in source code.
MCP standardizes discovery and invocation. It does not remove our responsibility to authenticate users, authorize operations, and protect data.
Wrapping up
In this post, we connected a Microsoft Agent Framework agent to a remote MCP server. The MCP client discovered the server's tools at runtime, Agent Framework exposed them to the model, and the model used the returned tool results to answer a question with current Microsoft Learn information.
This gives us a clean way to add capabilities that live outside our application. In the next post, we will connect an Agent Framework agent to Microsoft Graph and use Microsoft 365 data to answer a user request.
Hope this helps!







