MinervaApiDocs 2.0.2

dotnet add package MinervaApiDocs --version 2.0.2
                    
NuGet\Install-Package MinervaApiDocs -Version 2.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MinervaApiDocs" Version="2.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MinervaApiDocs" Version="2.0.2" />
                    
Directory.Packages.props
<PackageReference Include="MinervaApiDocs" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MinervaApiDocs --version 2.0.2
                    
#r "nuget: MinervaApiDocs, 2.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MinervaApiDocs@2.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MinervaApiDocs&version=2.0.2
                    
Install as a Cake Addin
#tool nuget:?package=MinervaApiDocs&version=2.0.2
                    
Install as a Cake Tool

Minerva

Interactive OpenAPI documentation for ASP.NET Core — like Swagger/Scalar, but with declarative, executable multi-step flows and a built-in React UI served directly from your application. The UI is embedded in the assembly, so you only reference one package.

Install

dotnet add package MinervaApiDocs

Usage

// Program.cs
builder.Services.AddOpenApi();   // built-in .NET OpenAPI
builder.Services.AddMinerva();   // register Minerva

var app = builder.Build();
app.MapOpenApi();                // expose /openapi/v1.json
app.UseMinervaDocs();            // serve the docs UI + API at /openapi/docs

app.MapControllers();
app.Run();

Annotate the actions you want documented:

[Minerva(Category = "Authentication", Order = 1, Description = "Login and get a token.")]
[HttpPost("login")]
public IActionResult Login([FromBody] LoginRequest req) => ...;

Configuration

Content — the title, categories, pages and flows — lives in a Minerva folder at your app's content root. Flows chain requests and map response values into variables (e.g. capture a JWT from POST /auth/login and reuse it as a Bearer token on later requests).

YourApp/
  Minerva/
    minerva.yaml               # title, categories, settings
    Pages/
      home.md                  # one markdown file per page
      getting-started.md
    Flows/
      Authentication.yaml      # one file per category
      Products.yaml

One file per category and one file per page is the whole point: two people working on different features stop conflicting in the same file, and a page's markdown gets line-by-line diffs instead of being wrapped in a YAML scalar.

Minerva/minerva.yaml — global settings only:

title: Contoso API
categories:
  - name: Authentication
    order: 1
  - name: Products
    order: 2
settings:
  theme: dark

Minerva/Flows/Authentication.yaml — the category is declared once for the file:

category: Authentication      # optional; defaults to the file name
order: 1                      # optional; used when minerva.yaml does not declare it
flows:
  - id: login
    name: Login and get user info
    order: 1
    steps:
      - type: request
        method: POST
        path: /auth/login
        body:
          type: json
          content:
            username: '{{username}}'
            password: '{{password}}'
      - type: map
        from: response.access_token
        to: jwt
      - type: request
        method: GET
        path: /auth/users/me
        headers:
          Authorization: Bearer {{jwt}}

A flow's parameters are derived from its steps (and its dependencies' steps), so they are never written to the file — a dependency in another file could change them.

Minerva/Pages/home.md — markdown with YAML front matter:

---
id: home
title: Home
order: 1
icon: home
---

# Welcome

Ordinary markdown: lists, tables and `---` rules all survive a round trip through
the page editor.

The files are embedded in your assembly

On every build, Minerva's MSBuild target embeds Minerva/**/*.{yaml,yml,md,markdown} into your assembly as resources named Minerva.Config/<relative/path>, and removes them from the build and publish output. So a published application:

  • serves its documentation from the embedded copy — no files to deploy, nothing to forget in a Docker image;
  • cannot have its documentation edited in place. The write endpoints are refused (403 outside Development, 409 with code: "config_read_only" if you run Development against an embedded source), and the UI hides the create/edit buttons.

In Development the folder on disk wins instead, so the built-in editors read and write real files and edits hot-reload without a restart.

Opt out or adjust with MSBuild properties:

