Sep 30, 2026

Self-hosting Currai: your first agent conversation

Set up your own Currai instance, connect a working agent, and verify one real conversation from the user exchange to its model and tool events.

FEATURES6 min readThe Currai team / Engineering

The first useful result from a self-hosted Currai instance is a conversation you can recognize. You ask your agent a question, see its answer, and find the same exchange in your workspace alongside the operations that produced it.

This guide takes you from a fresh checkout to that result. Start with a test application and synthetic messages. Once capture works, you can decide which production workflows to instrument.

What you need

Prepare Node.js 22.12 or newer, pnpm 9.12.0, and your own Convex and Clerk projects. Currai uses Next.js for the application, Convex for its backend, and Clerk for authentication. Intent and violation classification also requires a TypeSafe API key.

You need a working chat or agent application to connect. Keep it separate from the Currai application, including its environment file and development port. Your agent's model-provider credentials belong in that application's server environment.

Self-hosting gives you an instance to operate. It still uses these services; starting Next.js locally does not make the whole system run offline.

1. Get the self-hosted edition

Start from the Currai repository and use the self-hosted edition described in its README. Its repository includes the application, ingestion code, and integration helpers.

git clone https://github.com/curraiapp/currai.git
cd currai
corepack enable
corepack prepare pnpm@9.12.0 --activate
pnpm install --frozen-lockfile
cp apps/web/.env.example apps/web/.env.local

Use .env.example as the configuration inventory. The repository's development guide is the reference for setup details when upgrading to a different release.

2. Configure authentication and the backend

Create a Clerk application for this test environment. Put its publishable and secret keys in apps/web/.env.local, using the variable names in the example file. Configure a Clerk JWT template named convex with audience convex.

From apps/web, initialize your Convex development project:

pnpm exec convex dev

This writes the deployment and public backend URL into the local environment file. Set CLERK_JWT_ISSUER_DOMAIN in the Convex deployment environment to your Clerk issuer URL. If Convex requests this value during initialization, configure it and run the command again.

Create a Clerk webhook that sends user.created and user.updated to:

https://<your-deployment>.convex.site/clerk-auth-webhook

Store its signing secret as CLERK_WEBHOOK_SECRET in Convex. This synchronizes Clerk users with Currai's backend. If you created a user before configuring the webhook, resend the relevant event or update the user in Clerk.

The Next.js environment file and Convex environment are separate configuration locations. Putting a backend secret in .env.local does not configure the remote Convex deployment.

3. Start Currai and create a workspace

Set NEXT_PUBLIC_APP_URL to http://localhost:3000 in the Next.js environment and APP_URL to the same origin in Convex. Set TYPESAFE_API_KEY in Convex for intent and violation classification.

After backend setup, return to the repository root and initialize the model catalog against your development deployment:

pnpm seed
pnpm dev

Open http://localhost:3000, sign up, and create a workspace. Create an ingestion key during onboarding or in Workspace Settings → API Keys. You will use its public and secret keys to authenticate capture requests.

4. Point your agent at your instance

In the application you want to instrument, set these server-side environment variables:

CURRAI_BASE_URL=http://localhost:3000
CURRAI_PUBLIC_KEY=<your-workspace-public-key>
CURRAI_SECRET_KEY=<your-workspace-secret-key>

Keep the keys out of browser code. For a Next.js agent application, do not prefix them with NEXT_PUBLIC_. Restart the agent application after changing its environment.

The base URL is essential: the integration skill defaults to hosted Currai when you do not set it. If the agent runs in a container or on another machine, localhost refers to that environment. Use an address that can reach your Currai server instead.

5. Instrument the conversation path

You can install the Currai integration skill in the agent application's project:

npx skills add https://github.com/curraiapp/skills --skill currai

Ask your coding agent:

Connect this application's real chat or agent path to my self-hosted Currai instance using CURRAI_BASE_URL. Capture the session and agent events through native HTTP, include model and tool events where available, and verify one real interaction. Keep the workspace keys server-side.

For a manual integration, use POST /api/v1/capture-session to create or update the conversation and POST /api/v1/capture-event for its operations. Native capture uses HTTP Basic authentication, with the workspace public key as the username and secret key as the password. The streaming chatbot integration guide walks through the payloads and server-side helper.

Use one stable session ID across the conversation. Give each operation its own event ID and use parent IDs to connect model and tool events to the agent turn. Start a new session when the user begins a new conversation.

Capture the actual input and output from execution. A canned demo event can confirm connectivity, but it does not show that your application's conversation path is instrumented.

6. Send one real message and inspect it

Use your agent's normal interface to send a recognizable test request, such as:

Summarize our fictional return policy: unopened items can be returned within 30 days with a receipt.

Wait for the answer, then open your Currai workspace. Find the session and check that the user request and agent response match what you just saw. Inspect the agent event and any model or tool events your integration captures.

Send a follow-up in the same conversation. It should reuse the session ID and add a new turn. Start a new conversation and confirm it gets a different session.

If you want to examine intent or violation findings, configure rules appropriate to the test and confirm the classification credentials are present in Convex. Ingestion and classification are separate checks: an imported conversation does not by itself prove that classification is configured.

If the conversation does not appear

Check the destination first. Confirm the running agent process has your local CURRAI_BASE_URL, rather than the hosted default, and can reach that address. Then inspect capture responses and the Next.js and Convex logs.

An authentication failure can mean the keys belong to another workspace or instance. If sign-in works but onboarding fails, check Clerk's user-sync webhook and Convex configuration. If only the demo appears, inspect whether capture runs inside the real chat handler.

For voice-provider webhooks, the local application needs a reachable public HTTPS address. Follow the repository's connector and tunnel instructions; provider webhook URLs target the Next.js application, while the Clerk user-sync webhook targets Convex.

Before moving to production

Create separate production Convex and Clerk projects, configure your deployed application origin, and repeat the same conversation check. Assign responsibility for updates, credentials, backups, and retention. The self-hosted edition removes application subscriptions and event quotas; you still operate the infrastructure and pay its service and model costs.

If you are deciding who should operate that system, read Open-source vs hosted Currai: choosing what fits your team.

03

Keep going with nearby topics from the Currai blog.