build

Integrate with Next.js

Expose the canonical Kestrel agent through server-only JSON, SSE, or webhook routes while keeping credentials and actor context on the server.

Next.jsbeginnerCurrent releases
Verified 2026-08-25View sourceReport a docs issue

Install

Bash
pnpm add @kestrel-agents/next@0.8.5 @kestrel-agents/sdk@0.8.5

Create the agent in a server-only module using the kestrel profile, as in the first Build step. Resolve the actor and tenant from the authenticated server session for each request.

Resolve server-owned identity

Authenticate before parsing identity-bearing request fields. The server owns tenant, actor, provider authority, approval context, and runner credentials; the browser may supply only validated user intent and resource identifiers it is authorized to access.

JSON route

Create app/api/agent/run/route.ts:

TypeScript
import { createJsonRunRouteHandler } from "@kestrel-agents/next";
import { agent } from "@/lib/kestrel-agent";
import { resolveKestrelContext } from "@/lib/auth";
 
export const POST = createJsonRunRouteHandler({
  agent,
  resolveContext: resolveKestrelContext,
});

The default request body is:

JSON
{
  "sessionId": "kestrel-session-001",
  "message": "Summarize the current project."
}

The handler validates the body, runs the agent, returns the terminal event as JSON, and adds x-kestrel-request-id and x-kestrel-correlation-id.

Streaming route

TypeScript
import { createStreamRunRouteHandler } from "@kestrel-agents/next";
import { agent } from "@/lib/kestrel-agent";
import { resolveKestrelContext } from "@/lib/auth";
 
export const POST = createStreamRunRouteHandler({
  agent,
  resolveContext: resolveKestrelContext,
});

This handler returns server-sent events and passes request.signal to the SDK. Closing the response cancels the exact upstream run.

Webhook route

Use a webhook helper when the incoming payload does not already have the Kestrel turn shape:

TypeScript
import { createWebhookRunRouteHandler } from "@kestrel-agents/next";
import { agent } from "@/lib/kestrel-agent";
import { resolveKestrelContext } from "@/lib/auth";
 
export const POST = createWebhookRunRouteHandler<{
  conversationId: string;
  prompt: string;
}>({
  agent,
  resolveContext: resolveKestrelContext,
  mapPayload(payload) {
    return {
      sessionId: payload.conversationId,
      message: payload.prompt,
    };
  },
});

Authenticate and validate the webhook before treating its fields as actor, tenant, session, or approval context.

Correlation ownership

The Next.js helpers read x-request-id and x-correlation-id, generate missing values, and return x-kestrel-request-id and x-kestrel-correlation-id. Session and run headers belong to upstream OpenAI-compatible responses; they are not generated by these route helpers.

Failure handling

Return safe, distinct failures for authentication, invalid input, unreachable runner, interrupted stream, and terminal failure. A waiting or cancelled terminal result is not a generic HTTP success message and must remain visible to the client as runtime state.

Verify

Exercise the JSON, streaming, and webhook routes outside the browser trust boundary. Confirm forged actor headers are ignored, disconnect cancels the exact stream, webhook retries are idempotent, and request/correlation identifiers reach the terminal result.

Use the route cookbook for request and response details or OpenAI-compatible HTTP for an existing OpenAI client.