ServiceStack.AI.Chat

A complete AI Assistant inside your .NET App

One plugin gives your users a multi-provider Chat UI, RAG over your documents, a PDF designer and safe AI access to your own APIs — using the accounts, database and security boundary your App already has.

AI Chat running at /chat

Governed by your App

It's already your users

ChatFeature authenticates against the App it's hosted in. Signing in, roles, locking an account, revoking a key — all of it keeps working exactly as it does everywhere else in your App.

Your users
alex Admin
sam Staff
contractor no role
Your existing auth
RequireAuth true
RequiredRole "Staff"
2 allowed · 1 rejected
Approved models
anthropic openai google ollama +20 more
centralized provider keys & billing

No second user directory. No SSO integration project. The people who can already sign into your App are the people who can use it — and the ones who can't, can't.

Restrict who gets in

Set RequiredRole and only users holding that role reach the UI or any of its APIs. Everyone else is rejected at the door.

Keys for programmatic clients

With ApiKeysFeature registered, /v1/chat/completions also accepts a Bearer key — so scripts and MCP clients work alongside browser sign-in.

Multi-user from the start

Everyone gets their own workspace. Chat history, uploads and gallery, agent profiles, projects, skills, themes and PDF templates are all partitioned per user.

Signing in to the Chat UI with an existing account
Managing users from the Admin UI
Configure.AI.Chat.cs
services.AddPlugin(new ChatFeature {
    RequireAuth  = true,
    RequiredRole = "Staff",       // only Staff can use it
    RoutePrefix  = "/chat",
    EnableProviders = ["openai", "anthropic", "google"],
});

One interface, every provider

Never bet the organization on one model vendor

OpenAI, Anthropic, Google, Groq, xAI, Mistral, OpenRouter, Fireworks, Cerebras, a local Ollama or LM Studio endpoint — all behind one model selector, with search, capability filters, context sizes, pricing and favorites.

AI Chat model selector
Filtering models by provider

Route work to the right model

Fast and cheap for triage, frontier reasoning for hard problems, a local model for anything that mustn't leave the network.

Consistent streaming

History, attachments, system prompts, tool calls and usage records stay in the same UI when users switch providers mid-conversation.

Fully self-hosted, if you want

Point AI Chat at Ollama or LM Studio and nothing leaves your network. Which providers see your prompts is entirely your decision.

Your APIs become AI capabilities

No parallel AI backend

Models progressively discover and call the ServiceStack APIs you already have — as the signed-in user, through the same validation, authorization and business logic as every other client.

Three tools, not one per API

An App's whole API surface is far too large to keep in context. Only a compact search index is loaded eagerly, and a Model pays for an API's schema only when it actually uses it.

  • api_search Finds APIs relevant to the user's intent
  • api_describe Returns full schemas and workflow metadata
  • api_call Invokes the typed Request DTO as the current user
Opt an API in
[Tag("CoffeeShop")]
[Tool("the user wants to place an order",
    Safety = ToolSafety.Write,
    RequiresApproval = true)]
public class CreateCoffeeShopOrder : IPost { }

Consequential calls need a human

Reads execute immediately. Writes and destructive operations pause and render an editable form generated from the API's own schema — so the user sees exactly what will be sent, and can fix it before approving. No per-API Chat component to write.

Schema-generated approval form

Inside the Chat UI

Enable API Tools and name the tags you want Models to reach. Your users get a natural-language operations console over the APIs they're already authorized to call.

API Tools reference →

From any MCP client

The built-in MCP Server at /chat/mcp exposes the same tools to Claude Code, Cursor, VS Code and OpenCode — authenticated with a ServiceStack API key, so tools run as that key's user.

MCP Server reference →
An external AI Assistant using ServiceStack API Tools over MCP

Grounded answers

RAG over your documents, without building a pipeline

Drag a folder of PDFs into a File Store and ask questions about it. No chunking pipeline, no vector database to operate, no indexer to write.

Gemini File Search stores
Asking a question scoped to a document category

