🎯 This is a SKELETON/TEMPLATE for building MCP servers - NOT a production application!
MCP Skeleton (.NET) is a generic template for building Model Context Protocol (MCP) servers with the official .NET MCP SDK. The architecture provides complete separation between the MCP server layer and your business logic, making it a true "plug-and-play" skeleton for any domain.
Provides a modular architecture for building production-ready MCP servers with dual transport modes (stdio + HTTP/SSE) and full Kubernetes/AKS deployment support.
- Clean Architecture – Separated layers: Server, Tools (business logic), Utilities
- Dual Transport – Supports both stdio (IDE integration) and HTTP/SSE (deployment)
- Type Safe – Full C# type safety with nullable reference types
- Example Tools – Calculator, Weather, HTTP, and Text services as reference implementations
- Production Ready – Includes Docker setup, multi-stage builds, and configuration management
- Well Tested – xUnit test project with FluentAssertions patterns
mcp-skeleton-dotnet/
├── McpSkeleton.sln # Solution file
│
├── src/
│ ├── McpSkeleton.Server/ # MCP Server Entry Point
│ │ ├── Program.cs # Main entry with tool registrations
│ │ ├── appsettings.json # Configuration
│ │ └── McpSkeleton.Server.csproj
│ │
│ ├── McpSkeleton.Tools/ # Business Logic Layer ⚠️ REPLACE WITH YOUR OWN
│ │ ├── Calculator/ # 📚 EXAMPLE Tool 1: Math operations
│ │ │ └── CalculatorTools.cs
│ │ ├── Weather/ # 📚 EXAMPLE Tool 2: Weather data (mock)
│ │ │ └── WeatherTools.cs
│ │ ├── Http/ # 📚 EXAMPLE Tool 3: HTTP client
│ │ │ └── HttpTools.cs
│ │ ├── Text/ # 📚 EXAMPLE Tool 4: Text processing
│ │ │ └── TextTools.cs
│ │ └── McpSkeleton.Tools.csproj
│ │
│ └── McpSkeleton.Utilities/ # Shared Utilities (Keep or extend)
│ ├── Configuration/ # Settings management
│ │ ├── ServerSettings.cs
│ │ └── ConfigurationLoader.cs
│ ├── Models/ # Shared models
│ │ └── ToolResponse.cs
│ ├── Extensions/ # Extension methods
│ │ └── ServiceCollectionExtensions.cs
│ └── McpSkeleton.Utilities.csproj
│
├── tests/
│ └── McpSkeleton.Tests/ # Unit Tests ⚠️ REPLACE WITH YOUR OWN
│ ├── Calculator/
│ │ └── CalculatorToolsTests.cs
│ ├── Weather/
│ │ └── WeatherToolsTests.cs
│ ├── Text/
│ │ └── TextToolsTests.cs
│ ├── Http/
│ │ └── HttpToolsTests.cs
│ └── McpSkeleton.Tests.csproj
│
├── Dockerfile # Production container image
├── docker-compose.yml # Local development
├── global.json # SDK version
├── ARCHITECTURE.md # System architecture documentation
└── README.md # This file
✅ Production-Ready Infrastructure (Keep as-is)
- MCP server with official .NET MCP SDK
- Dual transport: stdio (local) + HTTP/SSE (containers)
- Docker containerization with security best practices
- Kubernetes/AKS deployment ready
- Type-safe configuration with Microsoft.Extensions.Configuration
- Comprehensive logging with Serilog
📚 Example Tools (Replace with your business logic)
- Calculator, Weather, HTTP, Text tools are DEMOS ONLY
- Shows the pattern for implementing your own tools
- Clear separation between server and business logic
This template includes 4 example tools that you should REPLACE:
| Example Tool | Purpose | Replace With |
|---|---|---|
| 🧮 Calculator | Math operations demo | Your domain logic |
| 🌤️ Weather | API integration pattern | Your API calls |
| 🌐 HTTP | HTTP client example | Your integrations |
| 📝 Text | Text processing demo | Your data processing |
Keep: Server infrastructure, Docker, Kubernetes configs, utilities
Replace: Everything in McpSkeleton.Tools/ with your business logic
- .NET 8.0 SDK
- Docker (optional, for containerization)
-
Clone and navigate:
cd mcp-skeleton-dotnet -
Restore dependencies:
dotnet restore
-
Build the solution:
dotnet build
-
Run the server:
stdio mode (for Cursor, VS Code, Claude Desktop):
dotnet run --project src/McpSkeleton.Server
HTTP/SSE mode (for containers/web):
dotnet run --project src/McpSkeleton.Server -- --http
Server available at
http://localhost:8000/sse
-
Build the image:
docker build -t mcp-skeleton-dotnet:latest . -
Run the container:
docker run -d \ -p 8000:8000 \ -e MCP__LOGLEVEL=Information \ --name mcp-skeleton-dotnet \ mcp-skeleton-dotnet:latest
-
Or use Docker Compose:
docker-compose up -d
-
Test the endpoint:
curl http://localhost:8000/sse
# Run all tests
dotnet test
# Run with verbose output
dotnet test --logger "console;verbosity=detailed"
# Run specific test project
dotnet test tests/McpSkeleton.Tests
# Run with coverage (requires coverlet)
dotnet test --collect:"XPlat Code Coverage"🎯 These are DEMONSTRATION TOOLS ONLY - They show you the pattern, but are not meant for production use.
Delete or replace them with your domain-specific business logic.
| Demo Tool | What It Shows | Replace With Your... |
|---|---|---|
| 🧮 Calculator | Basic sync function with validation | Database queries, computations, business rules |
| 🌤️ Weather (mock) | External API pattern (mock implementation) | Real API integrations, third-party services |
| 🌐 HTTP | HTTP client usage with HttpClient | API aggregation, webhook handlers, integrations |
| 📝 Text | String processing and analysis | NLP, data transformation, ETL logic |
// src/McpSkeleton.Tools/YourDomain/YourDomainTools.cs
using System.ComponentModel;
using ModelContextProtocol.Server;
namespace McpSkeleton.Tools.YourDomain;
[McpServerToolType]
public static class YourDomainTools
{
[McpServerTool(Name = "your_tool_name")]
[Description("Your tool description that MCP clients will see")]
public static async Task<YourResult> YourMethodAsync(
[Description("Parameter description")] string inputParam)
{
// Your business logic here
// - Database queries
// - ML inference
// - API calls
// - Business rules
return new YourResult
{
// Your result properties
};
}
}
public class YourResult
{
public string Status { get; set; } = string.Empty;
// Add your properties
}// src/McpSkeleton.Server/Program.cs
// Option 1: Auto-discover all tools from assembly (recommended)
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly(typeof(YourDomainTools).Assembly);
// Option 2: Register individual tool types
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithTools<YourDomainTools>();// tests/McpSkeleton.Tests/YourDomain/YourDomainToolsTests.cs
using McpSkeleton.Tools.YourDomain;
namespace McpSkeleton.Tests.YourDomain;
public class YourDomainToolsTests
{
[Fact]
public async Task YourMethod_ValidInput_ReturnsExpectedResult()
{
// Arrange
var input = "test";
// Act
var result = await YourDomainTools.YourMethodAsync(input);
// Assert
result.Should().NotBeNull();
result.Status.Should().Be("expected");
}
}Configuration is managed via appsettings.json and environment variables:
{
"Mcp": {
"ServerName": "MCP Skeleton Server (.NET)",
"ServerVersion": "0.1.0",
"LogLevel": "Information",
"ServerHost": "0.0.0.0",
"ServerPort": 8000
}
}Environment variables use the MCP__ prefix:
export MCP__SERVERNAME="My Custom Server"
export MCP__LOGLEVEL="Debug"
export MCP__SERVERPORT="9000"-
Update
ServerSettings.cs:public class ServerSettings { // Existing settings... // Your new settings public string? MyApiKey { get; set; } public string MyCustomSetting { get; set; } = "default"; }
-
Add to
appsettings.json:{ "Mcp": { "MyApiKey": "your-api-key", "MyCustomSetting": "some-value" } } -
Use in your code:
public class YourTools { public static async Task<Result> YourMethod(ServerSettings settings) { var apiKey = settings.MyApiKey; // Use your settings } }
ModelContextProtocol- Official MCP C# SDK from modelcontextprotocol/csharp-sdk (maintained with Microsoft)Microsoft.Extensions.Hosting- Generic hostMicrosoft.Extensions.Configuration- Configuration managementSerilog- Structured logging
xunit- Testing frameworkFluentAssertions- Fluent assertion syntaxMoq- Mocking library
# Build with specific configuration
docker build -t mcp-skeleton-dotnet:v1.0 .docker run -d \
-p 8000:8000 \
-e MCP__SERVERNAME="My MCP Server" \
-e MCP__LOGLEVEL=Debug \
--name mcp-skeleton-dotnet \
mcp-skeleton-dotnet:latest- ✅ Non-root user (
mcpuser) - ✅ Alpine-based minimal runtime image
- ✅ Multi-stage build (small final image)
- ✅ Health check endpoint
- ✅ No hardcoded secrets
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-skeleton-dotnet
spec:
replicas: 2
selector:
matchLabels:
app: mcp-skeleton-dotnet
template:
metadata:
labels:
app: mcp-skeleton-dotnet
spec:
containers:
- name: mcp-skeleton
image: your-registry/mcp-skeleton-dotnet:latest
ports:
- containerPort: 8000
env:
- name: MCP__LOGLEVEL
value: "Information"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /sse
port: 8000
initialDelaySeconds: 10
readinessProbe:
httpGet:
path: /sse
port: 8000
---
apiVersion: v1
kind: Service
metadata:
name: mcp-skeleton-dotnet
spec:
selector:
app: mcp-skeleton-dotnet
ports:
- port: 80
targetPort: 8000Deploy:
kubectl apply -f deployment.yaml
kubectl get pods -l app=mcp-skeleton-dotnet# Development
dotnet restore # Restore dependencies
dotnet build # Build solution
dotnet run --project src/McpSkeleton.Server # Run stdio mode
dotnet run --project src/McpSkeleton.Server -- --http # Run HTTP mode
dotnet test # Run tests
# Docker
docker build -t mcp-skeleton-dotnet . # Build image
docker run -p 8000:8000 mcp-skeleton-dotnet # Run container
docker-compose up -d # Run with compose
docker logs -f mcp-skeleton-dotnet # View logs
# Kubernetes
kubectl apply -f deployment.yaml # Deploy
kubectl get pods # Check status
kubectl logs -f deployment/mcp-skeleton-dotnet # Stream logs
kubectl scale deployment mcp-skeleton-dotnet --replicas=3 # ScaleBefore using this template for your project:
- Update
appsettings.jsonwith your server name - Delete or replace example tools in
McpSkeleton.Tools/ - Update tool registrations in
Program.cs - Add your custom configuration to
ServerSettings.cs - Write tests for your tools
- Run tests to verify:
dotnet test - Update this README.md with your project details
- Test locally with
dotnet run - Build and test Docker image
- Deploy to your target environment
- Official MCP C# SDK - The official SDK (maintained with Microsoft)
- MCP Protocol Specification
- .NET Documentation
- Docker Best Practices
- Kubernetes Documentation
Template Version: 0.1.0
Status: Production Ready Template
Runtime: .NET 8.0
Deployment: Local, Docker, Kubernetes, AKS Compatible