Overview
Drop-in middleware for 7 frameworks.
How adapters work
The kavachos package has zero framework dependencies. It operates entirely on the Web platform Request/Response API. Adapter packages wrap the core and expose framework-idiomatic handlers for authentication, authorization, and MCP OAuth routes.
Each adapter follows the same pattern: accept a kavach instance, optionally accept a config object, and return something your framework knows how to mount.
import { createKavach, createMcpModule } from 'kavachos';
const kavach = createKavach({
database: { provider: 'sqlite', url: 'kavach.db' },
baseUrl: 'https://auth.yourapp.com',
});
const mcp = createMcpModule(kavach); // optional — enables MCP OAuth endpointsPass mcp to the adapter to enable all MCP OAuth 2.1 endpoints under the same mount path.
Available adapters
| Package | Framework | Mount pattern |
|---|---|---|
@kavachos/hono | Hono | app.route('/api/kavach', kavachHono(kavach)) |
@kavachos/express | Express | app.use('/api/kavach', kavachExpress(kavach)) |
@kavachos/nextjs | Next.js App Router | catch-all route app/api/kavach/[...kavach]/route.ts |
@kavachos/fastify | Fastify | app.register(kavachFastify(kavach), { prefix: '/api/kavach' }) |
@kavachos/nuxt | Nuxt (H3) | catch-all file server/api/kavach/[...].ts |
@kavachos/sveltekit | SvelteKit | catch-all route src/routes/api/kavach/[...path]/+server.ts |
@kavachos/astro | Astro | catch-all page src/pages/api/kavach/[...path].ts |
Endpoints registered
All adapters register the same set of REST routes under basePath (default /api/kavach):
| Path | Methods | Description |
|---|---|---|
/agents | GET, POST | List and create agents |
/agents/:id | GET, PATCH, DELETE | Get, update, revoke an agent |
/agents/:id/rotate | POST | Rotate an agent's token |
/authorize | POST | Authorize an action by agent ID |
/authorize/token | POST | Authorize an action by bearer token |
/delegations | POST | Create a delegation chain |
/delegations/:id | GET, DELETE | List or revoke a delegation |
/audit | GET | Query audit logs |
/audit/export | GET | Export audit logs as JSON or CSV |
When mcp is passed, additional endpoints are registered:
| Path | Methods | Description |
|---|---|---|
/.well-known/oauth-authorization-server | GET | OAuth 2.1 server metadata (RFC 8414) |
/.well-known/oauth-protected-resource | GET | Protected resource metadata (RFC 9728) |
/mcp/register | POST | Dynamic client registration (RFC 7591) |
/mcp/authorize | GET | Authorization endpoint (PKCE + S256) |
/mcp/token | POST | Token endpoint |
Using without an adapter
If your framework is not listed, use the core handler directly. It works with any server that handles standard Request objects.
import { createKavach, createMcpModule } from 'kavachos';
const kavach = createKavach({ /* ... */ });
const mcp = createMcpModule(kavach);
async function handler(request: Request): Promise<Response> {
// Let KavachOS handle its own routes
const kavachResponse = await mcp.handleRequest(request);
if (kavachResponse) return kavachResponse;
// Validate auth for your protected routes
const authResult = await mcp.validateRequest(request);
if (!authResult.valid) {
return mcp.buildUnauthorizedResponse(request);
}
return new Response(JSON.stringify({ tools: [] }), {
headers: { 'Content-Type': 'application/json' },
});
}handleRequest returns null when the request URL does not match any KavachOS route, so your own handlers run normally for all other paths.