Getting Started
Fastest path to a working AI experience
If you want the least-effort path, use this sequence:
- Register
AddCrestAppsCore(...).AddAISuite(...) - Add one provider plus
AddChatInteractions() - Configure
CrestApps:AI:ConnectionsandCrestApps:AI:Deployments - Create an AI profile and chat against it through Chat Interactions
Chat Interactions are the easiest playground-style UI for validating that your connection, deployment, prompts, and profile wiring are all correct before you build a custom experience.
Prerequisites
- .NET 10 SDK
- Node.js 20+ for the documentation site
- At least one AI provider credential or a local Ollama instance when you want to run the sample app with live AI features
Clone the repository
git clone https://github.com/CrestApps/CrestApps.Core.git
cd CrestApps.Core
Build and test
dotnet build .\CrestApps.Core.slnx -c Release /p:NuGetAudit=false
dotnet test .\tests\CrestApps.Core.Tests\CrestApps.Core.Tests.csproj -c Release /p:NuGetAudit=false
Run the sample hosts
MVC sample application
Visual Studio: Set CrestApps.Core.Mvc.Web as the startup project and press F5 (or Ctrl+F5 to run without debugging).
Command line:
dotnet run --project .\src\Startup\CrestApps.Core.Mvc.Web\CrestApps.Core.Mvc.Web.csproj
The sample host resolves its content root to the MVC project directory automatically, so this command works correctly when run from the repository root.
Use the MVC sample when you want to see the full framework in one place: AI providers, deployments, profiles, templates, document processing, MCP, A2A, storage, and SignalR-driven chat flows.
Aspire host
The Aspire host boots the MVC and Blazor sample hosts together with the shared A2A and MCP client samples as a composed local environment. The client samples include a server selector so you can switch between the MVC and Blazor endpoints without launching separate client projects.
:::info Prerequisites Aspire manages containers for services like Redis. You need a container runtime such as Docker Desktop installed and running before starting the Aspire host. :::
Visual Studio: Set CrestApps.Core.Aspire.AppHost as the startup project and press F5.
Command line:
dotnet run --project .\src\Startup\CrestApps.Core.Aspire.AppHost\CrestApps.Core.Aspire.AppHost.csproj
The MVC and Blazor sample hosts both keep their writable runtime state inside each project's own App_Data folder. Their project files exclude **/App_Data/** from .NET 10 watch discovery so Visual Studio Aspire runs do not restart the hosted app when uploads, logs, or local SQLite files change at runtime.
Smallest useful app integration
Use the AddCrestAppsCore(...) builder as the main entry point:
builder.Services.AddCrestAppsCore(crestApps => crestApps
.AddAISuite(ai => ai
.AddOpenAI()
)
);
Then add the first interactive feature:
builder.Services.AddCrestAppsCore(crestApps => crestApps
.AddAISuite(ai => ai
.AddOpenAI()
.AddChatInteractions()
)
);
By default:
- connections are read from
CrestApps:AI:Connections - deployments are read from
CrestApps:AI:Deployments
{
"CrestApps": {
"AI": {
"Connections": [
{
"Name": "primary-openai",
"ClientName": "OpenAI",
"ApiKey": "YOUR_API_KEY"
}
],
"Deployments": [
{
"Name": "gpt-4.1",
"ConnectionName": "primary-openai",
"ModelName": "gpt-4.1",
"Type": "Chat"
},
{
"Name": "standalone-utility",
"ClientName": "OpenAI",
"ModelName": "gpt-4.1-mini",
"Type": "Utility",
"ApiKey": "YOUR_OTHER_API_KEY"
}
]
}
}
}
Use ConnectionName when a deployment should point at a shared entry from CrestApps:AI:Connections. Keep contained connection settings directly on the deployment only when you want a standalone deployment definition.
Create an AI profile that uses your chat deployment, then use Chat Interactions to test it end to end.
Run locally with Ollama (no API key)
Ollama is the fastest way to try CrestApps.Core without a cloud provider or API key. The one requirement that trips people up: Ollama only serves models that have already been pulled onto the machine. If the deployment's ModelName does not match a locally pulled model, the provider returns 404 (Not Found) and the chat fails.
Option A — Let the Aspire host do it for you (recommended)
The included Aspire host starts an Ollama container, pulls a model automatically, and pre-wires the connection and deployment for both sample hosts, so there is nothing to configure by hand:
dotnet run --project .\src\Startup\CrestApps.Core.Aspire.AppHost\CrestApps.Core.Aspire.AppHost.csproj
This requires a running container runtime such as Docker Desktop.
:::info First run downloads a model
On the first run, the Aspire host pulls the default deepseek-v2:16b model. Depending on your internet speed this can take a while, and the model takes several gigabytes of disk space. The download only happens once — the model is cached in a persistent volume for later runs. To use a smaller or different model, change the model name in the Aspire host's Program.cs.
:::
Option B — Point at your own Ollama instance
The sample hosts already register the Ollama provider, so running them against your own Ollama only requires pulling the model and pointing a connection at it.
-
Pull the model you want to use, then confirm it is available:
ollama pull llama3.2curl http://localhost:11434/api/tags -
Create an Ollama connection and a chat deployment. In the sample hosts you can add both from the admin UI on the AI Connections and AI Deployments screens, the same way you would for any provider. Whichever route you use, the deployment's Model name must exactly match the pulled model name (including any tag, e.g.
llama3.2:latest).You can also provide them through configuration instead of the UI:
{"CrestApps": {"AI": {"Connections": [{"Name": "ollama-local","ClientName": "Ollama","Endpoint": "http://localhost:11434"}],"Deployments": [{"Name": "llama3.2","ConnectionName": "ollama-local","ModelName": "llama3.2","Type": "Chat"}]}}}
Ollama does not require an API key — the connection only needs an Endpoint. See the Ollama provider guide for model management, Docker setup, and capability details.
If you are wiring CrestApps.Core into your own project rather than running the sample hosts, register the provider the same way as the OpenAI example above, swapping .AddOpenAI() for .AddOllama():
builder.Services.AddCrestAppsCore(crestApps => crestApps
.AddAISuite(ai => ai
.AddOllama()
.AddChatInteractions()));
:::warning Getting a 404 (Not Found) from Ollama?
This almost always means the requested model has not been pulled. Run ollama pull <model> and confirm the name appears in curl http://localhost:11434/api/tags — it must match the deployment's Model name exactly.
:::
Complete Hello World example
Here is a minimal, self-contained Program.cs that sends a chat completion request using CrestApps.Core with OpenAI:
using CrestApps.Core;
using CrestApps.Core.AI;
using CrestApps.Core.AI.Models;
using CrestApps.Core.AI.Completions;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
// Register CrestApps with the OpenAI provider.
builder.Services.AddCrestAppsCore(crestApps => crestApps
.AddAISuite(ai => ai
.AddOpenAI()
)
);
var app = builder.Build();
// Resolve the completion service from DI.
using var scope = app.Services.CreateScope();
var deploymentManager = scope.ServiceProvider.GetRequiredService<IAIDeploymentManager>();
var completionService = scope.ServiceProvider.GetRequiredService<IAICompletionService>();
// Resolve the deployment that fills the chat slot.
var deployment = await deploymentManager.ResolveSlotAsync(AIDeploymentSlotNames.Chat);
if (deployment is null)
{
Console.WriteLine("No chat deployment found. Check your CrestApps:AI:Deployments configuration.");
return;
}
// Send a completion request.
var messages = new List<ChatMessage>
{
new(ChatRole.User, "What is CrestApps.Core in one sentence?"),
};
var context = new AICompletionContext();
var response = await completionService.CompleteAsync(deployment, messages, context);
Console.WriteLine(response.Message?.Text ?? "No response.");
Add the matching appsettings.json:
{
"CrestApps": {
"AI": {
"Connections": [
{
"Name": "my-openai",
"ClientName": "OpenAI",
"ApiKey": "sk-YOUR_API_KEY_HERE"
}
],
"Deployments": [
{
"Name": "gpt-4.1-mini",
"ConnectionName": "my-openai",
"ModelName": "gpt-4.1-mini",
"Type": "Chat"
}
]
}
}
}
Learn the registration model
Under the hood, each builder step still maps to the corresponding AddCrestApps... IServiceCollection extension, so hosts can still opt into the lower-level registration methods when they want that control.
- Start with Core overview to understand the package layout
- Use ASP.NET Core integration to wire the same services into MVC, Razor Pages, Blazor, Minimal APIs, or MAUI hybrid hosts
- Follow MVC example for a complete working composition
Build the docs site
cd src\CrestApps.Core.Docs
npm install
npm run build
Package feed
Preview packages are published to:
https://nuget.cloudsmith.io/crestapps/crestapps-core/v3/index.json