Why This Matters Now
As organizations increasingly adopt the Model Context Protocol (MCP) for integrating language models with external tools, the need for robust security measures becomes paramount. The recent surge in enterprise deployments has highlighted the vulnerabilities associated with unsecured MCP servers. Protecting these servers not only safeguards sensitive data but also ensures compliance with regulatory standards.
Build Your MCP Server in C#
To illustrate the process of securing an MCP server, we’ll start by building a basic MCP server using the C# SDK. This server will then be extended to include OAuth 2.1 authorization via Auth0.
Prerequisites
Before diving into the implementation, ensure you have the following:
- .NET SDK 10 or later installed.
- The C# SDK for MCP package.
- An Auth0 account (sign up for free here).
Create the MCP Server
First, install the MCP server template project by running:
dotnet new install Microsoft.McpServer.ProjectTemplates
Next, create your MCP server project:
dotnet new mcpserver -n AspNetCoreMcpServer -t remote
This command generates a new ASP.NET Core application configured as an MCP server.
Explore the Project
Navigate to the Program.cs file in your project directory. You should see the following code:
// Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add the MCP services: the transport to use (http) and the tools to register.
builder.Services
.AddMcpServer()
.WithHttpTransport()
.WithTools<RandomNumberTools>();
var app = builder.Build();
app.MapMcp();
app.Run();
This setup initializes an MCP server using HTTP transport and registers a tool (RandomNumberTools) for interaction.
Implementing Security with Auth0
To secure your MCP server, integrate OAuth 2.1 using Auth0. This involves setting up Auth0, configuring the server, and registering the client.
Set Up Auth0
- Create an Auth0 Account: Sign up at Auth0.
- Create an Application: In the Auth0 dashboard, create a new application and select “Single Page Web Applications.”
- Configure API: Create an API in Auth0 to represent your MCP server. Note the Audience URL, as it will be used in the server configuration.
Configure the MCP Server
Install Required Packages: Add the necessary NuGet packages for OAuth 2.1 integration.
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearerUpdate Program.cs: Modify the
Program.csfile to include JWT Bearer authentication.// Program.cs var builder = WebApplication.CreateBuilder(args); // Add the MCP services: the transport to use (http) and the tools to register. builder.Services .AddMcpServer() .WithHttpTransport() .WithTools<RandomNumberTools>(); // Add JWT Bearer authentication builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.Authority = builder.Configuration["Auth0:Domain"]; options.Audience = builder.Configuration["Auth0:Audience"]; }); builder.Services.AddAuthorization(); var app = builder.Build(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapMcp(); app.Run();AppSettings Configuration: Update
appsettings.jsonwith your Auth0 domain and audience.{ "Auth0": { "Domain": "https://your-auth0-domain.auth0.com", "Audience": "your-api-audience" } }
Register the Client
Dynamic Client Registration (DCR): Use Auth0’s DCR feature to register your MCP client dynamically. This can be done programmatically or manually through the Auth0 dashboard.
// Example of manual registration in Auth0 dashboard // Set up the client with appropriate scopes and permissionsConfigure Client: Ensure your MCP client (e.g., VSCode) is configured to obtain and send the necessary JWT tokens for authentication.
Implementing Different Access Levels
To demonstrate resource isolation and multi-tenancy, we’ll implement three tools:
- PublicTool: Available to everyone.
- AdminTool: Requires admin-level access.
- UserTool: Requires user-level access.
Define Tools
Create classes for each tool:
// PublicTool.cs
public class PublicTool : IMcpTool
{
public async Task<McpResponse> ExecuteAsync(McpRequest request)
{
return new McpResponse { Success = true, Message = "Public Tool executed." };
}
}
// AdminTool.cs
public class AdminTool : IMcpTool
{
[Authorize(Policy = "Admin")]
public async Task<McpResponse> ExecuteAsync(McpRequest request)
{
return new McpResponse { Success = true, Message = "Admin Tool executed." };
}
}
// UserTool.cs
public class UserTool : IMcpTool
{
[Authorize(Policy = "User")]
public async Task<McpResponse> ExecuteAsync(McpRequest request)
{
return new McpResponse { Success = true, Message = "User Tool executed." };
}
}
Register Tools
Update Program.cs to register the new tools:
// Program.cs
builder.Services
.AddMcpServer()
.WithHttpTransport()
.WithTools<PublicTool>()
.WithTools<AdminTool>()
.WithTools<UserTool>();
Define Policies
Define authorization policies in Program.cs:
// Program.cs
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("Admin", policy => policy.RequireClaim("scope", "admin"));
options.AddPolicy("User", policy => policy.RequireClaim("scope", "user"));
});
Testing the Secured MCP Server
To test the secured MCP server, follow these steps:
Start the Server: Run your MCP server application.
dotnet runObtain Tokens: Use Auth0 to obtain JWT tokens for different user roles (public, admin, user).
Invoke Tools: Use a tool like Postman or cURL to invoke the MCP server endpoints with the appropriate tokens.
curl -X POST http://localhost:5000/mcp \ -H "Authorization: Bearer YOUR_JWT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"tool": "AdminTool"}'
Key Takeaways
- Security First: Always prioritize security when deploying MCP servers, especially in enterprise environments.
- Resource Isolation: Use OAuth 2.1 and Auth0 to enforce access controls and prevent unauthorized access.
- Multi-Tenancy: Implement role-based access control (RBAC) to ensure different users have appropriate permissions.
Conclusion
Securing a C# MCP server with Auth0 and OAuth 2.1 is essential for protecting against unauthorized access and ensuring resource isolation. By following the steps outlined in this article, you can build a secure MCP server that meets the needs of modern enterprise applications.