Drop in a folder

PDFs, Markdown, text and business documents, deduplicated by SHA-256 and indexed by a background worker so the UI never blocks.

Narrow the question

Ask the whole store, one category, or a single document — whichever scope actually contains the answer.

Kept honest

Grounding sources are retained with responses, so a user can verify where an answer came from instead of trusting fluent output.

Same front door

Stores are scoped per user behind the same auth as everything else, with a sync report when the local catalog and remote drift.

Design with AI, render without it

PDF Studio

Describe the document you want — or hand a vision model a screenshot of the one you're replacing — and iterate on a live preview. Then publish it and render production PDFs with no LLM in the path.

PDF Studio designer

Rendered by typst

Plain-text templates that compile fast and express precise typography, tables and page structure.

Data-driven, not baked in

A JSON Schema contract sits beside every template, with named fixtures that must render before it can be published.

Typed end to end

Generate strongly typed C# models from the schema, so document design and application code share a compile-time contract.

A versioned design system

Shared fonts, colors and components live in lib/v1.typ, so a redesign can't reflow every historical document.

Edit with AI

Describe the change in English. The model gets the current template, its data and any referenced partials, and Studio compiles what it returns immediately — with a repair pass if it doesn't compile the first time.

Add a Paid watermark when the outstanding balance is zero.

Move the totals into a bordered box and show tax on a separate row.

Reformat this as a 4×6 shipping label with no page margins.

AI edits update editor buffers rather than committing files, so experimentation stays reversible.

A template after an AI edit
Published templates in the Admin UI

From template to inbox

Publishing validates the template and every fixture, generates the typed model, compiles it all and saves an immutable revision — rolling back if anything fails. Production rendering then needs nothing but typst and the published files.

InvoiceServices.cs
public class InvoiceServices(IPdfRenderer pdf) : Service
{
    public async Task<object> Any(GetOrderInvoice request)
    {
        var order = await Db.LoadSingleByIdAsync<Order>(request.Id);
        return await pdf.PdfResultAsync(MapToInvoice(order),
            $"Invoice-{order.InvoiceNo}.pdf");
    }
}

Specialization

Profiles, skills and safe working boundaries

One system prompt can't be right for every task. Package a model, prompt, theme, allowed tools and allowed skills into a named assistant — then give it a workspace it can't escape.

Agent Profiles

Agent Profiles

Support Assistant, Policy Analyst, Release Planner — governed job descriptions, each with only the context and capabilities its role needs.

Reference →
Skills

Skills

Procedures a Model loads only when relevant — incident response, onboarding, code review — keeping prompts small and specialists specialized.

Reference →
Projects

Projects

A per-user workspace that defines exactly which directories filesystem and code tools may touch. Capable Agents, without ambient server access.

Reference →

Operated, not just installed

Know what it costs before the invoice does

Every completion records provider, model, tokens, duration and cost into your own database — queryable with OrmLite, reportable from the Admin UI, and enforceable as a quota.

AI usage and cost analytics
Per-user activity analytics

And the rest of it

Everything below ships as a separately installable extension you can disable from one line of config.

Text, image & audio

Image and audio generation, speech synthesis and voice-to-text, with everything generated recorded in a browsable media gallery. Reference

Modular by design

19 built-in extensions, each owning its own routes, tools, tables and UI components — and replaceable by your own. Reference

Your own tools

Register a ServiceStack Command as a tool and its request type becomes the JSON Schema the Model reads. Reference

Code execution, opt-in

Filesystem and run_bash tools stay off until you turn them on, and only reach configured directories. Reference

OpenAI-compatible API

POST /v1/chat/completions plus an in-process IChatClient running the same pipeline. Reference

Your database

Threads, requests and media are ordinary OrmLite tables in your App's database. Nothing is held by a vendor. Reference

Add it to an App you already have

One command adds the package, registers ChatFeature and PdfFeature, and writes a starting configuration you can edit.

Set an API key for at least one provider, run your App and open /chat. Your existing users can sign in immediately.