webmcp-kit

mcp
Security Audit
Pass
Health Pass
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 11 GitHub stars
Code Pass
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

The easiest way to add WebMCP tools to your website.

README.md

webmcp-kit

npm version
npm downloads
license: MIT
types: TypeScript

Type-safe WebMCP tools with Zod.

What is WebMCP?

WebMCP is a browser API that lets websites expose tools to AI agents, developed under the WebML working group.

The API adds navigator.modelContext, which websites use to register tools that agents can discover and call. Think of it like making your site's functionality available to AI assistants.

The current spec exposes a single method — navigator.modelContext.registerTool(tool, { signal }) — and tools are unregistered by aborting the AbortSignal you passed at registration time. webmcp-kit handles that controller lifecycle for you.

Major browsers are starting to experiment with implementations.

What does webmcp-kit do?

webmcp-kit wraps the raw WebMCP API to make building tools easier:

  • Zod schemas: Define inputs once, get JSON Schema conversion and TypeScript inference
  • Built-in validation: Inputs are validated against your schema before execute runs
  • Less boilerplate: Feature detection, response formatting, and registration handled for you
  • Automatic feature detection: Works when the API exists, falls back gracefully when it doesn't
  • Dev panel: Test and debug tools in the browser without needing a real agent
import { defineTool } from 'webmcp-kit';
import { z } from 'zod';

const addToCart = defineTool({
  name: 'addToCart',
  description: 'Add a product to cart',
  inputSchema: z.object({
    productId: z.string(),
    quantity: z.number().min(1),
  }),
  execute: async ({ productId, quantity }) => {
    // productId and quantity are typed
    return `Added ${quantity}x ${productId}`;
  },
});

addToCart.register();

Install

npm install webmcp-kit zod

Requires Zod v4.

Install and Use the add-webmcp-tools Skill

Install the skill from this repository using Vercel's Skills CLI:

npx skills add victorhuangwq/webmcp-kit

Then invoke it with requests like:

  • "add a webmcp tool for search"
  • "debug why my tool is not in dev panel"
  • "update tool schema and validation"

References:

Usage

Define a Tool

import { defineTool } from 'webmcp-kit';
import { z } from 'zod';

const searchProducts = defineTool({
  name: 'searchProducts',
  description: 'Search the product catalog',
  inputSchema: z.object({
    query: z.string().describe('Search query'),
    limit: z.number().optional().default(10),
  }),
  execute: async ({ query, limit }) => {
    const results = await db.products.search(query, limit);
    return JSON.stringify(results);
  },
});

searchProducts.register();

The schema is converted to JSON Schema for the WebMCP API. Your execute function receives typed inputs.

User Interaction

Tools can request confirmation or input from the user:

const checkout = defineTool({
  name: 'checkout',
  description: 'Complete purchase',
  inputSchema: z.object({ cartId: z.string() }),
  execute: async ({ cartId }, client) => {
    const { confirmed } = await client.requestUserInteraction({
      prompt: 'Confirm purchase?',
      type: 'confirmation',
    });

    if (!confirmed) return 'Cancelled';

    await processOrder(cartId);
    return 'Order placed';
  },
});

Response Helpers

import { textContent, jsonContent, errorContent } from 'webmcp-kit';

// String responses are auto-wrapped, but you can be explicit:
return textContent('Done');
return jsonContent({ status: 'ok' });
return errorContent('Something went wrong');

Dev Panel

Test tools without a real agent:

import { enableDevMode } from 'webmcp-kit/devtools';

enableDevMode();

This injects a panel that lists your tools, generates input forms from schemas, and lets you execute them.

API

defineTool(options)

const tool = defineTool({
  name: string,
  title?: string,
  description: string,
  inputSchema: ZodSchema,
  execute: (input, client) => Promise<string | ToolResponse>,
  annotations?: ToolAnnotations, // { readOnlyHint?, untrustedContentHint? }
});

tool.register();   // Add to navigator.modelContext (mints an AbortController internally)
tool.unregister(); // Aborts the signal — removes the tool
tool.execute(input); // Call directly (for testing)

Internally, tool.register() calls navigator.modelContext.registerTool(tool, { signal }) with a kit-owned AbortController. tool.unregister() aborts it. You don't need to manage controllers yourself.

unregisterAll() / getRegisteredTools()

The kit tracks every tool you register via defineTool().register() in a process-wide set. This is handy for HMR, SPA route teardown, and test cleanup:

import { unregisterAll, getRegisteredTools } from 'webmcp-kit';

// e.g. on Vite HMR dispose
if (import.meta.hot) {
  import.meta.hot.dispose(() => unregisterAll());
}

console.log(getRegisteredTools().map((t) => t.name));

enableDevMode()

import { enableDevMode } from 'webmcp-kit/devtools';

enableDevMode();

How It Works

defineTool() creates a tool object. When you call .register():

  1. It checks if navigator.modelContext exists
  2. If yes, registers with the native API
  3. If no, registers with an internal mock (so the dev panel still works)

Your code doesn't change based on environment. When browsers ship WebMCP support, the same code will use the real API.

Examples

  • examples/pizza-shop: pizza ordering flow with multiple tools (getMenu, addToCart, checkout).
  • examples/flight-booking: multi-step flight purchase flow (searchFlights, selectFlight, addTraveler, addExtras, purchaseFlight).

Both examples include setup instructions for testing with native WebMCP and mock mode.

Support

If you find webmcp-kit useful:

  • Star the repo: It helps others discover the project
  • Report issues: Found a bug or have a feature request? Open an issue

License

MIT

Reviews (0)

No results found