using System.Net; using Microsoft.Extensions.Primitives; namespace Alchegos.MCP.Filters; public class McpAuthFilter : IEndpointFilter { private readonly ILogger _logger; public McpAuthFilter(ILogger logger) { _logger = logger; } public async ValueTask InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) { var expectedToken = Environment.GetEnvironmentVariable("MCP_API_KEY"); if (string.IsNullOrEmpty(expectedToken)) { _logger.LogCritical("Required environment variable 'MCP_API_KEY' is not set."); return Results.StatusCode((int)HttpStatusCode.InternalServerError); } var httpContext = context.HttpContext; if (!httpContext.Request.Headers.TryGetValue("X-Api-Key", out StringValues receivedTokenValues) || receivedTokenValues.Count == 0) { _logger.LogWarning("MCP request rejected: Missing 'X-Api-Key' header."); return Results.Unauthorized(); } var receivedToken = receivedTokenValues.ToString(); if (!SecureCompare(receivedToken, expectedToken)) { _logger.LogWarning("MCP request rejected: Invalid API Key provided."); return Results.Unauthorized(); } _logger.LogInformation("MCP request authenticated successfully."); return await next(context); } private static bool SecureCompare(string a, string b) { a ??= string.Empty; b ??= string.Empty; if (a.Length != b.Length) return false; int diff = 0; for (int i = 0; i < a.Length; i++) diff |= a[i] ^ b[i]; return diff == 0; } }