Protect an Express App
Use @caracalai/mcp-express when an Express app should verify Caracal mandates before route handlers run.
Install
Section titled “Install”npm install express @caracalai/mcp-express @caracalai/transport-mcp @caracalai/revocationUse a Redis-backed revocation store in production. The in-memory store is only suitable for local development and tests.
Add middleware
Section titled “Add middleware”import express from "express";import { caracalAuth, type CaracalRequest } from "@caracalai/mcp-express";import { createMandateVerifier } from "@caracalai/transport-mcp";import { InMemoryRevocationStore } from "@caracalai/revocation";
const app = express();
const verifier = createMandateVerifier({ issuer: process.env.CARACAL_ISSUER!, audience: process.env.CARACAL_AUDIENCE!, zoneId: process.env.CARACAL_ZONE_ID!, revocations: new InMemoryRevocationStore(),});
await verifier.warmup();
app.use("/mcp", caracalAuth({ verifier }, { requiredScopes: ["mcp:tool:call"], requiredTargets: ["https://mcp.example.com"],}));
app.post("/mcp/tools/list", (req: CaracalRequest, res) => { res.json({ principal: req.caracalClaims?.sub, tools: ["search", "summarize"], });});The middleware attaches verified claims to req.caracal and req.caracalClaims, plus the propagation context at req.caracalContext.
Enforce the right boundary
Section titled “Enforce the right boundary”| Option | Use it for |
|---|---|
requiredScopes | Tool or route-level scope checks. |
requiredTargets | Resource-target checks. |
requireAgent | Reject non-agent mandates. |
requireDelegation | Require delegated authority. |
maxHopCount | Limit delegation depth. |
Validate
Section titled “Validate”- Exchange for a mandate that targets the resource.
- Call the protected route with
Authorization: Bearer <mandate>. - Remove a required scope and confirm the route returns
403. - Revoke the session and confirm the route rejects the old mandate.
Related pages: Mandates and Sessions and Revocation.