Property Default Effect
MinervaEmbedConfig true Set false to embed nothing.
MinervaConfigDirectory Minerva Folder to embed. Set MinervaOptions.ConfigDirectory to match.
MinervaConfigExtensions yaml;yml;md;markdown Extensions to include, ;-separated.
MinervaKeepConfigInOutput false Set true to embed and keep copies in the build output.
MinervaConfigExclude (empty) An item list, not a property: files to leave out.

The resource-name prefix is fixed at Minerva.Config/ and read back by the runtime, so renaming the folder does not change resource names. Don't override MinervaConfigResourcePrefix unless you also construct MinervaEmbeddedFileProvider with the matching prefix yourself.

.json is deliberately not in the default extension list: in a web project **/*.json is Content that gets copied to the output, which would defeat the purpose.

When the configuration lives in a class library rather than the startup project, point Minerva at it:

builder.Services.AddMinerva(o => o.UseConfigFromAssemblyOf<SomeTypeInThatLibrary>());

Options

Option Default Purpose
RoutePrefix /openapi/docs Where the docs UI is served.
ConfigDirectory Minerva Configuration folder, relative to the content root (an absolute path also works).
ConfigSourceMode Auto Auto (disk first in Development, embedded first elsewhere), PreferDisk, EmbeddedOnly, DiskOnly.
ConfigAssembly (auto) Assembly holding the embedded configuration.
OpenApiSpecPath /openapi/v1.json Where Minerva reads your OpenAPI document.
MaxUploadBytes 32 MB Cap on files uploaded for a flow run.
ConfigFilePath minerva.yaml Legacy single-file fallback (see below).
ProxyAllowedHosts (empty) Extra hosts the "Try it" proxy may reach, beyond your own.
AcceptAnyServerCertificate (Development) Accept any TLS certificate on outbound flow/proxy requests.
EnableDraftExecution (Development) Allow POST /_minerva/flows/execute-draft.

What a published application will not do

Three things are restricted outside Development, because a documentation page should not be more powerful than the documentation:

  • The "Try it" proxy only reaches your own application. It exists so the UI can call the API it documents without CORS, and that is all the UI ever asks of it. Unrestricted it is a server-side request forgery primitive: the request is issued by your server, so it reaches hosts the caller cannot — cloud metadata endpoints, services on your internal network — and the response body comes straight back. Add hosts to ProxyAllowedHosts if you genuinely need them ("*" disables the check).
  • Executing an unsaved flow is off. execute-draft runs a flow definition supplied in the request — method, path, headers and body — against your base URL. Only the flow editor uses it, and the editor is Development-only.
  • TLS certificates are validated. Accepting any certificate is a convenience for self-signed localhost certs; it used to apply everywhere. (Minerva's fetch of your own OpenAPI document stays permissive: it is a self-connection, with no third party to authenticate.)

Upgrading from a single minerva.yaml

A single minerva.yaml at the content root is still read, in every environment, so upgrading the package changes nothing on its own.

The simplest migration is one command — it works immediately, with no content edits:

git mv minerva.yaml Minerva/minerva.yaml

The root file is still a complete configuration document, so flows and pages may stay inline in it; splitting them into Flows/ and Pages/ is optional and incremental.

To split it all at once, run the app in Development and use the Split into files button the docs UI offers (or POST /_minerva/config/migrate directly). It writes the folder and renames the original to minerva.yaml.migrated — your file is never deleted.

See the project repository for full documentation.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.2 115 9/8/2026
2.0.1 111 9/8/2026
2.0.0 101 9/8/2026
1.9.0 134 7/29/2026
1.8.0 114 7/29/2026
1.7.0 115 7/29/2026
1.6.0 122 7/29/2026
1.5.0 118 7/29/2026
1.4.0 125 7/24/2026
1.3.0 130 7/22/2026
1.2.4 151 6/23/2026
1.2.3 129 6/23/2026
1.2.2 135 6/22/2026
1.2.1 137 6/22/2026
1.2.0 140 6/22/2026
1.1.4 132 6/19/2026
1.1.3 131 6/19/2026
1.1.2 130 6/19/2026
1.1.1 127 6/19/2026
1.1.0 129 6/19/2026
Loading failed