A comprehensive .NET template for creating Model Context Protocol (MCP) servers using ASP.NET Core. This template provides a robust foundation for building MCP servers that can integrate with AI assistants and other MCP clients.
The Model Context Protocol (MCP) is an open standard for enabling AI assistants to securely access external resources and tools. MCP servers provide three main capabilities:
- Tools: Functions that can be called by AI assistants to perform actions
- Resources: Read-only data that assistants can access for context
- Prompts: Reusable prompt templates for common AI tasks
-
Install the template:
dotnet new install ./
-
Create a new MCP server:
dotnet new mcp-server -n MyCompany.McpServer cd MyCompany.McpServer
-
Run the server:
dotnet run
The server will start on http://localhost:5000
by default.
--ServerName
: Display name for your MCP server (default: "My MCP Server")--Port
: Port number for the server (default: 5000)--Framework
: Target framework (default: net8.0)
Example:
dotnet new mcp-server -n Acme.WeatherServer --ServerName "Acme Weather Service" --Port 8080
├── .template.config/ # Template configuration
│ └── template.json
├── Extensions/ # Utility extensions
│ └── HttpClientExtensions.cs
├── Tools/ # MCP tools implementation
│ └── ExampleTools.cs
├── Prompts/ # MCP prompts implementation
│ └── ExamplePrompts.cs
├── Resources/ # MCP resources implementation
│ └── ExampleResources.cs
├── Program.cs # Application entry point
├── appsettings.json # Configuration
├── Dockerfile # Docker configuration
└── README.md # This file
Tools are functions that AI assistants can call to perform actions. Here's how to create them:
using System.ComponentModel;
using ModelContextProtocol.Server;
namespace YourNamespace.Tools;
[McpServerToolType]
public class MyTools
{
[McpServerTool, Description("Performs a custom operation")]
public static string MyTool([Description("Input parameter")] string input)
{
// Your tool logic here
return $"Processed: {input}";
}
}
[McpServerTool, Description("Fetches data from an API")]
public static async Task<string> FetchData(
HttpClient httpClient, // Injected dependency
[Description("API endpoint")] string endpoint)
{
var response = await httpClient.GetStringAsync(endpoint);
return response;
}
[McpServerTool, Description("Gets user information")]
public static string GetUserInfo([Description("User ID")] int userId)
{
var user = new { Id = userId, Name = "John Doe", Email = "john@example.com" };
return JsonSerializer.Serialize(user, new JsonSerializerOptions { WriteIndented = true });
}
Prompts are reusable templates for AI interactions:
using Microsoft.Extensions.AI;
using ModelContextProtocol.Server;
namespace YourNamespace.Prompts;
[McpServerPromptType]
public class MyPrompts
{
[McpServerPrompt, Description("Creates a prompt for data analysis")]
public static ChatMessage AnalyzeData(
[Description("Data to analyze")] string data,
[Description("Analysis type")] string analysisType = "summary")
{
return new ChatMessage(ChatRole.User,
$"Please perform a {analysisType} analysis of this data: {data}");
}
}
Resources provide read-only access to data:
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;
namespace YourNamespace.Resources;
[McpServerResourceType]
public class MyResources
{
[McpServerResource(UriTemplate = "data://users/{id}", Name = "User Data")]
public static ResourceContents GetUser(string id)
{
var userData = GetUserById(id); // Your data retrieval logic
return new BlobResourceContents
{
Blob = JsonSerializer.Serialize(userData),
MimeType = "application/json",
Uri = $"data://users/{id}"
};
}
}
Configure the server in appsettings.json
:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:5000"
}
}
}
}
ASPNETCORE_ENVIRONMENT
: Set toDevelopment
for enhanced loggingASPNETCORE_URLS
: Override the default listening URLs
# Build the image
docker build -t my-mcp-server .
# Run the container
docker run -p 5000:5000 my-mcp-server
version: '3.8'
services:
mcp-server:
build: .
ports:
- "5000:5000"
environment:
- ASPNETCORE_ENVIRONMENT=Production
Test the server endpoints:
# Check server health
curl http://localhost:5000/health
# List available tools
curl -X POST http://localhost:5000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
Connect your MCP server to compatible clients like:
- Claude Desktop
- VS Code with MCP extension
- Custom MCP clients
Create a test script to verify template functionality:
#!/bin/bash
# Test template generation
rm -rf test-output
dotnet new mcp-server -n TestServer -o test-output
cd test-output
dotnet build
dotnet run &
sleep 5
curl http://localhost:5000/health
pkill -f "TestServer"
The template uses ASP.NET Core's built-in DI container. Common services are pre-configured:
HttpClient
: For making HTTP requests in toolsILogger<T>
: For logging throughout the application- MCP Server services: Automatically registered
The MCP server automatically discovers:
- Tools in classes decorated with
[McpServerToolType]
- Prompts in classes decorated with
[McpServerPromptType]
- Resources in classes decorated with
[McpServerResourceType]
The template includes proper error handling:
- Tool exceptions are caught and returned as error responses
- HTTP client errors are handled gracefully
- Validation errors are properly formatted
- Keep tools focused on single responsibilities
- Use descriptive names and documentation
- Validate input parameters
- Handle errors gracefully
- Return structured data when possible
- Validate all inputs
- Use HTTPS in production
- Implement proper authentication if needed
- Don't expose sensitive information in error messages
- Use async/await for I/O operations
- Cache expensive computations
- Implement proper resource disposal
- Monitor memory usage
- Document all tools, prompts, and resources
- Provide clear parameter descriptions
- Include usage examples
- Maintain API documentation
The template includes comprehensive examples:
- Echo: Simple text processing
- Calculate: Mathematical operations
- GetTimestamp: Date/time utilities
- CheckHttpStatus: HTTP monitoring
- GenerateUuid: ID generation
- Summarize: Content summarization
- ReviewCode: Code review assistance
- ExplainCode: Code explanation
- GenerateDocumentation: Documentation generation
- TranslateText: Language translation
- Configuration: Server settings
- System Status: Health monitoring
- API Documentation: Interactive docs
- Port already in use: Change the port in
appsettings.json
- Assembly not found: Ensure all dependencies are restored with
dotnet restore
- Tools not discovered: Verify
[McpServerToolType]
attributes are present - JSON serialization errors: Check return types and ensure they're serializable
Enable detailed logging by setting ASPNETCORE_ENVIRONMENT=Development
:
export ASPNETCORE_ENVIRONMENT=Development
dotnet run