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

Install without a framework

Six steps, from an empty folder to a tool the agent cursor runs, with plain HTML and TypeScript and createWebAgents.

Six steps, from an empty folder to a tool the agent cursor runs, with no framework: plain HTML, TypeScript and createWebAgents from @webmcp-agents/core. Use this for a classic site, or with Vue or Svelte.

Create a project

Skip this if you already have a page with a bundler. In the prompts, choose Vanilla and TypeScript.

npm create vite@latest
pnpm create vite@latest
yarn create vite@latest
bun create vite@latest
nub create vite@latest
aube create vite@latest

Install the packages

The agent cursor, then the devtools panel for development. Without React, nothing installs the panel for you, and it draws itself with React, so React comes along as a development dependency. Browsers without WebMCP need nothing more: createWebAgents loads a polyfill for them.

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

Add the styles

Import the cursor’s stylesheet in your entry file.

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

Add the provider

Without a framework there is no provider component: createWebAgents is the function <WebAgentsProvider> wraps. It installs the cursor and registers your tools, which you write in the next step; in a browser without WebMCP it loads a polyfill first, by itself. In development the same file loads the devtools: <WebAgentsProvider> installs them itself, but createWebAgents cannot (the devtools are built on core), so this page keeps that one block.

import { createWebAgents } from "@webmcp-agents/core";

import "@webmcp-agents/core/cursor.css";
import { saveNote, tools } from "./tools";

createWebAgents({ tools });

// Development only: the devtools panel, wired to the cursor above.
// <WebAgentsProvider> installs it itself; createWebAgents cannot,
// since the devtools are built on this package.
if (import.meta.env.DEV) {
  const { installWebAgentsDevtools } = await import(
    "@webmcp-agents/devtools"
  );
  installWebAgentsDevtools();
}

// A person submits this.
const form = document.querySelector("form")!;

form.addEventListener("submit", (event) => {
  event.preventDefault();

  saveNote(String(new FormData(form).get("text")));
  form.reset();
});

Add your first tool

The action is one function with two callers: a person submits the form, an agent calls the tool. The page needs nothing for the cursor: it finds the button by its name and the field by its name.

import { defineWebTool } from "@webmcp-agents/core";

const notes: string[] = [];

// One function, two callers.
export function saveNote(text: string) {
  notes.push(text);
  document.querySelector("#notes")!.textContent = notes.join(" · ");

  return `Saved: ${text}`;
}

// An agent calls this.
const saveNoteTool = defineWebTool({
  id: "save_note",
  title: "Save note",
  description:
    "Save a note. Use when the user asks you to write something down.",
  inputSchema: {
    type: "object",
    properties: {
      text: { type: "string", description: "The note, e.g. Buy milk" },
    },
    required: ["text"],
  },
  execute: ({ text }: { text: string }) => saveNote(text),
});

export const tools = { saveNote: saveNoteTool };
<form>
  <label>Note <input name="text" required /></label>
  <button type="submit">Save note</button>
</form>

<p id="notes"></p>

<script type="module" src="/src/main.ts"></script>

Run it

Start the page 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 save_note, type a note and press Run. The cursor types it into Note, presses Save note, and the tool answers “Saved: …”.

Next

The pages under Build show React code. Everything they teach about a tool applies here unchanged, because useWebTool takes the same definition as defineWebTool.

Was this page helpful?