Make your Next.js app agent-ready.

opdeck reads your routes, server actions and schemas at build time and emits the MCP tools agents need. Every mutation stays locked until you allow it by name. No LLM in the loop, nothing guessed.

Open source, Apache-2.0. View on GitHub

app/api/orders/[id]/route.ts
/**
 * Cancel an order and delete its record.
 * @agent effect irreversible
 */
export async function DELETE(
  _req: Request,
  { params }: { params: Promise<{ id: string }> },
) {
  const session = await auth();
  if (!session) return new Response(null, { status: 401 });
  const { id } = await params;
  await db.order.delete({ where: { id } });
  return new Response(null, { status: 204 });
}
.agent/tools.json
{
  "name": "delete_orders_by_id",
  "description": "Cancel an order and delete its record.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "id": {
        "type": "string"
      }
    },
    "required": [
      "id"
    ]
  },
  "kind": "route",
  "method": "DELETE",
  "path": "/api/orders/{id}",
  "effect": "irreversible",
  "auth": "required",
  "enabled": false
}
Literal compiler output. The handler goes in; a described, classified, disabled tool comes out.

What a build gives you

.agent/ bundle

A readable Markdown tree describing every action your app exposes. Check it into your repo. Review it like code.

A live MCP endpoint

Your app serves its own agent surface at /api/mcp. No separate server to deploy, nothing new to run.

A coverage report

See exactly what the compiler understood, with evidence for every claim it makes.

Locked by default

readwriteirreversible

Every action is labeled. The label travels with the tool.

Mutations ship disabled

You enable them one by one, by exact name. No wildcards, ever.

Invisible without a token

Unconfigured endpoints return 404.

Your auth still runs

On every request. opdeck never bypasses it.

Make your app operable.