Creating a Model Context Protocol (MCP) Server in C#

Creating a Model Context Protocol (MCP) server in C# enables seamless integration between AI systems and applications by standardizing communication. This guide walks you through everything from initial setup to advanced tool implementation using the official C# SDK.
Introduction to Model Context Protocol (MCP)
Model Context Protocol (MCP) is an open standard designed to support context-aware communication between AI models and external systems. Its modular architecture allows developers to:
- Expose AI capabilities as reusable tools
- Handle high-throughput requests efficiently
- Maintain secure, versioned API endpoints
- Integrate easily with existing infrastructure
Since its release by Anthropic in 2024, MCP has gained rapid adoption, with Microsoft integrating it into their AI toolchain and releasing the official ModelContextProtocol C# SDK.
Prerequisites
Before you begin building your MCP server, ensure you have the following:
1. Development Environment
- .NET SDK 9.0+
- Visual Studio 2025 or VS Code with C# Dev Kit
- CLI tools for .NET and NuGet
2. Required NuGet Packages
dotnet add package ModelContextProtocol --prerelease
dotnet add package Microsoft.Extensions.Hosting
3. Foundational Knowledge
- Dependency injection in .NET
- Asynchronous programming (async/await)
- REST API design principles
Step 1: Project Setup
Create and initialize a new console application:
dotnet new console -n McpDemoServer
cd McpDemoServer
Configure the project file (McpDemoServer.csproj
) with appropriate settings:
<PropertyGroup>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
</PropertyGroup>
Step 2: Core Server Implementation
Edit Program.cs
to set up the base MCP server:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
using System.ComponentModel;
var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(options =>
options.LogToStandardErrorThreshold = LogLevel.Trace);
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
await builder.Build().RunAsync();
Key Components
AddMcpServer()
: Initializes the MCP server infrastructureWithStdioServerTransport()
: Enables communication via standard I/OWithToolsFromAssembly()
: Automatically registers tools from the assembly
Step 3: Implementing MCP Tools
Create a new file Tools/ExampleTools.cs
:
using ModelContextProtocol.Server;
using System.ComponentModel;
[McpServerToolType]
public static class DemoOperations
{
[McpServerTool(Description = "Converts text to uppercase")]
public static string Uppercase(string input)
=> input.ToUpperInvariant();
[McpServerTool(Description = "Generates Fibonacci sequence")]
public static IEnumerable<long> Fibonacci(int count)
{
long a = 0, b = 1;
for (int i = 0; i < count; i++)
{
yield return a;
(a, b) = (b, a + b);
}
}
}
Step 4: API and Database Integration
For HTTP-based communication and database integration:
API Endpoint Configuration
builder.Services.AddMcpServer()
.WithHttpServerTransport("https://localhost:5000/mcp")
.WithJwtAuthentication();
Entity Framework Example
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("Default")));
[McpServerTool]
public class UserTools(AppDbContext context)
{
[Description("Gets user by ID")]
public User? GetUser(Guid id)
=> context.Users.Find(id);
}
Step 5: Testing and Validation
Using the Built-in MCP Client
var client = new McpClient(new HttpTransport("http://localhost:5000/mcp"));
var response = await client.InvokeMethodAsync(
"Uppercase", new { input = "test message" });
Console.WriteLine(response); // Output: TEST MESSAGE
Curl Example
curl -X POST http://localhost:5000/mcp/tools/Uppercase \
-H "Content-Type: application/json" \
-d '{"input":"hello world"}'
Integration Testing
[Fact]
public async Task Uppercase_ReturnsCapitalizedString()
{
using var host = await StartTestServer();
var client = host.GetMcpClient();
var result = await client.InvokeMethodAsync("Uppercase", new { input = "test" });
Assert.Equal("TEST", result);
}
Production Considerations
Monitoring
- Integrate OpenTelemetry
- Use Application Insights
- Track QPS, latency, and errors
Security
- Enforce TLS 1.3
- Implement OAuth2 scopes
- Apply rate limits via API gateways
Performance
services.AddMcpServer()
.WithOptimizedBinaryTransport()
.WithConnectionPooling(100);
Real-World Use Cases
AI-Powered CRM
- Integrate Salesforce with LLMs
- Auto-summarize meetings
- Predict deal closures
Smart Manufacturing
- Link IoT sensor data with models
- Schedule production tasks
- Monitor machine health
Healthcare Analytics
- Analyze medical images
- Generate risk profiles
- Automate insurance codes
Troubleshooting Common Issues
Problem | Solution |
---|---|
Tools not appearing | Ensure [McpServerToolType] is on the parent class |
Serialization errors | Use record types for complex data |
Connection timeouts | Check port/firewall rules |
Version conflicts | Pin the ModelContextProtocol package version |
Future-Proofing Your Implementation
Versioning Strategy
services.AddMcpServer()
.WithVersioning(v =>
{
v.AddEndpoint("v1", api => api.WithToolsFromAssembly());
v.AddEndpoint("v2", api => api.WithNewFeatures());
});
Hybrid Transport
.WithHttpServerTransport("http://*:5000")
.WithGrpcServerTransport("http://*:5001")
Integration with Semantic Kernel
var kernel = Kernel.CreateBuilder()
.AddMcpPlugin("http://localhost:5000/mcp")
.Build();
Conclusion
Building an MCP server in C# provides a solid foundation for scalable, secure AI integration. With the ModelContextProtocol SDK, you can expose AI tools, handle large request volumes, and ensure long-term maintainability.
Whether you're building internal tools or customer-facing AI solutions, MCP is a powerful protocol to include in your stack.