with one click
scalar
Use when configuring Scalar API documentation UI for a .NET project.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Use when configuring Scalar API documentation UI for a .NET project.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Use when designing gRPC services, proto files, or adding gRPC-Web or JSON transcoding.
Use when writing async code, propagating CancellationTokens, or fixing async/await pitfalls.
Use when applying or enforcing C# coding style — namespaces, sealed classes, var usage, XML docs.
Use when applying modern C# idioms — records, pattern matching, primary constructors, collection expressions.
Use when registering services, choosing lifetimes, or implementing DI patterns like decorator or keyed services.
Use when selecting or implementing design patterns in C# — factory, builder, strategy, decorator, or mediator.
| name | scalar |
| description | Use when configuring Scalar API documentation UI for a .NET project. |
| metadata | {"category":"api","agent":"api-designer"} |
| when_to_use | When setting up Scalar API documentation with authentication and theming |
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