Skip to main content
Glama
README.md
# DotnetFastMCP โ€” Enterprise Security & Governance Gateway for MCP Servers

[![CI](https://github.com/tekspry/DotnetFastMCP/actions/workflows/ci.yml/badge.svg)](https://github.com/tekspry/DotnetFastMCP/actions/workflows/ci.yml)
[![.NET 8.0](https://img.shields.io/badge/.NET-8.0%20LTS-blue)](https://dotnet.microsoft.com)
[![.NET 10.0](https://img.shields.io/badge/.NET-10.0%20LTS-purple)](https://dotnet.microsoft.com)
[![NuGet](https://img.shields.io/badge/NuGet-v2.1.1-orange)](https://www.nuget.org/packages/DotnetFastMCP)
[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
[![GitHub](https://img.shields.io/badge/GitHub-tekspry-black)](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
[![GitHub](https://img.shields.io/badge/GitHub-tekspry%2Ffashion--pipeline-black)](https://github.com/tekspry/fashion-pipeline)
[![.NET 10.0](https://img.shields.io/badge/.NET-10.0%20LTS-blue)](https://dotnet.microsoft.com)
[![Google A2A](https://img.shields.io/badge/Protocol-Google%20A2A-green)](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