Scalar API documentation setup for .NET. OpenAPI doc generation, Scalar UI configuration, basic auth protection, theme customization.
From dotnet-ai-kitnpx claudepluginhub faysilalshareef/dotnet-ai-kit --plugin dotnet-ai-kitThis skill uses the workspace's default tool permissions.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
namespace {Company}.{Domain}.Api.Extensions;
public static class OpenApiExtensions
{
public static IServiceCollection AddOpenApiDocumentation(
this IServiceCollection services, IWebHostEnvironment environment)
{
services.AddOpenApi("v1", options =>
{
options.AddDocumentTransformer<BearerSecuritySchemeTransformer>();
});
return services;
}
public static IApplicationBuilder UseOpenApiDocumentation(
this IApplicationBuilder app, IWebHostEnvironment environment)
{
app.MapOpenApi();
app.MapScalarApiReference(options =>
{
options
.WithTitle("{Company} {Domain} API")
.WithTheme(ScalarTheme.BluePlanet)
.WithDefaultHttpClient(ScalarTarget.CSharp, ScalarClient.HttpClient);
});
return app;
}
}
internal sealed class BearerSecuritySchemeTransformer(
IAuthenticationSchemeProvider provider)
: IOpenApiDocumentTransformer
{
public async Task TransformAsync(
OpenApiDocument document,
OpenApiDocumentTransformerContext context,
CancellationToken ct)
{
var schemes = await provider.GetAllSchemesAsync();
if (schemes.Any(s => s.Name == "Bearer"))
{
var requirements = new Dictionary<string, OpenApiSecurityScheme>
{
["Bearer"] = new()
{
Type = SecuritySchemeType.Http,
Scheme = "bearer",
BearerFormat = "JWT"
}
};
document.Components ??= new();
document.Components.SecuritySchemes = requirements;
}
}
}
namespace {Company}.Gateways.Common.Scalar;
public sealed class ScalarBasicAuthMiddleware(
RequestDelegate next,
IOptions<ScalarAuthorizationOptions> options)
{
public async Task InvokeAsync(HttpContext context)
{
if (IsLocalRequest(context))
{
await next(context);
return;
}
var authHeader = context.Request.Headers.Authorization.ToString();
if (!ValidateBasicAuth(authHeader, options.Value))
{
context.Response.StatusCode = 401;
context.Response.Headers.WWWAuthenticate = "Basic realm=\"API Docs\"";
return;
}
await next(context);
}
private static bool IsLocalRequest(HttpContext context) =>
IPAddress.IsLoopback(context.Connection.RemoteIpAddress!);
}
builder.Services.AddOpenApiDocumentation(builder.Environment);
var app = builder.Build();
app.UseOpenApiDocumentation(app.Environment);
| Anti-Pattern | Correct Approach |
|---|---|
| Swagger UI for new projects | Use Scalar with MapScalarApiReference |
| Exposing docs without auth | Use ScalarBasicAuthMiddleware |
| Missing Bearer scheme | Add BearerSecuritySchemeTransformer |
grep -r "MapScalarApiReference\|AddOpenApi\|MapOpenApi" --include="*.cs"
grep -r "SwaggerUI\|UseSwagger" --include="*.cs" # Legacy check
AddOpenApi() in services and MapScalarApiReference() in pipelineBearerSecuritySchemeTransformer if JWT auth is used