Next.js quickstart
Next.js. App Router. Ten minutes.
Works on App Router and Pages Router. The middleware handles the callback routes and the hook handles the client. You write your app.
Install
Install the core library and the Next.js adapter in one step.
pnpm add kavachos @kavachos/nextjsConfigure the auth module
Create a single config module at the root of your lib folder. This is the only file that imports provider credentials.
import { createAuth } from "kavachos";
import { nextAdapter } from "@kavachos/nextjs";
import { drizzleAdapter } from "kavachos/adapters/drizzle";
import { db } from "./db";
export const auth = createAuth({
secret: process.env.KAVACHOS_SECRET!,
baseUrl: process.env.APP_URL ?? "http://localhost:3000",
database: drizzleAdapter(db),
providers: [
{ id: "github", clientId: process.env.GITHUB_ID!, clientSecret: process.env.GITHUB_SECRET! },
],
});
export const nextAuth = nextAdapter(auth);Add middleware
Drop the adapter middleware at the project root. It owns the sign-in, callback, session, and sign-out routes.
import { nextAuth } from "./lib/auth";
export default nextAuth.middleware({
protected: ["/dashboard/:path*"],
});
export const config = {
matcher: ["/((?!_next|favicon.ico|.*\\..*).*)"],
};Read the session in a Server Component
In an App Router Server Component, call nextAuth.session(). It returns the resolved session or null, reading the cookie on the server.
import { nextAuth } from "@/lib/auth";
import { redirect } from "next/navigation";
export default async function Dashboard() {
const session = await nextAuth.session();
if (!session) redirect("/sign-in");
return <h1>Hello, {session.user.name}</h1>;
}Use the client hook
In a Client Component, import useSession from the client entry point. It subscribes to session changes and exposes sign-out.
"use client";
import { useSession } from "@kavachos/nextjs/client";
export function UserMenu() {
const { session, signOut } = useSession();
if (!session) return <a href="/sign-in">Sign in</a>;
return <button onClick={() => signOut()}>Sign out, {session.user.name}</button>;
}Grant an agent token
When a signed-in human wants to dispatch an AI agent, mint a delegation token scoped tight.
import { nextAuth } from "@/lib/auth";
export async function POST() {
const session = await nextAuth.session();
if (!session) return new Response("Unauthorized", { status: 401 });
const agent = await nextAuth.agents.create({
parent: session.subject.id,
name: "research.assistant",
scopes: ["tools:call:search"],
ttl: "15m",
});
const token = await nextAuth.agents.issueToken(agent.id, {
audience: "https://your.mcp.server",
});
return Response.json({ token });
}What is next
You have a working flow. Now pick the next layer based on what you are building: agent identity, MCP OAuth, SCIM, or enterprise SSO.
- · Full identity model. Read concepts.
- · Agent delegation. AI agents guide.
- · MCP tool servers. MCP OAuth 2.1 guide.