AI agents are evolving from simple chatbots into autonomous systems capable of planning tasks, invoking tools, retrieving enterprise data, and collaborating with other services. Building these applications requires more than just connecting an LLM to an API. A production-ready AI agent platform needs orchestration, observability, secure tool access, and scalable infrastructure.
Three technologies complement each other particularly well in the .NET ecosystem:
.NET Aspire for orchestrating cloud-native distributed applications.
Semantic Kernel for AI orchestration, memory, and plugin execution.
Model Context Protocol (MCP) for exposing standardized tools that AI agents can discover and invoke.
Together, they provide a strong foundation for building enterprise-grade AI platforms. This article explores how these technologies work together and demonstrates how to build a production-ready architecture.
Understanding the Role of Each Technology
.NET Aspire
.NET Aspire simplifies the development and orchestration of distributed applications. It provides service discovery, centralized configuration, health checks, telemetry, and dashboarding, making it easier to manage applications composed of multiple services.
It is responsible for infrastructure concerns such as:
Service orchestration
Configuration management
Distributed diagnostics
Service discovery
Local development experience
Semantic Kernel
Semantic Kernel acts as the AI orchestration layer.
Its responsibilities include:
Prompt execution
AI planning
Function invocation
Plugin management
Memory integration
LLM communication
Instead of manually calling an LLM for every task, Semantic Kernel coordinates AI workflows while keeping business logic organized.
Model Context Protocol (MCP)
MCP standardizes how AI agents discover and invoke external tools.
Rather than building custom integrations for every application, MCP allows agents to communicate with enterprise services using a consistent protocol.
Typical MCP tools include:
Customer lookup
Product search
Inventory queries
Ticket creation
Document retrieval
Workflow automation
How These Technologies Work Together
A production-ready AI platform separates responsibilities rather than combining everything into a single application.
User
│
▼
ASP.NET Core API
│
▼
Semantic Kernel
│
┌───────────┴───────────┐
▼ ▼
LLM MCP Server
│
┌────────────────┴──────────────┐
▼ ▼
Business Services Enterprise APIs
│
▼
SQL / External Systems
In this architecture:
ASP.NET Core exposes application endpoints.
Semantic Kernel determines how to solve the user's request.
MCP provides standardized tool execution.
Business services contain application logic.
.NET Aspire orchestrates every service while providing centralized monitoring.
This separation makes the platform easier to scale and maintain.
Setting Up a .NET Aspire Solution
Create an Aspire solution and register your services.
var builder = DistributedApplication.CreateBuilder(args);
builder.AddProject<Projects.Api>("api");
builder.AddProject<Projects.McpServer>("mcp");
builder.AddProject<Projects.InventoryService>("inventory");
builder.Build().Run();
Why This Configuration?
Instead of manually configuring networking and service dependencies, Aspire automatically handles service discovery and orchestration.
This reduces infrastructure configuration and makes local development closely resemble production deployments.
Building the AI Orchestration Layer
Semantic Kernel can be registered using dependency injection.
builder.Services.AddKernel()
.AddOpenAIChatCompletion(
modelId: "gpt-4.1",
apiKey: builder.Configuration["OpenAI:ApiKey"]);
Why Use Dependency Injection?
Registering Semantic Kernel through dependency injection allows the kernel to be reused across controllers, services, and background workers. It also simplifies testing by allowing mock implementations during unit testing.
Avoid creating kernel instances manually inside controllers, as this leads to unnecessary object creation and tightly coupled code.
Creating an MCP Tool
Suppose your AI assistant needs to retrieve product information.
Create a business service.
public interface IInventoryService
{
Task<ProductDto?> GetProductAsync(int id);
}
Implementation:
public class InventoryService : IInventoryService
{
public async Task<ProductDto?> GetProductAsync(int id)
{
// Retrieve product from database
}
}
Expose the service through an MCP endpoint.
app.MapPost("/tools/product", async (
int id,
IInventoryService service) =>
{
var product = await service.GetProductAsync(id);
return product is null
? Results.NotFound()
: Results.Ok(product);
});
Why Keep the Endpoint Thin?
Notice that the endpoint contains almost no business logic.
Instead, it delegates the work to the application service. This keeps the MCP layer focused on protocol handling while allowing business logic to be reused by APIs, background jobs, or other services.
End-to-End Production Workflow
Let's consider an enterprise support assistant.
A customer asks:
"Do we still have Product 1205 in stock?"
The workflow is as follows:
Join the conversation! Your thoughts help the community grow.