Hosted
The hosted backend replaces your chat database and attachment bucket with
@mordn/chat-api. The API key authenticates a tenant and agent; the handler's
verified userId scopes each end-user request.
createMordnHandler
One key wires published config, persistence, storage, and feedback. This is the recommended setup.
import { createMordnHandler } from '@mordn/chat-widget/server';
import { auth } from '@clerk/nextjs/server';
export const { GET, POST, DELETE, OPTIONS } = createMordnHandler({
apiKey: process.env.MORDN_CHAT_KEY!,
getUserId: async () => (await auth()).userId,
});MORDN_CHAT_KEY="mck_live_..."Every other createChatHandler option is accepted alongside apiKey and
getUserId, so you can add buildTools, cors, or knowledge without giving
up the hosted wiring.
Wiring the pieces yourself
createMordnHandler composes these four clients. Use them directly when you
want to mix hosted and self-hosted parts — for example hosted config with
your own Postgres store.
import {
createHostedChatStore,
createHostedStorage,
createHostedConfig,
createHostedFeedback,
} from '@mordn/chat-widget/server/hosted';
const hosted = { apiKey: process.env.MORDN_CHAT_KEY! };
export const { GET, POST, DELETE } = createChatHandler({
getUserId: getChatUserId,
store: createHostedChatStore(hosted),
storage: createHostedStorage(hosted),
getHostedConfig: createHostedConfig(hosted),
onFeedback: createHostedFeedback(hosted),
});baseUrl defaults to https://api.mordn.com; timeoutMs defaults to 30 seconds.
The key is server-only.
Hosted configuration precedence
createHostedConfig caches per-user results in process for 60 seconds and
returns null on failure. The current normalized fields include model, system
prompt, greeting, appearance, max output tokens, and follow-ups.
- Model: code, then hosted config, then an error.
- System prompt: code, then hosted config, then the package generic prompt.
- Output cap: code, then hosted config, then provider default.
- Follow-ups: code, then hosted config, then off.
Warning
A control-plane failure is harmless only when required code fallbacks exist. If
you omit model and hosted configuration is unavailable or has no model, the
turn fails because there is no package-default model.
Store behavior
The hosted store implements ownership-scoped conversation and message
persistence. Its current listMessages implementation fetches the complete
conversation and ignores limit/before; do not promise infinite-scroll
pagination until the hosted API/store implements it.
Hosted storage provides upload, re-sign, and removal over the same tenant and verified-user axes.