DotnetFastMCP
by tekspry
README.md
# DotnetFastMCP โ Enterprise Security & Governance Gateway for MCP Servers
[](https://github.com/tekspry/DotnetFastMCP/actions/workflows/ci.yml)
[](https://dotnet.microsoft.com)
[](https://dotnet.microsoft.com)
[](https://www.nuget.org/packages/DotnetFastMCP)
[](LICENSE)
[](https://github.com/tekspry/DotnetFastMCP)
**Enterprise security, governance, and observability layer for Model Context Protocol (MCP) servers in .NET โ OAuth 2.0/OIDC authentication, per-tool MFA enforcement, OpenTelemetry instrumentation, and zero-config health checks. Built on ASP.NET Core.**
## ๐ฏ Overview
DotnetFastMCP adds enterprise-grade security, governance, and observability to your MCP servers. While the core protocol is simple, running MCP tools in production requires OAuth 2.0/OIDC authentication, per-tool MFA enforcement, distributed tracing, and health monitoring โ none of which the base protocol provides. DotnetFastMCP handles all of this with a clean attribute-based API on ASP.NET Core, plus a **native .NET client library** for consuming MCP servers.
### โญ Key Features
#### โก Zero-Boilerplate MCP Servers (NEW! v2.1.0)
- โ
**Automatic DI Registration** - Non-static tool, resource, and prompt classes scanned via `WithComponentsFrom()` are automatically registered as `Transient` services in the DI container. Zero manual `builder.Services.AddTransient<T>()` boilerplate.
- โ
**Preserves Custom Lifetimes** - Built on `TryAddTransient` semantics to honor custom Singleton or Scoped registrations without collision.
- โ
**`[McpDescription]` Parameter Attributes** - Annotate method parameters with rich descriptions emitted directly into JSON Schema `inputSchema` (`tools/list`), significantly enhancing LLM tool-calling accuracy.
- โ
**Smart Schema Filtering** - Automatically hides framework-injected types (`McpContext`, `CancellationToken`, `ClaimsPrincipal`, `IMcpSession`) from schema exposure so LLMs only see valid user inputs.
#### ๐ .NET 10 LTS & .NET 8 LTS Dual Support (v2.0.0)
- โ
**Dual-Targeting** - Ships both `net8.0` and `net10.0` binaries in a single package
- โ
**Zero Breaking Changes** - 100% backward compatible for existing .NET 8 applications
- โ
**Modern Non-Blocking Async Streams** - High-performance SSE parsing compliant with .NET 10 CA2024 rules
- โ
**Comprehensive Test Matrix** - Dual-targeted unit & in-memory integration tests covering positive & negative scenarios
#### Core Framework
- โ
**Simple Attribute-Based API** - Declare tools and resources with `[McpTool]` and `[McpResource]` attributes
- โ
**First-Class Prompts Support** - Define prompts with `[McpPrompt]` for LLM interaction templates
- โ
**Automatic Component Discovery** - Reflection-based scanning of assemblies
- โ
**JSON-RPC 2.0 Compliant** - Full protocol compliance with proper error handling
- โ
**Flexible Parameter Binding** - Supports both array and named parameters
- โ
**Built on ASP.NET Core** - Leverage the powerful ASP.NET Core hosting model
- โ
**Production Ready** - Comprehensive error handling and logging
- โ
**Type-Safe** - Full C# type system integration
#### ๐ Enterprise Authentication
- โ
**6 OAuth Providers Supported** - Azure AD, Google, GitHub, Auth0, Okta, AWS Cognito
- โ
**OAuth Proxy Built-In** - Automatic Dynamic Client Registration (DCR) for non-DCR providers
- โ
**JWT Token Verification** - Automatic token validation with JWKS caching
- โ
**Zero Configuration** - Set environment variables and go
- โ
**Sensible Defaults** - Pre-configured scopes for common use cases
- โ
**Fine-Grained Authorization** - Protect tools with `[Authorize]` attribute
- โ
**Claims-Based Access** - Access user information from authenticated requests
- โ
**MFA Support** - Enforce Multi-Factor Authentication for sensitive tools
#### ๐ Native Client Library
- โ
**McpClient** - Type-safe .NET client for consuming any MCP server
- โ
**Transport Agnostic** - Support for both Stdio and SSE connections
- โ
**Notification Handling** - Events for real-time logs and progress
- โ
**Tool Invocation** - Clean `CallToolAsync<T>` API
#### ๐ค LLM Integration
- โ
**8 LLM Providers** - Ollama, OpenAI, Azure OpenAI, Anthropic Claude, Google Gemini, Cohere, Hugging Face, Deepseek
- โ
**Latest Models (Feb 2026)** - Claude Opus 4.6, Gemini 3 Pro/Flash, Command A, DeepSeek V3.2
- โ
**Unified Interface** - Single `ILLMProvider` API for all providers
- โ
**Streaming Support** - Real-time token streaming with `IAsyncEnumerable<string>`
- โ
**Production-Ready** - HttpClientFactory, Polly retry policies, connection pooling
- โ
**Plug-and-Play** - Simple extension methods: `builder.AddAnthropicProvider()`
#### ๐ก Observability
- โ
**OpenTelemetry Integration** - First-class metrics and distributed tracing
- โ
**5 Auto-Tracked Metrics** - Tool invocations, duration, errors, prompt requests, resource reads
- โ
**One-Line Setup** - `builder.WithTelemetry()` โ zero boilerplate
- โ
**Exporter Agnostic** - Plug in Prometheus, Application Insights, Grafana, Jaeger, or any OTLP backend
- โ
**OTel Semantic Conventions** - Standard tag names, exception events, span status
- โ
**Zero Overhead When Disabled** - Fully opt-in, no performance cost if unused
- โ
**Stdio + HTTP** - Metrics work across both transports
#### ๐ฅ Health Checks & Diagnostics
- โ
**Built-In Health Endpoint** - `GET /mcp/health` exposed automatically
- โ
**One-Line Setup** - `builder.WithHealthChecks()` โ no configuration required
- โ
**Plug-In Custom Checks** - Add any check as a simple lambda (no interfaces needed)
- โ
**Parallel Execution** - All checks run concurrently with per-check timeout
- โ
**Standard HTTP Status Codes** - 200 Healthy / 207 Degraded / 503 Unhealthy
- โ
**Kubernetes & Docker Ready** - Drop-in for liveness/readiness probes
- โ
**Auto Server Diagnostics** - Tool count, uptime, framework version included
- โ
**Zero Overhead When Disabled** - Fully opt-in, endpoint not registered unless configured
## ๐ Quick Start
### Installation
Install via NuGet Package Manager:
```bash
dotnet add package DotnetFastMCP --version 2.1.1
```
Or clone the repository:
```bash
git clone https://github.com/tekspry/DotnetFastMCP.git
cd DotnetFastMCP
dotnet build -c Release
```
### Create Your First MCP Server
#### 1. Define Your Tools
Tools can be written as instance classes with constructor dependency injection (auto-registered!) or static methods:
```csharp
using FastMCP.Attributes;
using Microsoft.Extensions.Logging;
// Instance-based tool with constructor injection (automatically registered into DI via WithComponentsFrom!)
public class CalculatorTools
{
private readonly ILogger<CalculatorTools> _logger;
public CalculatorTools(ILogger<CalculatorTools> logger)
{
_logger = logger;
}
[McpTool(Description = "Performs mathematical addition")]
public int Add(
[McpDescription("The first number to add")] int a,
[McpDescription("The second number to add")] int b)
{
_logger.LogInformation("Adding {A} + {B}", a, b);
return a + b;
}
}
// Static tools are also supported out of the box
public static class EchoTools
{
[McpTool(Description = "Returns an echo of the input message")]
public static string Echo(
[McpDescription("Text message to echo back")] string message) => message;
}
```
#### 2. Create Program.cs
```csharp
using FastMCP.Hosting;
using FastMCP.Server;
using System.Reflection;
var server = new FastMCPServer("MyMcpServer");
var builder = McpServerBuilder.Create(server, args);
builder.WithComponentsFrom(Assembly.GetExecutingAssembly());
var app = builder.Build();
await app.RunMcpAsync(args);
```
### Running the Example Server
```bash
cd examples/BasicServer
dotnet run
```
The server will start on `http://localhost:5000`.
## ๐ Built With DotnetFastMCP
Real-world enterprise projects that demonstrate DotnetFastMCP in production:
### ๐ Fashion Accessory AI Marketing Pipeline
[](https://github.com/tekspry/fashion-pipeline)
[](https://dotnet.microsoft.com)
[](https://a2a-protocol.org)
An enterprise-grade, distributed multimodal AI pipeline on **.NET 10 LTS** that automates the transformation of raw fashion accessory photographs into commercial marketing visuals and video content.
**Architecture highlights:**
- ๐๏ธ **Two-Dimensional AI Architecture** โ DotnetFastMCP (vertical MCP tool layer) + Google A2A Protocol (horizontal agent communication)
- ๐ค **5 DotnetFastMCP Servers** โ `VisionMcpServer`, `PromptMcpServer`, `ImageMcpServer`, `InpaintingMcpServer`, `VideoMcpServer`
- ๐จ **Multimodal AI** โ Gemini 3.1 Flash Image for dual-conditioning image synthesis, Kling AI for video generation
- ๐ก๏ธ **Multi-Tenant SaaS** โ Entity Framework Core global query filters with tenant isolation
- โฑ๏ธ **Async Background Jobs** โ Hangfire with exponential backoff and rate-limit protection
```
OrchestratorAgent (A2A)
โโโ VisionAgent โ VisionMcpServer :5100 (extract_accessory_features)
โโโ CreativeAgent โ PromptMcpServer :5200 (generate_image_prompts)
โโโ ImageAgent โ ImageMcpServer :5300 (generate_accessory_image)
โโโ InpaintingAgent โ InpaintingMcpServer :5500 (inpaint_accessory)
โโโ VideoAgent โ VideoMcpServer :5400 (generate_accessory_video)
```
> ๐ [View Repository โ](https://github.com/tekspry/fashion-pipeline)
---
## ๐ Architecture
### Core Components
```
DotnetFastMCP/
โโโ src/
โ โโโ FastMCP/
โ โ โโโ Attributes/ # Component declaration attributes
โ โ โโโ Client/ # ๐ Client library implementation
โ โ โโโ Hosting/ # Server hosting and middleware
โ โ โโโ Protocol/ # JSON-RPC protocol implementation
โ โ โโโ Server/ # FastMCPServer core class
โ โ โโโ FastMCP.csproj
โ โโโ FastMCP.CLI/ # Command-line utilities
โโโ examples/
โ โโโ BasicServer/ # Example MCP server implementation
โโโ tests/
โ โโโ McpIntegrationTest/ # Integration tests
โโโ LAUNCH_TESTS.ps1 # PowerShell test suite launcher
โโโ RUN_AND_TEST.ps1 # PowerShell integration test script
```
### Project Structure
| Project | Purpose |
|---------|---------|
| `FastMCP` | Core framework library |
| `FastMCP.CLI` | Command-line interface tools |
| `BasicServer` | Example MCP server implementation |
| `McpIntegrationTest` | Integration tests |
| `ClientDemo` | Example Client consuming BasicServer |
## ๐ง Creating an MCP Server
### 1. Define Components
For better organization, split your components into multiple files (e.g., `Tools.cs`, `Resources.cs`). The framework will discover them automatically.
**File: `Tools.cs`**
```csharp
using FastMCP.Attributes;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;
public static class MyTools
{
/// <summary>
/// Public tool - no authentication required
/// </summary>
[McpTool]
public static int Add(int a, int b) => a + b;
public static class Resources
{
/// <summary>
/// Protected tool - requires authentication
/// </summary>
[McpTool]
[Authorize]
public static object GetUserProfile(ClaimsPrincipal user)
{
return new
{
Name = user.Identity?.Name,
Email = user.FindFirst("email")?.Value,
IsAuthenticated = user.Identity?.IsAuthenticated
};
}
}
```
#### 2. Configure Server with Authentication
```csharp
using FastMCP.Hosting;
using FastMCP.Server;
using System.Reflection;
var mcpServer = new FastMCPServer(name: "My Secure MCP Server");
var builder = McpServerBuilder.Create(mcpServer, args);
// Add authentication (choose your provider)
builder.AddAzureAdTokenVerifier(); // or AddGoogleTokenVerifier(), AddGitHubTokenVerifier(), etc.
// Register tools
builder.WithComponentsFrom(Assembly.GetExecutingAssembly());
var app = builder.Build();
app.Urls.Add("http://localhost:5002");
await app.RunAsync();
```
#### 3. Set Environment Variables
```powershell
# Windows PowerShell
$env:FASTMCP_SERVER_AUTH_AZUREAD_TENANT_ID="your-tenant-id"
$env:FASTMCP_SERVER_AUTH_AZUREAD_CLIENT_ID="your-client-id"
$env:FASTMCP_SERVER_AUTH_AZUREAD_CLIENT_SECRET="your-client-secret"
```
```bash
# Linux/Mac
export FASTMCP_SERVER_AUTH_AZUREAD_TENANT_ID="your-tenant-id"
export FASTMCP_SERVER_AUTH_AZUREAD_CLIENT_ID="your-client-id"
export FASTMCP_SERVER_AUTH_AZUREAD_CLIENT_SECRET="your-client-secret"
```
#### 4. Run and Test
```bash
dotnet run
```
Your server is now running with **OAuth Proxy** endpoints:
- MCP endpoint: `http://localhost:5002/mcp`
- OAuth authorization: `http://localhost:5002/oauth/authorize`
- OAuth token: `http://localhost:5002/oauth/token`
- Discovery: `http://localhost:5002/.well-known/oauth-authorization-server`
#### Stdio Mode
You can also run the server in Stdio mode (for local LLM clients):
```bash
dotnet run -- --stdio
```
### Create an MCP Client
Connect to any MCP server using the C# Client Library:
```csharp
using FastMCP.Client;
using FastMCP.Client.Transports;
// 1. Connect (via Stdio or SSE)
var transport = new StdioClientTransport("dotnet", "run --project examples/BasicServer -- --stdio");
await using var client = new McpClient(transport);
await client.ConnectAsync();
// 2. List & Call Tools
var tools = await client.ListToolsAsync();
var result = await client.CallToolAsync<int>("add_numbers", new { a = 10, b = 20 });
```
## ๐ Authentication Providers
DotnetFastMCP supports **6 enterprise-grade OAuth providers** out of the box:
| Provider | Method | Use Case | Default Scopes |
|----------|--------|----------|----------------|
| **Azure AD** | `AddAzureAdTokenVerifier()` | Enterprise apps, Microsoft 365 | `openid`, `profile`, `email`, `offline_access` |
| **Google** | `AddGoogleTokenVerifier()` | Consumer apps, Google Workspace | `openid`, `profile`, `email`, `userinfo.profile` |
| **GitHub** | `AddGitHubTokenVerifier()` | Developer tools, repositories | `read:user`, `user:email` |
| **Auth0** | `AddAuth0TokenVerifier()` | Multi-tenant SaaS, custom identity | `openid`, `profile`, `email`, `offline_access` |
| **Okta** | `AddOktaTokenVerifier()` | Enterprise SSO, workforce identity | `openid`, `profile`, `email`, `offline_access` |
| **AWS Cognito** | `AddAwsCognitoTokenVerifier()` | AWS-native apps, user pools | `openid`, `profile`, `email` |
### Quick Setup Examples
<details>
<summary><b>Azure AD</b></summary>
```csharp
builder.AddAzureAdTokenVerifier();
```
**Environment Variables:**
```bash
FASTMCP_SERVER_AUTH_AZUREAD_TENANT_ID=your-tenant-id
FASTMCP_SERVER_AUTH_AZUREAD_CLIENT_ID=your-client-id
FASTMCP_SERVER_AUTH_AZUREAD_CLIENT_SECRET=your-client-secret
```
**Example:** [`examples/Auth/AzureAdOAuth`](examples/Auth/AzureAdOAuth)
</details>
<details>
<summary><b>Google</b></summary>
```csharp
builder.AddGoogleTokenVerifier();
```
**Environment Variables:**
```bash
FASTMCP_SERVER_AUTH_GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
FASTMCP_SERVER_AUTH_GOOGLE_CLIENT_SECRET=your-client-secret
```
**Example:** [`examples/Auth/GoogleOAuth`](examples/Auth/GoogleOAuth)
</details>
<details>
<summary><b>GitHub</b></summary>
```csharp
builder.AddGitHubTokenVerifier();
```
**Environment Variables:**
```bash
FASTMCP_SERVER_AUTH_GITHUB_CLIENT_ID=your-github-client-id
FASTMCP_SERVER_AUTH_GITHUB_CLIENT_SECRET=your-github-client-secret
```
**Example:** [`examples/Auth/GitHubOAuth`](examples/Auth/GitHubOAuth)
</details>
### PowerShell Integration Test Suite
The project includes a comprehensive PowerShell-based integration test suite that validates a running server end-to-end.
1. **Publish the server** (from the root of the `DotnetFastMCP` project):
```sh
dotnet publish -c Release -o ..\publish examples\BasicServer
```
2. **Run the tests**:
Open a PowerShell terminal and run the launcher script from the project root:
```powershell
.\LAUNCH_TESTS.ps1
```
This will open a new window, start the `BasicServer`, and run a series of tests covering all tools and resources, including error handling.
### Example Manual Test
<details>
<summary><b>Auth0</b></summary>
```csharp
builder.AddAuth0TokenVerifier();
```
**Environment Variables:**
```bash
FASTMCP_SERVER_AUTH_AUTH0_DOMAIN=your-tenant.auth0.com
FASTMCP_SERVER_AUTH_AUTH0_AUDIENCE=https://your-api-identifier
FASTMCP_SERVER_AUTH_AUTH0_CLIENT_ID=your-client-id
FASTMCP_SERVER_AUTH_AUTH0_CLIENT_SECRET=your-client-secret
```
**Example:** [`examples/Auth/Auth0OAuth`](examples/Auth/Auth0OAuth)
</details>
<details>
<summary><b>Okta</b></summary>
```csharp
builder.AddOktaTokenVerifier();
```
**Environment Variables:**
```bash
FASTMCP_SERVER_AUTH_OKTA_DOMAIN=dev-123456.okta.com
FASTMCP_SERVER_AUTH_OKTA_AUDIENCE=api://default
FASTMCP_SERVER_AUTH_OKTA_CLIENT_ID=your-client-id
FASTMCP_SERVER_AUTH_OKTA_CLIENT_SECRET=your-client-secret
```
**Example:** [`examples/Auth/OktaOAuth`](examples/Auth/OktaOAuth)
</details>
<details>
<summary><b>AWS Cognito</b></summary>
```csharp
builder.AddAwsCognitoTokenVerifier();
```
**Environment Variables:**
```bash
FASTMCP_SERVER_AUTH_AWSCOGNITO_USER_POOL_ID=us-east-1_XXXXXXXXX
FASTMCP_SERVER_AUTH_AWSCOGNITO_REGION=us-east-1
FASTMCP_SERVER_AUTH_AWSCOGNITO_CLIENT_ID=your-app-client-id
FASTMCP_SERVER_AUTH_AWSCOGNITO_CLIENT_SECRET=your-app-client-secret
FASTMCP_SERVER_AUTH_AWSCOGNITO_DOMAIN=myapp.auth.us-east-1.amazoncognito.com
```
**Example:** [`examples/Auth/AwsCognitoOAuth`](examples/Auth/AwsCognitoOAuth)
</details>
## ๐ Architecture
### Project Structure
```
DotnetFastMCP/
โโโ src/
โ โโโ FastMCP/
โ โโโ Attributes/ # Component declaration attributes
โ โโโ Authentication/ # ๐ OAuth providers & token verification
โ โ โโโ Providers/ # Azure AD, Google, GitHub, Auth0, Okta, AWS
โ โ โโโ Proxy/ # OAuth Proxy for DCR
โ โ โโโ Verification/ # JWT token validation
โ โโโ Hosting/ # Server hosting and middleware
โ โโโ Protocol/ # JSON-RPC protocol implementation
โ โโโ Server/ # FastMCPServer core class
โโโ examples/
โ โโโ BasicServer/ # Simple MCP server
โ โโโ Auth/ # ๐ Authentication examples
โ โโโ AzureAdOAuth/ # Azure AD example
โ โโโ GoogleOAuth/ # Google OAuth example
โ โโโ GitHubOAuth/ # GitHub OAuth example
โ โโโ Auth0OAuth/ # Auth0 example
โ โโโ OktaOAuth/ # Okta example
โ โโโ AwsCognitoOAuth/ # AWS Cognito example
โโโ tests/
โโโ McpIntegrationTest/ # Integration tests
```
### Project Structure (Client)
The `FastMCP` framework now includes a complete client implementation in `src/FastMCP/Client`.
```mermaid
graph TD
App[Your App] -->|Uses| Client[McpClient]
Client -->|IClientTransport| Trans[Transport Layer]
Trans -->|Stdio| Local[Local Process]
Trans -->|SSE/HTTP| Remote[Remote Server]
```
### Authentication Flow
```mermaid
sequenceDiagram
participant Client
participant MCP Server
participant OAuth Provider
Client->>MCP Server: Request with Bearer Token
MCP Server->>Token Verifier: Validate Token
Token Verifier->>OAuth Provider: Fetch JWKS (if needed)
OAuth Provider-->>Token Verifier: Public Keys
Token Verifier-->>MCP Server: Validated Claims
MCP Server-->>Client: Protected Resource
```
## ๐ง Creating an MCP Server
### Basic Server (No Authentication)
```csharp
using FastMCP.Hosting;
using FastMCP.Server;
using System.Reflection;
var mcpServer = new FastMCPServer(name: "My MCP Server");
var builder = McpServerBuilder.Create(mcpServer, args);
builder.WithComponentsFrom(Assembly.GetExecutingAssembly());
var app = builder.Build();
await app.RunAsync();
```
### Secure Server (With Authentication)
```csharp
using FastMCP.Hosting;
using FastMCP.Server;
using System.Reflection;
var mcpServer = new FastMCPServer(name: "My Secure MCP Server");
var builder = McpServerBuilder.Create(mcpServer, args);
// Add authentication - automatically configures OAuth Proxy
builder.AddAzureAdTokenVerifier(); // or any other provider
builder.WithComponentsFrom(Assembly.GetExecutingAssembly());
var app = builder.Build();
app.Urls.Add("http://localhost:5002");
await app.RunMcpAsync(args);
```
### Protected Tools
```csharp
using FastMCP.Attributes;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;
public static class SecureTools
{
/// <summary>
/// Public tool - anyone can call
/// </summary>
[McpTool]
public static string Echo(string message) => message;
/// <summary>
/// Protected tool - requires valid OAuth token
/// </summary>
[McpTool]
[Authorize]
public static object GetUserInfo(ClaimsPrincipal user)
{
return new
{
Name = user.Identity?.Name ?? "Unknown",
Email = user.FindFirst("email")?.Value ?? "Not available",
IsAuthenticated = user.Identity?.IsAuthenticated ?? false,
Claims = user.Claims.Select(c => new { c.Type, c.Value }).ToList()
};
}
/// <summary>
/// Role-based authorization
/// </summary>
[McpTool]
[Authorize(Roles = "Admin")]
public static string AdminOnly() => "Admin access granted";
}
```
## ๐ก JSON-RPC Protocol
### Prompts
Prompts allow servers to provide templates that LLMs can use.
```csharp
using FastMCP.Attributes;
using FastMCP.Protocol;
public static class MyPrompts
{
[McpPrompt("analyze_code")]
public static GetPromptResult Analyze(string code)
{
return new GetPromptResult
{
Description = "Analyze the given code",
Messages = new List<PromptMessage>
{
new PromptMessage
{
Role = "user",
Content = new { type = "text", text = $"Please analyze this code:\n{code}" }
}
}
};
}
}
```
### Calling Tools
**Public Tool (No Auth):**
```json
POST /mcp
{
"jsonrpc": "2.0",
"method": "Echo",
"params": ["Hello World"],
"id": 1
}
```
**Protected Tool (With Auth):**
```json
POST /mcp
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc...
{
"jsonrpc": "2.0",
"method": "GetUserInfo",
"params": [],
"id": 2
}
```
## ๐งช Testing
### Run All Tests
```bash
dotnet test
```
### Test Authentication Flow
Each authentication example includes a comprehensive `.rest` file for testing:
```bash
# Open in VS Code with REST Client extension
code examples/Auth/AzureAdOAuth/azure-ad-auth-tests.rest
```
Test files include:
- โ
Discovery endpoints
- โ
Public tool tests
- โ
Protected tool tests (should fail without auth)
- โ
OAuth authorization flow
- โ
Token exchange
- โ
Provider-specific API calls
## ๐ Documentation
### Guides & Features
- [Automatic DI Registration & Parameter Descriptions Guide](docs/auto-di-registration-guide.md) (NEW! v2.1.0)
- [Health Checks & Diagnostics Guide](docs/health-checks-guide.md)
- [Observability & OpenTelemetry Guide](docs/observability-guide.md)
- [LLM Integration Guide](docs/llm-integration-guide.md)
- [MFA Support Guide](docs/mfa-support-guide.md)
- [Prompts Feature Guide](docs/prompts-feature-guide.md)
- [Client Library Guide](docs/client-library-guide.md)
- [Storage Abstraction Guide](docs/storage-abstraction-guide.md)
- [Server Composition Guide](docs/server-composition-guide.md)
- [Middleware Interception Guide](docs/middleware-interception-guide.md)
- [SSE Transport Guide](docs/sse-transport-guide.md)
- [Stdio Transport Guide](docs/stdio-transport-guide.md)
### Complete Authentication Guide
See [MFA Support Guide](docs/mfa-support-guide.md) for enforcing Multi-Factor Authentication on sensitive tools, and the individual provider README files under `examples/Auth/` for detailed OAuth setup instructions.
### Example Projects
| Example | Description | Port |
|---------|-------------|------|
| [BasicServer](examples/BasicServer) | Simple MCP server with Auto-DI & [McpDescription] | 5000 |
| [HealthChecksDemo](examples/HealthChecksDemo) | ๐ฅ Health monitoring & diagnostics demo | 5000 |
| [TelemetryDemo](examples/TelemetryDemo) | ๐ก OpenTelemetry metrics & tracing demo | 5000 |
| [AzureAdOAuth](examples/Auth/AzureAdOAuth) | Azure AD authentication example | 5002 |
| [GoogleOAuth](examples/Auth/GoogleOAuth) | Google OAuth example | 5000 |
| [GitHubOAuth](examples/Auth/GitHubOAuth) | GitHub OAuth example | 5001 |
| [Auth0OAuth](examples/Auth/Auth0OAuth) | Auth0 authentication example | 5005 |
| [OktaOAuth](examples/Auth/OktaOAuth) | Okta authentication example | 5007 |
| [AwsCognitoOAuth](examples/Auth/AwsCognitoOAuth) | AWS Cognito example | 5006 |
## ๐๏ธ Advanced Features
### โก Automatic DI Registration & [McpDescription] (NEW! v2.1.0)
DotnetFastMCP 2.1 makes authoring production MCP servers completely zero-boilerplate by pairing automatic Dependency Injection with LLM-grade parameter schemas:
1. **Zero-Config DI**: Non-static tool, resource, and prompt classes scanned with `WithComponentsFrom()` are automatically registered as `Transient` into ASP.NET Core DI. No more manual `builder.Services.AddTransient<OrderTools>()` lines.
2. **Preserves Custom Lifetimes**: Built on `TryAddTransient` semantics, so any class explicitly registered as `Singleton` or `Scoped` in `builder.Services` retains its desired lifetime.
3. **`[McpDescription]` for Parameters**: Annotate tool parameters with descriptions that are exposed directly in the JSON Schema `inputSchema` (`tools/list`), giving LLMs exact semantic context and eliminating hallucinated arguments.
4. **Framework Parameter Exclusion**: Types such as `McpContext`, `CancellationToken`, `ClaimsPrincipal`, and `IMcpSession` are automatically filtered out from the public schema.
```csharp
public class OrderTools
{
private readonly IOrderRepository _repository;
private readonly ILogger<OrderTools> _logger;
// Injected automatically via ASP.NET Core DI
public OrderTools(IOrderRepository repository, ILogger<OrderTools> logger)
{
_repository = repository;
_logger = logger;
}
[McpTool(Description = "Retrieves order status by order identifier and country")]
public async Task<string> GetOrderStatus(
[McpDescription("Unique order ID, e.g. ORD-98765")] string orderId,
[McpDescription("Two-letter country code, e.g. US, UK")] string countryCode = "US",
CancellationToken ct = default) // Framework types are automatically excluded from the tool schema
{
_logger.LogInformation("Fetching order {OrderId} in {Country}", orderId, countryCode);
return await _repository.GetStatusAsync(orderId, countryCode, ct);
}
}
```
```csharp
// Program.cs - Zero boilerplate registration!
var server = new FastMCPServer("OrderServer");
var builder = McpServerBuilder.Create(server, args);
// Automatically registers OrderTools as Transient, discovers [McpTool], and configures schemas!
builder.WithComponentsFrom(Assembly.GetExecutingAssembly());
var app = builder.Build();
await app.RunMcpAsync(args);
```
### ๐ฅ Health Checks & Diagnostics (v1.15.0)
FastMCP ships with a built-in production health check endpoint. Enable with one line and plug in any custom check as a simple lambda.
```csharp
using FastMCP.Health;
// Zero-config โ exposes GET /mcp/health automatically
builder.WithHealthChecks();
// With custom checks (database, LLM provider, memory, etc.)
builder.WithHealthChecks(checks =>
{
checks.AddCheck("memory", () =>
GC.GetTotalMemory(false) < 500_000_000L); // sync: < 500 MB
checks.AddAsyncCheck("database", async ct =>
await dbContext.Database.CanConnectAsync(ct));
checks.AddAsyncCheck("llm_provider", async ct =>
await llmProvider.IsHealthyAsync(ct));
});
```
**Response JSON (HTTP 200 โ Healthy):**
```json
{
"status": "Healthy",
"timestamp": "2026-04-19T20:00:00Z",
"checks": [
{ "name": "mcp_server", "status": "Healthy", "durationMs": 0 },
{ "name": "memory", "status": "Healthy", "durationMs": 0.1 },
{ "name": "database", "status": "Healthy", "durationMs": 4.9 },
{ "name": "llm_provider", "status": "Healthy", "durationMs": 22.3 }
],
"diagnostics": {
"serverName": "my-mcp-server",
"frameworkVersion": "1.15.0.0",
"toolCount": 12,
"uptimeSeconds": 3721.4
}
}
```
**HTTP status code mapping:**
| Status | HTTP Code | Meaning |
|---|---|---|
| `Healthy` | **200** | All checks passed |
| `Degraded` | **207** | Server up, โฅ1 check timed out |
| `Unhealthy` | **503** | โฅ1 check failed or threw |
**Kubernetes liveness / readiness probe:**
```yaml
livenessProbe:
httpGet:
path: /mcp/health
port: 5000
initialDelaySeconds: 15
periodSeconds: 30
readinessProbe:
httpGet:
path: /mcp/health
port: 5000
periodSeconds: 10
```
**See [Health Checks Guide](docs/health-checks-guide.md) for full documentation**, including Docker Compose, Azure Container Apps, per-check timeout configuration, unit testing patterns, and complete validation examples.
---
### ๐ก Observability โ OpenTelemetry (v1.14.0)
FastMCP ships with built-in OpenTelemetry instrumentation. Enable with one line and connect to any backend.
```csharp
using FastMCP.Telemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;
// 1. Enable FastMCP telemetry (one line)
builder.WithTelemetry(t =>
{
t.ServiceName = "my-mcp-server";
t.EnableMetrics = true;
t.EnableTracing = true;
});
// 2. Configure your exporter of choice
builder.Services.AddOpenTelemetry()
.WithMetrics(m =>
{
m.AddMcpInstrumentation(); // FastMCP extension method
m.AddPrometheusExporter(); // or AddConsoleExporter(), AddOtlpExporter()
})
.WithTracing(t =>
{
t.AddMcpInstrumentation(); // FastMCP extension method
t.AddOtlpExporter(); // or AddJaeger(), AddZipkin()
});
```
**Metrics automatically tracked:**
| Metric | Type | Tag | Description |
|--------|------|-----|-------------|
| `mcp.tool.invocations` | Counter | `tool.name` | Total tool calls |
| `mcp.tool.duration` | Histogram (ms) | `tool.name` | Tool execution time |
| `mcp.tool.errors` | Counter | `tool.name` | Failed tool calls |
| `mcp.prompt.requests` | Counter | โ | Prompt template requests |
| `mcp.resource.reads` | Counter | โ | Resource read requests |
**Validate with dotnet-counters (no exporter needed):**
```powershell
dotnet-counters monitor -n YourAppName --counters FastMCP
```
**See [Observability Guide](docs/observability-guide.md) for full documentation**, including production exporter setup, distributed tracing details, and real request/response validation examples.
---
### Middleware Interception
Middleware allows you to intercept and modify JSON-RPC messages (requests and responses) flowing through the server pipeline. This is useful for logging, validation, modification, or custom monitoring.
1. **Define Middleware:** Implement `IMcpMiddleware`.
2. **Register Middleware:** Use `builder.AddMcpMiddleware<T>()`.
```csharp
public class LoggingMiddleware : IMcpMiddleware
{
public async Task<JsonRpcResponse> InvokeAsync(McpMiddlewareContext context, McpMiddlewareDelegate next, CancellationToken ct)
{
Console.Error.WriteLine($"[LOG] Incoming: {context.Request.Method}");
// Pass to next handler
var response = await next(context, ct);
Console.Error.WriteLine($"[LOG] Completed. Error: {response.Error != null}");
return response;
}
}
// In Program.cs:
builder.AddMcpMiddleware<LoggingMiddleware>();
```
### Server Composition (NEW!)
Mount other MCP servers into your main server instantiation. This supports a "Micro-MCP" architecture where you can compose a robust agent from smaller, focused modules.
```csharp
// 1. Create Sub-Server (e.g. GitHub Tools)
var githubServer = new FastMCPServer("GitHub");
// ... register tools ...
// 2. Import into Main Server with "gh" prefix
builder.AddServer(githubServer, prefix: "gh");
// Result:
// The client sees tools named: "gh_create_issue", "gh_get_repo", etc.
```
### MFA Support (NEW!)
Enforce Multi-Factor Authentication for sensitive tools.
```csharp
[McpTool("transfer_funds")]
[AuthorizeMcpTool(RequireMfa = true)]
public static string TransferFunds()
{
return "Transferred!";
}
```
- **MFA Check**: Verifies `amr` claim contains `mfa`.
- **Security**: Provides granular protection for critical operations.
### Storage Abstraction (NEW!)
FastMCP now includes a built-in state persistence layer. Tools can request `McpContext` to access `IMcpStorage`.
```csharp
[McpTool]
public static async Task<string> SetValue(string key, string value, McpContext context)
{
await context.Storage.SetAsync(key, value);
return "Saved!";
}
```
The default implementation is **In-Memory**, but you can swap it for Redis, SQL, or File storage:
```csharp
builder.AddMcpStorage<MyRedisStorage>();
```
### LLM Integration (NEW!)
FastMCP includes a powerful LLM integration system with **8 providers** supporting the latest models (Feb 2026).
#### Quick Setup
```csharp
using FastMCP.AI;
// Option 1: Local (Ollama)
builder.AddOllamaProvider(options =>
{
options.BaseUrl = "http://localhost:11434";
options.DefaultModel = "llama3.1:8b";
});
// Option 2: Cloud (Anthropic Claude Opus 4.6 - Latest)
builder.AddAnthropicProvider(options =>
{
options.ApiKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY")!;
options.DefaultModel = "claude-opus-4.6"; // 1M context, Feb 2026
});
// Option 3: Google Gemini 3
builder.AddGeminiProvider(options =>
{
options.ApiKey = Environment.GetEnvironmentVariable("GEMINI_API_KEY")!;
options.DefaultModel = "gemini-3-flash"; // Fast, cost-effective
});
```
#### Use in Tools
```csharp
public class AITools
{
private readonly ILLMProvider _llm;
public AITools(ILLMProvider llm) => _llm = llm;
[McpTool("generate_story")]
public async Task<string> GenerateStory(string topic)
{
return await _llm.GenerateAsync(
$"Write a story about {topic}",
new LLMGenerationOptions
{
SystemPrompt = "You are a creative storyteller.",
Temperature = 0.8,
MaxTokens = 500
});
}
[McpTool("stream_response")]
public async IAsyncEnumerable<string> StreamResponse(string prompt)
{
await foreach (var token in _llm.StreamAsync(prompt))
{
yield return token;
}
}
}
```
#### Supported Providers (Feb 2026)
| Provider | Extension Method | Latest Model | Best For |
|----------|------------------|--------------|----------|
| **Ollama** | `AddOllamaProvider()` | `llama3.1:8b` | Local, privacy, offline |
| **OpenAI** | `AddOpenAIProvider()` | `gpt-4-turbo` | Production, function calling |
| **Azure OpenAI** | `AddAzureOpenAIProvider()` | `gpt-4` | Enterprise, compliance |
| **Anthropic** | `AddAnthropicProvider()` | `claude-opus-4.6` | Deep reasoning, 1M context |
| **Google Gemini** | `AddGeminiProvider()` | `gemini-3-flash` | Multimodal, high-volume |
| **Cohere** | `AddCohereProvider()` | `command-a` | Enterprise RAG, agents |
| **Hugging Face** | `AddHuggingFaceProvider()` | Any model | Open-source, flexibility |
| **Deepseek** | `AddDeepseekProvider()` | `deepseek-v3.2` | Cost-effective, reasoning |
**See [LLM Integration Guide](docs/llm-integration-guide.md) for complete documentation.**
### Background Tasks (NEW!)
FastMCP allows tools to fire-and-forget long running operations using `RunInBackground`.
```csharp
[McpTool]
public static async Task<string> ProcessFile(string file, McpContext context)
{
await context.RunInBackground(async (ct) =>
{
// This runs without blocking the client
await HeavyProcessing(file, ct);
});
return "Processing started!";
}
```
### Icons Support (NEW!)
Enhance the user interface of clients by providing icons for your server and tools.
```csharp
// Server Icon
server.Icon = "https://myserver.com/logo.png";
// Tool Icon
[McpTool(Icon = "https://myserver.com/tools/calc.png")]
public static int Add(int a, int b) => a + b;
```
### Binary Content Support (NEW!)
Return rich content like Images from your tools and prompts.
```csharp
[McpTool]
public static CallToolResult GetSnapshot()
{
return new CallToolResult
{
Content = new List<ContentItem>
{
new ImageContent { Data = "base64...", MimeType = "image/png" }
}
};
}
```
### OAuth Proxy
DotnetFastMCP includes a built-in **OAuth Proxy** that provides:
- โ
**Dynamic Client Registration (DCR)** - Automatic client registration for MCP clients
- โ
**Authorization Code Flow** - Full OAuth 2.0 authorization code flow with PKCE
- โ
**Token Management** - Automatic token exchange, refresh, and revocation
- โ
**Discovery Endpoints** - RFC 8414 compliant OAuth discovery
**Automatically Available Endpoints:**
- `/.well-known/oauth-authorization-server` - OAuth server metadata
- `/oauth/authorize` - Authorization endpoint
- `/oauth/token` - Token endpoint
- `/oauth/register` - Dynamic client registration
- `/oauth/userinfo` - User information endpoint
### Custom Scopes
Override default scopes for any provider:
```csharp
builder.AddAzureAdTokenVerifier(new AzureAdAuthOptions
{
RequiredScopes = new[] { "openid", "profile", "email", "User.Read", "Calendars.Read" }
});
```
### Multiple Authentication Schemes
```csharp
// Support multiple providers simultaneously
builder.AddAzureAdTokenVerifier();
builder.AddGoogleTokenVerifier();
builder.AddGitHubTokenVerifier();
```
## ๐ Security Best Practices
### Development
- โ
Use environment variables for secrets
- โ
Never commit credentials to source control
- โ
Use `.env` files for local development
- โ
Test with short-lived tokens
### Production
- โ
Use HTTPS for all communication
- โ
Store secrets in Azure Key Vault / AWS Secrets Manager
- โ
Enable MFA for OAuth providers
- โ
Implement rate limiting
- โ
Monitor authentication logs
- โ
Use separate app registrations per environment
- โ
Validate token scopes match required permissions
## ๐ฆ NuGet Package
Install from NuGet (when published):
```bash
dotnet add package DotnetFastMCP
```
## ๐ค Contributing
Contributions are welcome! Please:
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## ๐ License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## ๐ Resources
### Official Documentation
- [Model Context Protocol Specification](https://modelcontextprotocol.io)
- [JSON-RPC 2.0 Specification](https://www.jsonrpc.org/specification)
- [OAuth 2.0 RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749)
- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)
### Framework Documentation
- [Health Checks Guide](docs/health-checks-guide.md) ๐ **v1.15.0**
- [Observability Guide](docs/observability-guide.md) **v1.14.0**
- [LLM Integration Guide](docs/llm-integration-guide.md)
- [Protocol Discovery Guide](docs/protocol-discovery-guide.md)
- [Client Library Guide](docs/client-library-guide.md)
- [Context & Interaction Guide](docs/context-interaction-guide.md)
- [Middleware Interception Guide](docs/middleware-interception-guide.md)
- [SSE Transport Guide](docs/sse-transport-guide.md)
- [Stdio Transport Guide](docs/stdio-transport-guide.md)
- [ASP.NET Core Documentation](https://docs.microsoft.com/en-us/aspnet/core/)
- [.NET 8.0 Documentation](https://docs.microsoft.com/en-us/dotnet/)
### Provider Documentation
- [Azure AD OAuth 2.0](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow)
- [Google OAuth 2.0](https://developers.google.com/identity/protocols/oauth2)
- [GitHub OAuth](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps)
- [Auth0 Documentation](https://auth0.com/docs)
- [Okta Developer](https://developer.okta.com/docs/)
- [AWS Cognito](https://docs.aws.amazon.com/cognito/)
## ๐ Issues & Support
For bug reports and feature requests, please use [GitHub Issues](https://github.com/tekspry/DotnetFastMCP/issues).
## โจ What's New
### v2.1.1 - Client Deserialization Patch (Latest - Sep 2026)
- ๐ **Fix `McpClient.CallToolAsync<TResult>` Deserialization** - Resolved deserialization error where calling tools returning primitive types (`int`, `bool`, `double`, etc.), `string`, or custom POCO models threw JSON conversion errors (fixes #37).
- ๐ฆ **Automatic Envelope Unwrapping** - Correctly unwraps and deserializes the inner payload from `CallToolResult.Content` while maintaining full MCP specification compliance.
- โก **Direct Envelope Overload** - Added non-generic `client.CallToolAsync("toolName", args)` returning raw `CallToolResult` directly.
- ๐งช **Comprehensive Test Coverage** - Added unit and integration test suites validating primitive, string, and complex model deserialization.
### v2.1.0 - Zero-Boilerplate MCP Servers (Sep 2026)
- โก **Automatic DI Registration** - Non-static classes containing `[McpTool]`, `[McpResource]`, or `[McpPrompt]` are automatically registered as `Transient` during `WithComponentsFrom()`. No manual `builder.Services.AddTransient<T>()` boilerplate required.
- ๐ก๏ธ **Lifespan Safety** - Implemented via `TryAddTransient` so custom `Singleton` or `Scoped` registrations configured in `builder.Services` are never overwritten.
- ๐ **`[McpDescription]` Parameter Attribute** - Tool parameters annotated with `[McpDescription]` have their documentation automatically rendered into JSON Schema `properties.<param>.description` in `tools/list`.
- ๐งผ **Clean Schema Generation** - Framework types (`McpContext`, `CancellationToken`, `ClaimsPrincipal`, `IMcpSession`) are automatically excluded from `tools/list` schema definitions, preventing LLM argument errors.
- ๐งช **57 Tests Passing** - Dual-targeted unit and integration test suite passing across both .NET 8 LTS and .NET 10 LTS.
- ๐ **Comprehensive Guide** - Detailed documentation in `docs/auto-di-registration-guide.md`.
### v2.0.0 - .NET 10 LTS & .NET 8 LTS Dual Support (Aug 2026)
- ๐ **Dual-Targeting** - Ships both `net8.0` and `net10.0` binaries in a single package.
- ๐ **Zero Breaking Changes** - 100% backward compatible for existing .NET 8 applications.
- โก **High-Performance Non-Blocking Async Streams** - SSE parser compliant with .NET 10 CA2024 rules.
- ๐งช **Comprehensive Test Matrix** - Unit & in-memory integration tests running across both target frameworks.
### v1.15.0 - Health Checks & Diagnostics (Apr 2026)
- ๐ฅ **Built-In Health Endpoint** - `GET /mcp/health` exposed with a single `builder.WithHealthChecks()` call
- ๐ **Lambda-Based Custom Checks** - Add any check (`database`, `llm`, `memory`, external API) as a simple lambda with no interface to implement
- โก **Parallel Execution** - All checks run concurrently; a slow check never delays a fast one
- โฑ๏ธ **Per-Check Timeout** - Configurable `MaxResponseTimeMs`; hanging checks reported as `Degraded`, not left blocking
- ๐ **Standard HTTP Status Codes** - 200 Healthy / 207 Degraded / 503 Unhealthy; understood natively by Kubernetes, load balancers, and APM tools
- ๐ **Auto Server Diagnostics** - Automatically includes server name, framework version, tool/resource/prompt counts, and uptime
- ๐ก๏ธ **Always Reachable** - Endpoint marked `AllowAnonymous()` so infrastructure probes bypass authentication
- ๐ฏ **Zero Overhead** - Fully opt-in; endpoint is not registered unless `WithHealthChecks()` is called
- ๐ **Comprehensive Docs** - Full guide covering Kubernetes, Docker, ACA probes, validation walkthrough, and unit tests
### v1.14.0 - OpenTelemetry Observability (Mar 2026)
- ๐ก **OpenTelemetry Integration** - First-class metrics and distributed tracing built in
- ๐ **5 Auto-Tracked Metrics** - Tool invocations, duration, errors, prompt requests, resource reads
- โจ **One-Line Setup** - `builder.WithTelemetry()` with zero boilerplate
- ๐ **Exporter Agnostic** - Works with Prometheus, App Insights, Grafana, Jaeger, any OTLP backend
- ๐ **Distributed Tracing** - Full span support with OTel semantic convention tags
- ๐ก๏ธ **PII Safe Defaults** - Tool inputs never logged unless explicitly enabled
- ๐ฏ **Zero Overhead** - Fully opt-in, no cost when not used
- ๐ **Comprehensive Docs** - Full guide with validation examples and production checklist
### v1.13.0 - LLM Integration (Feb 2026)
- ๐ค **8 LLM Providers** - Ollama, OpenAI, Azure OpenAI, Anthropic Claude, Google Gemini, Cohere, Hugging Face, Deepseek
- โจ **Latest Models** - Claude Opus 4.6 (1M context), Gemini 3 Pro/Flash, Command A, DeepSeek V3.2
- ๐ **Unified Interface** - Single `ILLMProvider` API for all providers
- ๐ก **Streaming Support** - Real-time token streaming with `IAsyncEnumerable<string>`
- ๐๏ธ **Production-Ready** - HttpClientFactory, Polly retry policies, connection pooling
- ๐ฏ **Plug-and-Play** - Simple registration: `builder.AddAnthropicProvider()`
- ๐ **Comprehensive Docs** - Complete integration guide with examples
### v1.12.0 - MFA Support
- ๐ก๏ธ **MFA Enforcement** - Require `mfa` AMR claim for sensitive tools
- โ
**Granular Control** - Enable per-tool using `[AuthorizeMcpTool(RequireMfa=true)]`
- ๐ **Enhanced Security** - Standards-based multi-factor authentication check
### v1.11.0 - Binary Content Support
- โ
**Polymorphic Content** - Support for mixed Text and Image responses
- โ
**Image Support** - Return Base64 encoded images from tools
- โ
**Multimodal Prompts** - Embbed images in prompts for LLM context
### v1.10.0 - Icons Support
- โ
**Server Icons** - Define a brand icon for your MCP server
- โ
**Tool/Resource Icons** - Visually distinguish capabilities
- โ
**UI/UX Enhancement** - Enable richer client experiences
### v1.9.0 - Background Tasks
- โ
**Fire-and-Forget** - Offload long-running operations from tools
- โ
**Non-Blocking** - Return immediate responses to clients
- โ
**Hosted Service** - Built-in queuing mechanism using Channels
### v1.8.0 - Storage Abstractions
- โ
**State Persistence** - Tools can now persist data via `McpContext.Storage`
- โ
**Pluggable Backends** - Swap in Redis/SQL/File storage easily
- โ
**In-Memory Default** - Zero-config built-in storage for development
### v1.7.0 - Server Composition
- โ
**Server Composition** - Mount other MCP servers as modules (Micro-MCPs)
- โ
**Namespacing** - Automatically prefix imported tools (e.g., `github_createIssue`)
- โ
**Zero-Overhead** - High-performance internal dictionary routing (O(1))
### v1.6.0 - Middleware Interception
- โ
**Middleware Pipeline** - Intercept and modify requests/responses
- โ
**Critical Fixes** - Resolved Stdio transport initialization deadlocks
- โ
**Builder API** - Easy registration with `AddMcpMiddleware<T>`
### v1.5.0 - Native Client Library
- โ
**McpClient** - Type-safe .NET client for consuming MCP servers
- โ
**Transport Agnostic** - Support for both Stdio and SSE connections
- โ
**Notification Handling** - Events for real-time logs and progress
### v1.4.0 - Server-Sent Events (SSE)
- โ
**SSE Transport** - Real-time server-to-client streaming transport
- โ
**Async Notifications** - Push logs and progress updates to HTTP clients
### v1.3.0 - Context & Interaction
- โ
**Context System** - `McpContext` injection for logging and progress
- โ
**IMcpSession** - Transport-agnostic interaction abstraction
### v1.2.0 - Protocol Discovery
- โ
**Dynamic Discovery** - Auto-discovery of Tools, Resources, and Prompts
- โ
**Prompts/List** - Full support for prompt templates
### v1.1.0 - Stdio Transport & Authentication
- โ
**Stdio Transport** - Initial support for stdio communication
- ๐ **6 OAuth Providers** - Azure AD, Google, GitHub, Auth0, Okta, AWS Cognito
- ๐ **OAuth Proxy** - Built-in DCR support
### v1.0.0 - Core Framework
- โ
Attribute-based API
- โ
JSON-RPC 2.0 compliance
- โ
ASP.NET Core integration
**Made with โค๏ธ by the DotnetFastMCP team**
**โญ Star this repo if you find it useful!**
TDQS
C2.6/5.0
Scored across 3 tools
Disambiguation4/5
Each tool has a distinct purpose: add_numbers does addition, greet_user does greetings, and TestContext handles context-based processing. Only TestContext has a somewhat vague name, but its description makes it distinguishable.
Naming Consistency2/5
Naming is inconsistent: add_numbers and greet_user use snake_case, while TestContext uses PascalCase and lacks a verb. The mix of conventions reduces predictability.
Tool Count2/5
With only 3 tools, the server appears under-scoped for a general-purpose MCP server. This is too few to cover common operations, making the set feel thin.
Completeness1/5
The tools are trivial and unrelated, with no clear domain or CRUD operations. There is no meaningful coverage of any real-world use case, leaving significant gaps.
Maintenance
ActivityMaintained
ResponsivenessResponsive