GenAI & LLM Interviews · Lesson 22 of 30
MCP Servers for .NET & Azure
Model Context Protocol (MCP) is an open standard for connecting LLMs to tools, resources, and prompt templates. .NET developers can host MCP servers that GitHub Copilot, Claude Desktop, or a custom app call over Stdio (local) or HTTP (remote).
Related: MCP vs RAG vs agents · AI-assisted development · Course lesson
Mental model
┌─────────────┐ JSON-RPC 2.0 ┌─────────────┐
│ MCP Client │ ◄──────────────────► │ MCP Server │
│ (Copilot, │ Stdio or HTTP │ (.NET app) │
│ your app) │ │ tools/data │
└─────────────┘ └─────────────┘| Capability | Purpose | |------------|---------| | Tools | Functions the model can invoke (search orders, run query) | | Resources | Read-only context (file contents, config snapshot) | | Prompts | Reusable prompt templates with parameters |
Prerequisites
dotnet --version # .NET 8+ recommended; check MCP SDK docs for latest TFMCreate a workspace folder:
mkdir McpDotNetLabs && cd McpDotNetLabs1. Stdio MCP server (local tools)
Stdio servers run as a child process — the client writes JSON-RPC to stdin and reads stdout. Ideal for local filesystem or dev tools.
dotnet new console -o OrderFlow.McpServer
cd OrderFlow.McpServer
dotnet add package ModelContextProtocol
dotnet add package Microsoft.Extensions.HostingProgram.cs (pattern — verify package README for exact API on your version):
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using ModelContextProtocol.Server;
var builder = Host.CreateApplicationBuilder(args);
builder.Services
.AddMcpServer()
.WithStdioServerTransport();
builder.Services.AddSingleton<OrderTools>();
await builder.Build().RunAsync();
[McpServerToolType]
public sealed class OrderTools
{
[McpServerTool, Description("Get order count for a status")]
public static Task<string> GetOrderCount(string status) =>
Task.FromResult($"42 orders with status '{status}' (demo)");
}Build and note the DLL path — clients reference the executable.
Test with MCP Inspector
Use the MCP Inspector to list tools and invoke GetOrderCount without an LLM.
Connect from VS Code / Copilot
Add an MCP server entry in your editor config pointing at:
dotnet run --project /path/to/OrderFlow.McpServer(Exact config file format varies by client — follow Copilot or Claude Desktop MCP docs.)
2. HTTP MCP server (remote)
HTTP transport suits shared services — calendar, ticketing, internal APIs behind auth.
High-level steps:
dotnet new web(ASP.NET Core minimal host)- Register MCP with HTTP transport middleware
- Expose tools that call your existing application services via DI
- Protect with API keys, mTLS, or Entra ID — never expose raw tools to the public internet
// Illustrative — align with your SDK version
builder.Services
.AddMcpServer()
.WithHttpTransport();
var app = builder.Build();
app.MapMcp(); // extension from MCP ASP.NET integration
app.Run();Tradeoff: HTTP is easier to deploy and scale; Stdio is simpler for local-only tools with no port management.
3. Consume MCP from a .NET client
Your chat app can act as an MCP client:
- Start or connect to a server
- Discover tools via protocol handshake
- When the LLM requests a tool call, execute via MCP and return results to the model
This mirrors what Copilot does — you orchestrate the loop with Microsoft.Extensions.AI or vendor SDKs plus MCP client libraries.
Pseudo-flow:
// 1. User message → LLM
// 2. LLM returns tool_call: GetOrderCount(status: "Shipped")
// 3. Client invokes MCP tool → result string
// 4. Send tool result back to LLM → final natural language answerKeep tool implementations idempotent where possible and enforce authorization inside the server (the LLM is not trusted).
4. Production guidelines
| Topic | Guidance | |-------|------------| | Auth | Map MCP clients to service principals; audit tool calls | | Timeouts | Cap long-running tools; return structured errors | | PII | Don't expose raw customer data in resource URIs | | Versioning | Treat tool schemas as contract — breaking changes hurt clients | | Observability | Log tool name, duration, correlation ID — not secrets |
When MCP vs REST vs in-process DI
| Approach | Use when | |----------|----------| | In-process service | Same app, same trust boundary | | REST/gRPC | Standard microservice integration | | MCP | LLM clients must discover capabilities dynamically across tools |
MCP is not a replacement for your public API — it's an agent-facing integration layer.
Summary
- Stdio — local dev tools, Copilot, Claude Desktop
- HTTP — shared team servers, hosted capabilities
- Tools / resources / prompts — three extension points of the protocol
- .NET — host with
ModelContextProtocol+ generic host or ASP.NET Core