kavachOS
Framework adapters

Next.js

KavachOS adapter for Next.js App Router.

kavachNextjs(kavach, options?) returns named route handlers { GET, POST, PATCH, DELETE, OPTIONS } for the Next.js App Router. Mount them in a catch-all route file so all KavachOS paths are handled.

Install

pnpm add kavachos @kavachos/nextjs

Setup

Create the kavach instance

Create this in a shared module so it is initialized once at server startup:

// lib/kavach.ts
import { createKavach, createMcpModule } from 'kavachos';

export const kavach = createKavach({
  database: { provider: 'postgres', url: process.env.DATABASE_URL! },
  baseUrl: process.env.AUTH_BASE_URL!,
  mcp: {
    issuer: process.env.AUTH_BASE_URL!,
    audience: process.env.MCP_BASE_URL!,
  },
});

export const mcp = createMcpModule(kavach);

Create the catch-all route

Create app/api/kavach/[...kavach]/route.ts. The [...kavach] segment catches every sub-path under /api/kavach/.

// app/api/kavach/[...kavach]/route.ts
import { kavachNextjs } from '@kavachos/nextjs';
import { kavach, mcp } from '@/lib/kavach';

const handlers = kavachNextjs(kavach, { mcp });

export const GET = handlers.GET;
export const POST = handlers.POST;
export const PATCH = handlers.PATCH;
export const DELETE = handlers.DELETE;
export const OPTIONS = handlers.OPTIONS;

The basePath option defaults to /api/kavach. If you mount at a different path such as /api/auth/kavach, pass basePath: '/api/auth/kavach' so the dispatcher can strip the prefix correctly.

Options

interface KavachNextjsOptions {
  mcp?: McpAuthModule;     // enables MCP OAuth 2.1 endpoints
  basePath?: string;       // defaults to '/api/kavach'
}

MCP endpoints

When mcp is passed, the following endpoints are available:

GET  /api/kavach/.well-known/oauth-authorization-server
GET  /api/kavach/.well-known/oauth-protected-resource
POST /api/kavach/mcp/register
GET  /api/kavach/mcp/authorize
POST /api/kavach/mcp/token

Endpoint reference

MethodPathDescription
POST/agentsCreate an agent
GET/agentsList agents
GET/agents/:idGet an agent
PATCH/agents/:idUpdate an agent
DELETE/agents/:idRevoke an agent
POST/agents/:id/rotateRotate token
POST/authorizeAuthorize by agent ID
POST/authorize/tokenAuthorize by bearer token
POST/delegationsCreate delegation
GET/delegations/:agentIdList delegation chains
DELETE/delegations/:idRevoke delegation
GET/auditQuery audit logs
GET/audit/exportExport audit logs

Full example

// app/api/kavach/[...kavach]/route.ts
import { createKavach, createMcpModule } from 'kavachos';
import { kavachNextjs } from '@kavachos/nextjs';

const kavach = createKavach({
  database: { provider: 'postgres', url: process.env.DATABASE_URL! },
  baseUrl: process.env.AUTH_BASE_URL!,
  mcp: {
    issuer: process.env.AUTH_BASE_URL!,
    audience: process.env.MCP_BASE_URL!,
  },
});

const mcp = createMcpModule(kavach);

const handlers = kavachNextjs(kavach, { mcp });

export const GET = handlers.GET;
export const POST = handlers.POST;
export const PATCH = handlers.PATCH;
export const DELETE = handlers.DELETE;
export const OPTIONS = handlers.OPTIONS;

Do not define createKavach inside the route file if you need the instance elsewhere in your app. Export it from lib/kavach.ts and import it where needed to avoid creating multiple instances.

On this page