Skip to content

MCKRUZ/DotNetMCPServer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

.NET MCP Server Template

A production-ready template for building MCP (Model Context Protocol) servers and clients in .NET. This template implements best practices from enterprise-grade AI applications.

Overview

The Model Context Protocol (MCP) is a standard protocol for AI agents to interact with tools, prompts, and resources. This template provides:

  • MCPServer - A complete MCP server implementation with HTTP transport
  • MCPServer.Client - An example client for connecting to MCP servers
  • MCPServer.Contracts - Shared configuration and DTOs
  • MCPServer.Tests - Unit tests demonstrating testing patterns

Features

  • MCP Protocol v0.6.0 support with HTTP transport
  • Azure Entra ID (Azure AD) JWT authentication
  • Rate limiting with configurable policies
  • Security headers middleware (HSTS, CSP, X-Frame-Options, etc.)
  • CORS configuration
  • Swagger/OpenAPI documentation
  • Example tools, prompts, and resources
  • Comprehensive configuration management
  • Unit tests with xUnit

Quick Start

Prerequisites

  • .NET 9.0 SDK or later
  • Node.js 18+ (for npm-based MCP servers)

Running the Server

cd src/MCPServer
dotnet run

The server will start on:

Running the Client

cd src/MCPServer.Client
dotnet run

Running Tests

cd src
dotnet test

Project Structure

src/
├── MCPServer/                    # MCP Server project
│   ├── Extensions/               # Service collection extensions
│   ├── Tools/                    # MCP Tools (Calculator, DateTime, FileSystem)
│   ├── Prompts/                  # MCP Prompts (CodeReview, Documentation)
│   ├── Resources/                # MCP Resources (SystemInfo, Configuration)
│   ├── Program.cs                # Application entry point
│   └── appsettings.json          # Configuration
│
├── MCPServer.Contracts/          # Shared contracts
│   └── Config/                   # Configuration classes
│       ├── MCPServerConfig.cs    # Server configuration
│       └── MCPClientConfig.cs    # Client configuration
│
├── MCPServer.Client/             # Example MCP Client
│   └── Services/
│       └── McpToolProvider.cs    # MCP client wrapper
│
└── MCPServer.Tests/              # Unit tests
    ├── Tools/                    # Tool tests
    └── Config/                   # Configuration tests

Configuration

Server Configuration (appsettings.json)

{
  "MCPServer": {
    "ServerInfo": {
      "Name": "DotNet-MCPServer",
      "Version": "1.0.0",
      "Instructions": "Description for AI clients",
      "InitializationTimeoutSeconds": 60
    },
    "AzureEntra": {
      "TenantId": "your-tenant-id",
      "ClientId": "your-client-id"
    },
    "RateLimit": {
      "Enabled": true,
      "PermitLimit": 100,
      "WindowSeconds": 60
    },
    "Security": {
      "RequireAuthentication": true,
      "EnableHttpsRedirection": true,
      "EnableHsts": true,
      "AllowedOrigins": "https://example.com",
      "ScopesSupported": ["mcp:tools", "mcp:prompts", "mcp:resources"]
    },
    "Tools": {
      "AllowedBasePaths": ["C:/temp/mcp-workspace"],
      "MaxFileSizeBytes": 10485760,
      "MaxSearchResults": 100
    }
  }
}

Client Configuration

{
  "MCPClient": {
    "ClientInfo": {
      "Name": "DotNet-MCPClient",
      "Version": "1.0.0"
    },
    "Servers": {
      "file_system": {
        "Enabled": true,
        "Type": "Stdio",
        "Command": "npx",
        "Args": ["-y", "@modelcontextprotocol/server-filesystem", "C:/temp"],
        "StartupTimeoutSeconds": 30
      }
    }
  }
}

Adding Custom Tools

Tools are automatically discovered via assembly scanning. Create a new class with the [McpServerToolType] attribute:

using ModelContextProtocol.Server;
using System.ComponentModel;

[McpServerToolType]
public static class MyCustomTool
{
    [McpServerTool("my_tool")]
    [Description("Description for AI clients")]
    public static string MyToolMethod(
        [Description("Parameter description")] string input)
    {
        return $"Processed: {input}";
    }
}

Adding Custom Prompts

using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;
using System.ComponentModel;

[McpServerPromptType]
public static class MyPrompts
{
    [McpServerPrompt("my_prompt")]
    [Description("A custom prompt")]
    public static IEnumerable<PromptMessage> MyPrompt(
        [Description("Input parameter")] string input)
    {
        return new[]
        {
            new PromptMessage
            {
                Role = Role.User,
                Content = new TextContent { Text = $"Process this: {input}" }
            }
        };
    }
}

Adding Custom Resources

using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;

[McpServerResourceType]
public static class MyResources
{
    [McpServerResource("custom://my-resource", Name = "My Resource",
        Description = "A custom resource")]
    public static ResourceContents GetMyResource()
    {
        return new TextResourceContents
        {
            Uri = "custom://my-resource",
            MimeType = "application/json",
            Text = "{ \"data\": \"value\" }"
        };
    }
}

Authentication

Azure Entra ID (Recommended)

  1. Register an application in Azure AD
  2. Configure the client ID and tenant ID in appsettings.json
  3. Set Security.RequireAuthentication to true

Disabling Authentication (Development)

Set in appsettings.Development.json:

{
  "MCPServer": {
    "Security": {
      "RequireAuthentication": false
    }
  }
}

Security Features

  • JWT Authentication - Azure Entra ID token validation
  • Rate Limiting - Configurable request limits per time window
  • Security Headers - X-Frame-Options, X-Content-Type-Options, CSP, etc.
  • Path Validation - File system tools validate paths against allowed directories
  • Input Validation - URI validation to prevent injection attacks

Testing

The template includes comprehensive unit tests:

# Run all tests
dotnet test

# Run with coverage
dotnet test --collect:"XPlat Code Coverage"

# Run specific test project
dotnet test src/MCPServer.Tests

Deployment

Docker

FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
WORKDIR /app
EXPOSE 5000 5001

FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore
RUN dotnet build -c Release -o /app/build

FROM build AS publish
RUN dotnet publish -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MCPServer.dll"]

Azure App Service

  1. Publish the application
  2. Configure application settings in Azure Portal
  3. Enable HTTPS only
  4. Configure Azure AD authentication if needed

Integration with AI Agents

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "dotnet-mcp": {
      "command": "dotnet",
      "args": ["run", "--project", "path/to/MCPServer"]
    }
  }
}

Custom Clients

Use the MCPServer.Client project as a reference for building custom clients.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for new functionality
  4. Submit a pull request

License

MIT License - See LICENSE file for details.

Resources

About

.NET MCP Server and Client template with HTTP/SSE transport, attribute-based tool discovery, and configurable authentication

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages