Skip to content
WebMCP Agents
Esc
↑↓navigate↵open⌘Jpreview
On this page

Install in a Next.js app

Six steps, from an empty folder to a tool the agent cursor runs, on the Next.js App Router.

Six steps, from an empty folder to a tool the agent cursor runs. This is how examples/nextjs (Field Store on Next.js) is set up: Next.js 16, the App Router and Turbopack.

Create a project

Skip this if you already have a Next.js app. The recommended defaults are what this page uses: TypeScript, the App Router, Turbopack and the @/ import alias.

npx create-next-app@latest
pnpm dlx create-next-app@latest
yarn dlx create-next-app@latest
bunx create-next-app@latest
nubx create-next-app@latest
aube dlx create-next-app@latest

Install the packages

The agent cursor and the React bindings. Nothing else: the provider loads a WebMCP polyfill where the browser has none, and the devtools panel in development.

npm install @webmcp-agents/core @webmcp-agents/react
pnpm add @webmcp-agents/core @webmcp-agents/react
yarn add @webmcp-agents/core @webmcp-agents/react
bun add @webmcp-agents/core @webmcp-agents/react
nub add @webmcp-agents/core @webmcp-agents/react
aube add @webmcp-agents/core @webmcp-agents/react

Add the styles

Import the cursor’s stylesheet in the root layout, next to your own.

import "@webmcp-agents/core/cursor.css"; 
import "./globals.css";

Add the provider

<WebAgentsProvider> installs the cursor and registers your tools; in a browser without WebMCP it loads a polyfill first, by itself, and in development it installs the devtools panel. It lives in a client component, which Next.js still renders on the server with your page.

"use client";

import { WebAgentsProvider } from "@webmcp-agents/react";
import type { ReactNode } from "react";

export function Providers({ children }: { children: ReactNode }) {
  return <WebAgentsProvider>{children}</WebAgentsProvider>;
}

Wrap the page in it in the root layout. The highlighted lines are the ones you add.

import type { ReactNode } from "react";

import "@webmcp-agents/core/cursor.css";
import "./globals.css";
import { Providers } from "./providers";

export default function RootLayout({
  children,
}: {
  children: ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

Add your first tool

The action is one function with two callers: a person clicks the button, an agent calls the tool. useWebTool registers the tool while the component is on the page. A plain <button> is enough: the cursor finds it by its role and name.

"use client";

import { useWebTool } from "@webmcp-agents/react";
import { useState } from "react";

export function ClearCart() {
  const [items, setItems] = useState(["Ocean Tee", "Canvas Tote"]);

  const clear = () => {
    setItems([]);
    return "The cart is empty.";
  };

  // An agent calls this.
  useWebTool({
    id: "clear_cart",
    title: "Clear cart",
    description:
      "Empty the cart. Use when the user asks to start over. " +
      "The user confirms on the page.",
    destructive: true,
    requireConfirmation: true,
    execute: clear,
  });

  // A person clicks this.
  return (
    <div>
      <p>
        {items.length > 0 ? items.join(", ") : "The cart is empty."}
      </p>

      <button type="button" onClick={clear}>
        Clear cart
      </button>
    </div>
  );
}

Render it on a page. The page itself stays a Server Component.

import { ClearCart } from "@/components/clear-cart";

export default function Page() {
  return (
    <main>
      <ClearCart />
    </main>
  );
}

Run it

Start the app and open it.

npm run dev
pnpm run dev
yarn run dev
bun run dev
nub run dev
aube run dev

Open the devtools panel (bottom right, or Alt+Shift+A), expand clear_cart and press Run. The cursor flies to Clear cart and waits there. Click the button yourself: the cart empties, and the tool answers “The cart is empty.”

Next

Define a tool

What you just wrote, line by line: execute, the title the cursor looks for, and target for when the name is not enough.

Was this page helpful?