Advanced MCP: C# Servers, Auth and Ecosystem
After the basics: how to build an MCP server in .NET, how OAuth authorization works for remote MCP servers, and what is in the MCP ecosystem.
18.1 MCP server in C# (official C# SDK)
dotnet new console
dotnet add package ModelContextProtocol
dotnet add package Microsoft.Extensions.Hostingusing 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(o =>
{
o.LogToStandardErrorThreshold = LogLevel.Trace; // with stdio, logs go to stderr — stdout is for the protocol
});
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly(); // registers [McpServerToolType] classes automatically
await builder.Build().RunAsync();
[McpServerToolType]
public static class EmployeeTools
{
[McpServerTool, Description("Returns the department of an employee by employee ID.")]
public static string GetDepartment(int empId) => empId == 1 ? "IT" : "HR";
}# Add it to Claude Code
claude mcp add employee-tools -- dotnet run --project ./EmployeeMcp18.2 MCP Authorization (remote / HTTP servers)
Authorization is optional. For servers with HTTP transport the spec is based on OAuth 2.1. stdio servers do not follow OAuth — they take credentials from the environment.
| Role | Who |
|---|---|
| Resource server | The MCP server (protected) |
| OAuth client | The MCP client (Claude Code, Claude Desktop...) |
| Authorization server | Issues tokens (Entra ID, Auth0, Okta, your own) |
- 1.1. Request without a token: server returns 401 + WWW-Authenticate
- 2.2. Protected Resource Metadata: find the auth server via RFC 9728
- 3.3. Auth server metadata: RFC 8414 / OIDC discovery
- 4.4. Client registration: Client ID Metadata Document / pre-registered
- 5.5. Browser login + PKCE: resource param (RFC 8707)
- 6.6. Access token: Authorization: Bearer ... on every request
The token must be valid only for that MCP server's audience
- PKCE is required; the token never goes in the URL query string, only in the Authorization header.
- The server must validate the token's audience — it must not accept a token meant for another service or pass it on (token passthrough).
- On insufficient scope the server returns 403 + error="insufficient_scope"; the client does step-up authorization.
- Dynamic Client Registration is now deprecated; Client ID Metadata Documents are preferred.
18.3 MCP ecosystem
| Item | Detail |
|---|---|
| Official SDKs | Python, TypeScript, C#, Java, Kotlin, Go, Rust, Swift, Ruby, PHP |
| MCP Registry | The official listing/discovery of public MCP servers |
| MCP Inspector | A developer tool to test/debug a server |
| Desktop extensions | A local MCP server as a one-click install package in Claude Desktop |
| Connectors (claude.ai) | Remote MCP servers that attach to claude.ai / Claude apps from the directory |
| Elicitation, sampling, roots | Client features — so a server can ask the user for input / ask for an LLM completion |