Learnixo
Back to blog
AI Systemsintermediate

Build and Consume MCP Servers in .NET

Model Context Protocol in .NET โ€” create Stdio and HTTP MCP servers with tools, resources, and prompts, then connect them from AI clients and your own chat app.

LearnixoMay 16, 20264 min read
.NETC#MCPAIModel Context ProtocolOpenAIAgents
Share:๐•

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

Bash
dotnet --version   # .NET 8+ recommended; check MCP SDK docs for latest TFM

Create a workspace folder:

Bash
mkdir McpDotNetLabs && cd McpDotNetLabs

1. 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.

Bash
dotnet new console -o OrderFlow.McpServer
cd OrderFlow.McpServer
dotnet add package ModelContextProtocol
dotnet add package Microsoft.Extensions.Hosting

Program.cs (pattern โ€” verify package README for exact API on your version):

C#
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:

Bash
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:

  1. dotnet new web (ASP.NET Core minimal host)
  2. Register MCP with HTTP transport middleware
  3. Expose tools that call your existing application services via DI
  4. Protect with API keys, mTLS, or Entra ID โ€” never expose raw tools to the public internet
C#
// 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:

  1. Start or connect to a server
  2. Discover tools via protocol handshake
  3. 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:

C#
// 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 answer

Keep 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

  1. Stdio โ€” local dev tools, Copilot, Claude Desktop
  2. HTTP โ€” shared team servers, hosted capabilities
  3. Tools / resources / prompts โ€” three extension points of the protocol
  4. .NET โ€” host with ModelContextProtocol + generic host or ASP.NET Core

Next: Build an OpenAI chatbot ยท Getting started with Codex

Enjoyed this article?

Explore the AI Systems learning path for more.

Found this helpful?

Share:๐•

Leave a comment

Have a question, correction, or just found this helpful? Leave a note below.