Packages
Cairn ships as a small set of focused NuGet packages. Most applications install Cairn.AspNetCore (which brings in Cairn.Core and the build-time analyzers); the remaining packages are optional and serve specific roles — consuming an API, testing, or describing it.
Package reference
| Package | Purpose | Install when |
|---|---|---|
Cairn.Core |
Transport-agnostic hypermedia model and engine: links, link relations, and affordances. No ASP.NET dependency. | Usually transitive. Reference it directly only when defining link configurations in a project with no ASP.NET reference. |
Cairn.AspNetCore |
ASP.NET Core integration for both minimal APIs (.WithLinks()) and MVC controllers ([CairnLinks]). Bundles the analyzer, code fixes, and source generator. |
The main install for any API that emits hypermedia. |
Cairn.Client |
A typed client for consuming Cairn hypermedia APIs: read a resource's value, links, and affordances; navigate by relation; invoke affordances. | In a consumer (service, worker, or test) that calls a Cairn API. |
Cairn.Testing |
Test assertion helpers for links, affordances, templates, and snapshots — no third-party assertion library required. | In a test project asserting on hypermedia output. |
Cairn.OpenApi |
Surfaces hypermedia links and affordances in the OpenAPI document via Microsoft.AspNetCore.OpenApi (.NET 10 only). |
When you generate OpenAPI with Microsoft.AspNetCore.OpenApi. |
Cairn.Swashbuckle |
Surfaces hypermedia links and affordances in the Swagger/OpenAPI document via schema and operation filters. Requires Swashbuckle.AspNetCore 10.0 or later. | When you generate OpenAPI with Swashbuckle (the choice on .NET 8/9). |
Cairn.AspNetCore.Explorer |
A browsable HAL Explorer — middleware (UseCairnExplorer()) that serves an embedded, dependency-free UI for navigating the API's links, embedded resources, and HAL-FORMS actions. Development-only by default. |
When you want an interactive console for exploring a Cairn API. |
Cairn.Mcp |
A Model Context Protocol server surface: exposes the state- and authorization-gated affordances your link configurations declare as MCP tools, via the official MCP C# SDK. | When AI agents should discover and invoke your API's actions under the same gates as any hypermedia client. |
Cairn.Templates |
A dotnet new template pack. dotnet new cairn-api scaffolds a minimal API already wired for hypermedia. |
When starting a new Cairn API. Installed with dotnet new install, not dotnet add package. |
Cairn.Core
The hypermedia model and resolution engine: Link, LinkRelation, IanaLinkRelations, Affordance, LinkTarget, LinkSet, EmbeddedResource, LinkContext, and the configuration surface — LinkConfig<T>, ILinkBuilder<T>, ILinkSpec<T>, IAffordanceSpec<T>, and LinkConfigRegistry. It has no ASP.NET dependency, so link configurations can live in a domain or contracts assembly.
Cairn.AspNetCore, Cairn.Client, Cairn.OpenApi, and Cairn.Swashbuckle all reference Cairn.Core, so it normally arrives transitively. (Cairn.Testing is deliberately dependency-free — it parses hypermedia responses on its own rather than referencing the model.) See Link configurations for the builder API.
Cairn.AspNetCore
The main server package. It wires Cairn into ASP.NET Core through AddCairn(Action<CairnOptions>) and exposes both endpoint surfaces:
- Minimal APIs —
.WithLinks(),.WithPageLinks,.WithCursorLinks,.WithHypermediaFormat. - MVC controllers — the
[CairnLinks]attribute.
It also bundles the route-safety tooling — the analyzers (CAIRN001 for unknown route names, CAIRN002 for WithLinks endpoints whose return type has no LinkConfig), the code fixes, and the source generator that produces the Routes.* catalog (reporting CAIRN003 on colliding names). These ship inside this package as Roslyn components; there is no separate analyzer package to install. Adding Cairn.AspNetCore enables them automatically.
dotnet add package Cairn.AspNetCore
builder.Services.AddCairn(o => o.AddLinks(new OrderLinks()));
See Getting started, Controllers / MVC, and Analyzers & generated routes.
Cairn.Client
A typed consumer client. CairnClient reads a resource's value, ETag, links, and affordances, navigates by relation with FollowAsync, and invokes affordances with InvokeAsync; Resource<T> and ClientResult<T> model the responses. Register it with AddCairnClient(Action<CairnClientOptions>), which returns an IHttpClientBuilder.
dotnet add package Cairn.Client
See The typed client.
Cairn.Testing
Test assertion helpers with no third-party assertion dependency — failures throw CairnAssertionException, which any test framework reports cleanly. HypermediaResponse plus .Should() exposes fluent checks such as HaveSelfLink, HaveLink, HaveLinkMatching, and HaveAffordance, and HypermediaSnapshot renders stable output for snapshot testing.
dotnet add package Cairn.Testing
See Testing.
Cairn.OpenApi and Cairn.Swashbuckle
Two interchangeable packages that describe hypermedia in your API document — pick the one that matches your OpenAPI generator:
Cairn.OpenApi—AddCairnHypermedia()onOpenApiOptions(Microsoft.AspNetCore.OpenApi); registers a schema transformer and an operation transformer.Cairn.Swashbuckle—AddCairnHypermedia()onSwaggerGenOptions(Swashbuckle); registers a schema filter and an operation filter. Requires Swashbuckle.AspNetCore 10.0 or later: the filters build on the interface-based OpenAPI.NET 2.x object model (IOpenApiSchema) that Swashbuckle adopted in 10.x, so earlier Swashbuckle versions fail to load them.
dotnet add package Cairn.OpenApi
# or
dotnet add package Cairn.Swashbuckle
See OpenAPI & Swagger.
Cairn.AspNetCore.Explorer
A browsable HAL Explorer for the API. UseCairnExplorer() mounts an in-browser console (default /explorer) that navigates the live API by following links and running HAL-FORMS actions as forms. The UI is a single embedded HTML document with no external dependency, and it is served in the Development environment only unless you opt in.
dotnet add package Cairn.AspNetCore.Explorer
app.UseCairnExplorer();
Cairn.Mcp
A Model Context Protocol server surface for the API, built on the official MCP C# SDK (ModelContextProtocol.AspNetCore). WithCairnAffordances(...) on AddMcpServer() turns each affordance a link configuration declares into an MCP tool (order_cancel), plus a {resource}_get state-inspection tool per resource. tools/list is filtered per caller by the affordances' authorization policies, and a call re-runs the same state and authorization gates a hypermedia response applies before invoking the affordance's own endpoint over HTTP.
dotnet add package Cairn.Mcp
builder.Services.AddMcpServer()
.WithHttpTransport(o => o.Stateless = true)
.WithCairnAffordances(mcp => mcp.AddResource<OrderDto>("order", LoadOrderAsync));
app.MapMcp("/mcp");
Cairn.Templates
A dotnet new template pack. Unlike the other packages you install it into the template engine, not into a project:
dotnet new install Cairn.Templates
dotnet new cairn-api -o Orders.Api
cairn-api scaffolds a minimal API already wired for hypermedia — link configs registered, endpoints named and opted in, a state-conditional affordance, and an optional HAL Explorer. The pack ships at the same version as the libraries, and a generated project references that matching version. See Project template.
Targeting
The shippable packages multi-target net8.0, net9.0, and net10.0 — with one exception: Cairn.OpenApi targets net10.0 only, because it plugs into the Microsoft.AspNetCore.OpenApi schema-transformer pipeline, which exists in the shape Cairn builds on only in .NET 10 (the API is absent on .NET 8 and uses an incompatible object model on .NET 9). On .NET 8/9, use Cairn.Swashbuckle to surface hypermedia in your OpenAPI document instead.
Building from source requires the .NET 10 SDK; the shipped packages run on .NET 8 (LTS) and later. The Roslyn components bundled in Cairn.AspNetCore target netstandard2.0, as Roslyn requires.