Build a Frontend for your Microsoft Agent Framework Agents with AG-UI
TL;DR
Learn to build a frontend for Microsoft Agent Framework agents using AG-UI and CopilotKit. This guide covers setup, backend integration, and frontend development for AI agents.
Key Takeaways
- •Microsoft Agent Framework is an open-source SDK for building and orchestrating AI agents with features like modular agents, workflows, and tool integrations.
- •AG-UI protocol bridges the backend (Microsoft Agent Framework) and frontend (CopilotKit) for seamless communication.
- •Setup involves CLI commands, dependency installation, GitHub token configuration, and running a development server for a full-stack agent.
Tags
In this guide, you will learn how to build a frontend for your Microsoft Agent Framework Agents using AG-UI Protocol and CopilotKit. Microsoft Agent Framework will power the AI agents backend while CopilotKit powers the frontend and then AG-UI creates a bridge that enables the frontend to communicate with the backend.
Before we jump in, here is what we will cover:
What is the Microsoft Agent Framework?
Setting up a Microsoft Agent Framework + AG-UI + CopilotKit agent using CLI
Integrating your Microsoft Agent Framework agent with AG-UI protocol in the backend
Building a frontend for your Microsoft Agent Framework + AG-UI agent using CopilotKit
Here is a preview of what you can build using Microsoft Agent Framework + AG-UI + CopilotKit.
What is the Microsoft Agent Framework?
The Microsoft Agent Framework is an open-source software development kit (SDK) and runtime designed for building, orchestrating, and deploying AI agents and multi-agent workflows.
It supports both Python and .NET languages, allowing developers to create everything from simple chat-based agents to complex systems where multiple agents collaborate on tasks
Microsoft Agent Framework key features include:
Agents: Modular AI entities powered by large language models (LLMs) like Azure OpenAI, OpenAI, or others. Agents can reason, use tools, and maintain conversation history via built-in threading.
**Workflows: **Graph-based orchestration for explicit control over multi-agent execution (e.g., sequential, parallel, nested, or human-in-the-loop). Supports checkpointing, type-based routing, and debugging.
**Tools and Integrations: **OpenAPI-first design for calling APIs; Model Context Protocol (MCP) for dynamic tools; Agent2Agent (A2A) protocol for cross-runtime collaboration.
If you want to dive deeper into how Microsoft Agent Framework works and its setup, check out the docs here: Microsoft Agent Framework docs.
Prerequisites
Before you begin, you'll need the following:
GitHub Personal Access Token (for GitHub Models API)
Optional: Azure OpenAI endpoint and deployment (if using Azure OpenAI instead of GitHub Models)
Setting up a Microsoft Agent Framework + AG-UI + CopilotKit agent using CLI
In this section, you will learn how to set up a full-stack Microsoft Agent Framework agent using a CLI command that setups the backend using AG-UI protocol and the frontend using CopilotKit.
Let’s get started.
Step 1: Run CLI command
If you don’t already have a Microsoft Agent Framework agent, you can set up one quickly by running the CLI command below in your terminal.
npx copilotkit@latest init -m microsoft-agent-framework
Then give your project a name as shown below.
Step 2: Install dependencies
Once your project has been created successfully, install dependencies using your preferred package manager:
# Using pnpm (recommended)
pnpm install
# Using npm
npm install
# Using yarn
yarn install
# Using bun
bun install
Step 3: Set up your GitHub token for GitHub Models
After installing the dependencies, first, get your GitHub token:
gh auth token
Then, navigate to the agent directory and set it as a user secret:
cd agent
dotnet user-secrets set GitHubToken "<your-token>"
cd ..
Step 4: Run development server
Then start the development server using your preferred package manager:
# Using pnpm
pnpm dev
# Using npm
npm run dev
# Using yarn
yarn dev
# Using bun
bun run dev
Once the development server is running, navigate to http://localhost:3000/ and you should see your Microsoft Agent Framework + AG-UI + CopilotKit agent up and running.
Congrats! You've successfully integrated a ADK Agent chatbot to your application. To start, try the provided tools to set the web page theme, write proverbs or get the weather, as shown below.
Integrating your Microsoft Agent Framework agent with AG-UI protocol in the backend
In this section, you will learn how to integrate your Microsoft Agent Framework agent with AG-UI protocol, in order to expose it to the frontend.
Let’s jump in.
Step 1: Install Microsoft Agent Framework + AG-UI packages
To get started, install the Microsoft Agent Framework + AG-UI packages together with other necessary dependencies using the commands below.
dotnet new web -n AGUIServer
cd AGUIServer
dotnet add package Microsoft.Agents.AI.Hosting.AGUI.AspNetCore
dotnet add package Microsoft.Extensions.AI.OpenAI
dotnet add package OpenAI
Step 2: Import required packages
Once you have installed the required packages, import them as shown below in a Program.cs file.
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AGUI.AspNetCore;
using Microsoft.AspNetCore.Http.Json;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Options;
using OpenAI;
using System.ComponentModel;
using System.Text.Json.Serialization;
Step 3: Create and Configure Web Application Builder
After importing the required packages, create a new WebApplicationBuilder instance with command-line arguments, configure JSON Serialization Options and register AG-UI Services, as shown below.
// ...
// Create a new WebApplicationBuilder instance with command-line arguments
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
// Configure JSON Serialization Options
builder.Services.ConfigureHttpJsonOptions(options => options.SerializerOptions.TypeInfoResolverChain.Add(ProverbsAgentSerializerContext.Default));
// Register AG-UI Services
builder.Services.AddAGUI();
// Build the WebApplication instance from the builder
// This compiles all registered services and configurations
WebApplication app = builder.Build();
// ...
Step 4: Set Up Agent Factory and Map Endpoints
Once you have configured the web application builder, set up the agent factory and map endpoints, as shown below.
// ...
// Get Required Services from Dependency Injection Container
// Retrieve the logger factory for creating loggers
var loggerFactory = app.Services.GetRequiredService<ILoggerFactory>();
// Retrieve JSON options for serialization configuration
var jsonOptions = app.Services.GetRequiredService<IOptions<JsonOptions>>();
// Create Agent Factory Instance
// Instantiate the ProverbsAgentFactory with:
// - Application configuration (for accessing appsettings, environment variables, etc.)
// - Logger factory (for creating loggers within the factory)
// - JSON serializer options (for serializing agent data)
var agentFactory = new ProverbsAgentFactory(builder.Configuration, loggerFactory, jsonOptions.Value.SerializerOptions);
// Map AG-UI Endpoint
// Map the root path ("/") to the AG-UI agent endpoint
// The CreateProverbsAgent() method returns a configured AI agent instance
// This allows the agent to handle requests at the root URL
app.MapAGUI("/", agentFactory.CreateProverbsAgent());
// Start the web application and begin listening for HTTP requests
// This is an async operation that will run until the application is stopped
await app.RunAsync();
// ...
Step 5: Define your agent state
After setting up the agent factory and mapping endpoints, define your agent state class that maintains the application's state. The agent state class is registered as a singleton in the dependency injection container, meaning there's one instance shared across the entire application lifetime.
// ...
public class ProverbsState
{
// Initialize the Proverbs list as an empty list to avoid null reference issues
public List<string> Proverbs { get; set; } = new List<string>();
}
// ...
Step 6: Configure your Agent factory
Once you have defined your agent state, configure your agent factory class responsible for creating and configuring AI agents.
// ...
public class ProverbsAgentFactory
{
// Store configuration for accessing settings (like API tokens)
private readonly IConfiguration _configuration;
// Reference to the shared state instance
private readonly ProverbsState _state;
// OpenAI client instance for making API calls
private readonly OpenAIClient _openAiClient;
// Logger instance for logging agent activities
private readonly ILogger _logger;
// JSON serializer options for serializing/deserializing agent data
private readonly System.Text.Json.JsonSerializerOptions _jsonSerializerOptions;
// ...
}
// ...
Step 7: Initialize the Agent factory
Inside the agent factory class, define a constructor that initializes the agent factory by using a GitHub token to authenticate with the Azure OpenAI endpoint and configure the OpenAI client.
// ...
public class ProverbsAgentFactory
{
// Store configuration for accessing settings (like API tokens)
private readonly IConfiguration _configuration;
// Reference to the shared state instance
private readonly ProverbsState _state;
// OpenAI client instance for making API calls
private readonly OpenAIClient _openAiClient;
// Logger instance for logging agent activities
private readonly ILogger _logger;
// JSON serializer options for serializing/deserializing agent data
private readonly System.Text.Json.JsonSerializerOptions _jsonSerializerOptions;
// Step 3.1: Constructor - Initialize the factory with dependencies
// This constructor is called by the dependency injection container
public ProverbsAgentFactory(IConfiguration configuration, ProverbsState state)
{
// Store injected dependencies
_configuration = configuration;
_state = new();
// Step 3.2: Retrieve the GitHub token from configuration
// The token is used to authenticate with the Azure OpenAI endpoint
// If the token is not found, throw an exception with helpful instructions
var githubToken = _configuration["GitHubToken"]
?? throw new InvalidOperationException(
"GitHubToken not found in configuration. " +
"Please set it using: dotnet user-secrets set GitHubToken \"<your-token>\" " +
"or get it using: gh auth token");
// Step 3.3: Create and configure the OpenAI client
// - Use the GitHub token as the API key credential
// - Set the endpoint to Azure's inference API endpoint
_openAiClient = new OpenAIClient(
new System.ClientModel.ApiKeyCredential(githubToken),
new OpenAIClientOptions
{
Endpoint = new Uri("https://models.inference.ai.azure.com")
});
}
// ...
}
Step 8: Create and configure your AI agent
Once you have initialized the agent factory, define a method inside the agent factory class that sets up the chat client, defines the agent's behavior, and registers the available tools
// ...
public class ProverbsAgentFactory
{
// Store configuration for accessing settings (like API tokens)
private readonly IConfiguration _configuration;
// Reference to the shared state instance
private readonly ProverbsState _state;
// OpenAI client instance for making API calls
private readonly OpenAIClient _openAiClient;
// Logger instance for logging agent activities
private readonly ILogger _logger;
// JSON serializer options for serializing/deserializing agent data
private readonly System.Text.Json.JsonSerializerOptions _jsonSerializerOptions;
// ...
// Create Proverbs Agent
// This method creates and configures the AI agent with its tools and capabilities
public AIAgent CreateProverbsAgent()
{
// Get Chat Client
// Retrieve a chat client for the "gpt-4o-mini" model
// Convert it to the IChatClient interface required by the agent framework
var chatClient = _openAiClient.GetChatClient("gpt-4o-mini").AsIChatClient();
// Create Chat Client Agent
// Create a ChatClientAgent that wraps the chat client with agent capabilities
// - name: Identifier for the agent
// - description: System prompt that describes the agent's role and behavior
// This instructs the agent to always check the current proverbs list before discussing them
// - tools: Array of functions the agent can call to perform actions
var chatClientAgent = new ChatClientAgent(
chatClient,
name: "ProverbsAgent",
description: @"A helpful assistant that helps manage and discuss proverbs.
You have tools available to add, set, or retrieve proverbs from the list.
When discussing proverbs, ALWAYS use the get_proverbs tool to see the current list before mentioning, updating, or discussing proverbs with the user.",
tools: [
// Tool 1: Get the current list of proverbs
AIFunctionFactory.Create(GetProverbs, options: new() { Name = "get_proverbs", SerializerOptions = _jsonSerializerOptions }),
// Tool 2: Add new proverbs to the existing list
AIFunctionFactory.Create(AddProverbs, options: new() { Name = "add_proverbs", SerializerOptions = _jsonSerializerOptions }),
// Tool 3: Replace the entire list of proverbs
AIFunctionFactory.Create(SetProverbs, options: new() { Name = "set_proverbs", SerializerOptions = _jsonSerializerOptions }),
// Tool 4: Get weather information for a location
AIFunctionFactory.Create(GetWeather, options: new() { Name = "get_weather", SerializerOptions = _jsonSerializerOptions })
]);
// Wrap with Shared State Agent
// Wrap the chat client agent with SharedStateAgent to enable state persistence
// This allows the agent to maintain state across multiple interactions
// The JSON serializer options are used for state serialization
return new SharedStateAgent(chatClientAgent, _jsonSerializerOptions);
}
// ...
}
Step 9: Define agent tools
After configuring your agent, define agent tool methods inside the agent factory class that your AI agent can call as tools.
// ...
public class ProverbsAgentFactory
{
// Store configuration for accessing settings (like API tokens)
private readonly IConfiguration _configuration;
// Reference to the shared state instance
private readonly ProverbsState _state;
// OpenAI client instance for making API calls
private readonly OpenAIClient _openAiClient;
// ...
// Tool 1: Get Proverbs
// Retrieves the current list of proverbs from the shared state
[Description("Get the current list of proverbs.")]
private List<string> GetProverbs()
{
// Log the operation for debugging and monitoring
_logger.LogInformation("📖 Getting proverbs: {Proverbs}", string.Join(", ", _state.Proverbs));
// Return the current list of proverbs from the shared state
return _state.Proverbs;
}
// Tool 2: Add Proverbs
// Adds new proverbs to the existing list without removing existing ones
[Description("Add new proverbs to the list.")]
private void AddProverbs([Description("The proverbs to add")] List<string> proverbs)
{
// Log the operation with the proverbs being added
_logger.LogInformation("➕ Adding proverbs: {Proverbs}", string.Join(", ", proverbs));
// Add the new proverbs to the end of the existing list
// AddRange appends all items from the input list to the state's Proverbs list
_state.Proverbs.AddRange(proverbs);
}
// Tool 3: Set Proverbs
// Replaces the entire list of proverbs with a new list
[Description("Replace the entire list of proverbs.")]
private void SetProverbs([Description("The new list of proverbs")] List<string> proverbs)
{
// Log the operation with the new list of proverbs
_logger.LogInformation("📝 Setting proverbs: {Proverbs}", string.Join(", ", proverbs));
// Replace the entire list using collection expression syntax
// The [.. proverbs] syntax creates a new list with a copy of all items from proverbs
_state.Proverbs = [.. proverbs];
}
// Tool 4: Get Weather
// Retrieves weather information for a specified location
// Note: This is a mock implementation that returns ha
