webmcpregistry Svelte Themes

Webmcpregistry

The open-source SDK that makes any website WebMCP-ready. Framework adapters for React, Vue, Angular, Svelte, Next.js + CLI + conformance tests + evals.


WebMCP Registry SDK

Make any website callable by AI agents.

npm version CI License


The WebMCP Registry SDK is a TypeScript monorepo that implements the W3C Web Model Context Protocol draft specification. It lets websites register structured, type-safe tools that AI agents -- Claude, ChatGPT, Gemini, Copilot -- can discover and invoke directly through navigator.modelContext. No DOM scraping, no custom integrations, no glue code.

No browser ships WebMCP natively yet. This SDK provides a spec-compliant polyfill that works today and steps aside when native support lands. Framework adapters for React, Vue, Angular, Svelte, and Next.js are each under 3KB. A zero-dependency <script> tag covers everything else.

Table of Contents

Why WebMCP?

The W3C WebMCP specification (Draft Community Group Report, March 9, 2026 -- editors: Brandon Walderman/Microsoft, Khushal Sagar/Google, Dominic Farolino/Google) introduces navigator.modelContext to the browser platform. Instead of agents blindly scraping HTML and guessing at UI elements, websites declare what they can do:

navigator.modelContext.registerTool({
  name: 'search_products',
  description: 'Search the product catalog by keyword',
  inputSchema: {
    type: 'object',
    properties: { query: { type: 'string' } },
    required: ['query'],
  },
  execute: async (input) => {
    return fetch(`/api/search?q=${input.query}`).then(r => r.json())
  },
})

An AI agent visiting the page discovers search_products, knows its schema, calls it with typed arguments, and gets structured data back. Structured, bidirectional communication between websites and AI agents, standardized at the platform level.

This SDK provides:

  • A polyfill that faithfully implements navigator.modelContext so you can ship today
  • Framework adapters that manage tool lifecycle (mount/unmount) idiomatically
  • Validation, security scanning, and grading to ensure tool quality
  • Manifest generation (/.well-known/webmcp.json, JSON-LD, llms.txt, agents.json) for offline agent discovery
  • A Playwright-powered MCP server that bridges WebMCP tools into the MCP ecosystem (Claude Desktop, Cursor, VS Code)
  • Testing infrastructure: schema-driven test generation, contract testing, mutation testing, W3C conformance suite, and eval harness

Quick Start

React

npm install @webmcpregistry/react
import { WebMCPProvider, useWebMCPTool } from '@webmcpregistry/react'

function App() {
  return (
    <WebMCPProvider mode="auto">
      <SearchPage />
    </WebMCPProvider>
  )
}

function SearchPage() {
  useWebMCPTool({
    name: 'search_products',
    description: 'Search the product catalog by keyword',
    inputSchema: {
      type: 'object',
      properties: { query: { type: 'string', description: 'Search term' } },
      required: ['query'],
    },
    safetyLevel: 'read',
    handler: async ({ query }) => {
      const res = await fetch(`/api/search?q=${query}`)
      return res.json()
    },
  })

  return <div>Search Page</div>
}

Vue 3

npm install @webmcpregistry/vue
import { createApp } from 'vue'
import { webmcpPlugin } from '@webmcpregistry/vue'

createApp(App).use(webmcpPlugin, { mode: 'auto' }).mount('#app')

Script Tag (zero dependencies)

<script src="https://unpkg.com/@webmcpregistry/browser/dist/auto.global.js"
        data-mode="auto"></script>

Packages

Package Description Version
@webmcpregistry/core Polyfill, detector, registrar, validator, security scanner, manifest generation
@webmcpregistry/react React hooks -- useWebMCPTool, WebMCPProvider, useWebMCPContext
@webmcpregistry/nextjs Next.js App Router adapter with 'use client'
@webmcpregistry/vue Vue 3 plugin + composables
@webmcpregistry/angular Angular service + provideWebMCP()
@webmcpregistry/svelte Svelte stores + use:webmcpTool action
@webmcpregistry/browser Zero-dependency <script> tag bundle (IIFE)
@webmcpregistry/cli CLI: test, scan, init commands
@webmcpregistry/testing Schema-driven test generation, contract testing, mutation testing
@webmcpregistry/conformance W3C spec conformance suite (12 scenarios)
@webmcpregistry/evals AI agent tool-calling accuracy evaluation
@webmcpregistry/mcp-server Playwright-powered MCP-to-WebMCP bridge

Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                          Your Application                               │
│                                                                         │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│  │  react   │ │   vue    │ │ angular  │ │  svelte  │ │    nextjs    │ │
│  │  ~2KB    │ │  ~1.5KB  │ │  ~1.3KB  │ │  ~1.2KB  │ │ 'use client' │ │
│  └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │
│       │             │            │             │              │         │
│       └─────────────┴────────────┴─────────────┴──────────────┘         │
│                                  │                                      │
│                       ┌──────────▼──────────┐                           │
│                       │                     │    ┌─────────────────┐   │
│                       │  @webmcpregistry/   │    │    browser      │   │
│                       │       core          │◄───│  <script> tag   │   │
│                       │                     │    │   IIFE bundle   │   │
│                       │  - polyfill         │    └─────────────────┘   │
│                       │  - registrar        │                          │
│                       │  - detector         │                          │
│                       │  - validator        │                          │
│                       │  - security         │                          │
│                       │  - manifest         │                          │
│                       └──────────┬──────────┘                          │
│                                  │                                      │
│                       ┌──────────▼──────────┐                          │
│                       │ navigator.          │                          │
│                       │   modelContext      │                          │
│                       │                     │                          │
│                       │  .registerTool()   │  [SPEC]                  │
│                       │  .unregisterTool() │  [SPEC]                  │
│                       │  .getTools()       │  [EXTENSION]             │
│                       └─────────────────────┘                          │
└─────────────────────────────────────────────────────────────────────────┘

  Quality & Testing                           Agent Bridge
  ─────────────────                           ────────────
  ┌───────────┐ ┌─────────────┐ ┌──────┐     ┌─────────────────────────┐
  │  testing   │ │ conformance │ │ evals│     │      mcp-server         │
  │            │ │             │ │      │     │                         │
  │ test gen   │ │  12 W3C     │ │ tool │     │ Playwright  ──► pages   │
  │ contracts  │ │  scenarios  │ │ sel. │     │ browser        ──► MCP  │
  │ mutations  │ │             │ │ acc. │     │                  stdio  │
  └───────────┘ └─────────────┘ └──────┘     └─────────────────────────┘
                                              Claude Desktop / Cursor /
                                              VS Code / any MCP client

All framework adapters are thin wrappers over core. They handle lifecycle (React effects, Vue onMounted/onUnmounted, Angular DI, Svelte actions) and delegate everything else. The core package contains the polyfill, registration engine, tool detection from DOM attributes, validation, security scanning, and manifest generation.

Framework Examples

React

import { WebMCPProvider, useWebMCPTool } from '@webmcpregistry/react'

// 1. Wrap your app with the provider
<WebMCPProvider mode="auto">
  <App />
</WebMCPProvider>

// 2. Register tools tied to component lifecycle
function ProductSearch() {
  useWebMCPTool({
    name: 'search_products',
    description: 'Search the product catalog by keyword and optional category',
    inputSchema: {
      type: 'object',
      properties: {
        query: { type: 'string', description: 'Search term' },
        category: { type: 'string', enum: ['electronics', 'clothing', 'books'] },
      },
      required: ['query'],
    },
    safetyLevel: 'read',
    handler: async ({ query, category }) => {
      const params = new URLSearchParams({ q: String(query) })
      if (category) params.set('cat', String(category))
      return fetch(`/api/search?${params}`).then(r => r.json())
    },
  })

  return <div>Product Search</div>
}

The tool is registered when the component mounts and unregistered when it unmounts. React Strict Mode double-mounts are handled gracefully.

Next.js (App Router)

// app/layout.tsx
import { WebMCPProvider } from '@webmcpregistry/nextjs'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <WebMCPProvider mode="auto">
          {children}
        </WebMCPProvider>
      </body>
    </html>
  )
}

@webmcpregistry/nextjs re-exports the React adapter with 'use client' baked in. Same hooks, zero additional configuration.

Vue 3

// main.ts
import { createApp } from 'vue'
import { webmcpPlugin } from '@webmcpregistry/vue'
import App from './App.vue'

createApp(App).use(webmcpPlugin, { mode: 'auto' }).mount('#app')
<!-- SearchPage.vue -->
<script setup>
import { useWebMCPTool } from '@webmcpregistry/vue'

useWebMCPTool({
  name: 'search_products',
  description: 'Search the product catalog by keyword',
  inputSchema: {
    type: 'object',
    properties: { query: { type: 'string' } },
    required: ['query'],
  },
  safetyLevel: 'read',
  handler: async ({ query }) => {
    return fetch(`/api/search?q=${query}`).then(r => r.json())
  },
})
</script>

Tools are registered in onMounted and unregistered in onUnmounted, matching Vue's lifecycle.

Angular

// app.config.ts
import { provideWebMCP } from '@webmcpregistry/angular'

export const appConfig = {
  providers: [provideWebMCP({ mode: 'auto' })],
}
// In any component or service
import { getWebMCPService } from '@webmcpregistry/angular'

const webmcp = getWebMCPService()
webmcp.registerTool({
  name: 'search_products',
  description: 'Search the product catalog',
  inputSchema: { type: 'object', properties: { query: { type: 'string' } } },
  safetyLevel: 'read',
  handler: async ({ query }) => fetch(`/api/search?q=${query}`).then(r => r.json()),
})

Works with both standalone components and NgModule patterns. The service creates a fresh instance per request in SSR environments to prevent cross-request contamination.

Svelte

<script>
  import { initWebMCP, webmcpTools } from '@webmcpregistry/svelte'
  import { onMount } from 'svelte'

  onMount(() => initWebMCP({ mode: 'auto' }))
</script>

<p>Registered tools: {$webmcpTools.length}</p>

Or bind a tool to an element's lifecycle with the use:webmcpTool action:

<form use:webmcpTool={{
  name: 'search_products',
  description: 'Search the product catalog',
  inputSchema: { type: 'object', properties: { query: { type: 'string' } } },
  safetyLevel: 'read',
}}>
  <input name="query" />
  <button type="submit">Search</button>
</form>

Vanilla JavaScript

Script tag -- auto-detects tools from DOM attributes:

<script src="https://unpkg.com/@webmcpregistry/browser/dist/auto.global.js"
        data-mode="auto"></script>

Declarative HTML -- no JavaScript required:

<form toolname="search_products"
      tooldescription="Search the product catalog by keyword">
  <input name="query" type="text"
         toolparamdescription="Search keywords" required />
  <button type="submit">Search</button>
</form>

Core API -- framework-agnostic:

import { registerTool, initialize, installPolyfill } from '@webmcpregistry/core'

// Auto mode: detect tools from DOM + install polyfill
const result = initialize({ mode: 'auto' })

// Or register manually
installPolyfill()
registerTool({
  name: 'search_products',
  description: 'Search the product catalog by keyword',
  inputSchema: {
    type: 'object',
    properties: { query: { type: 'string' } },
    required: ['query'],
  },
  safetyLevel: 'read',
  handler: async ({ query }) => fetch(`/api/search?q=${query}`).then(r => r.json()),
})

CLI

The CLI tests, scans, and scaffolds WebMCP implementations without touching your source code.

# Full readiness test (launches a real browser via Playwright)
npx @webmcpregistry/cli test https://yoursite.com

# Lightweight static scan (no browser needed)
npx @webmcpregistry/cli scan https://yoursite.com

# Scaffold WebMCP setup for your framework
npx @webmcpregistry/cli init --framework react
npx @webmcpregistry/cli init --framework vue
npx @webmcpregistry/cli init --framework html

The test command produces a readiness grade (A through F) with a detailed breakdown:

+--------------------------------------+
|  WebMCP Readiness: Grade A (94/100)  |
+--------------------------------------+

  Tool count         ############----  16/20
  Descriptions       ################  23/25
  Schema             ################  20/20
  Naming             ########--------  10/10
  Manifest           ----------------   0/10
  Security           ################  15/15

Output formats: terminal (default), json, badge.

MCP Server Bridge

@webmcpregistry/mcp-server runs a standards-compliant Model Context Protocol server that discovers and executes WebMCP tools from any website using a real Playwright browser. It bridges browser-side WebMCP tools into the desktop AI agent ecosystem.

Claude Desktop / Cursor / VS Code

Add to your MCP client configuration:

{
  "mcpServers": {
    "my-site": {
      "command": "npx",
      "args": ["@webmcpregistry/mcp-server", "--url", "https://mysite.com"]
    }
  }
}

The server launches Chromium, navigates to the URL, discovers all tools registered via navigator.modelContext, and exposes them over MCP stdio. When the agent calls a tool, the server executes it in the real browser context and returns the result.

Built-in meta-tools (always available alongside discovered tools):

Meta-tool Purpose
webmcp_rediscover Re-scan all URLs for new or changed tools
webmcp_validate Run validation + security checks on all discovered tools
webmcp_report Get a detailed discovery report with sources and capabilities

Programmatic API

import { WebMCPGateway } from '@webmcpregistry/mcp-server'

const gateway = new WebMCPGateway({ urls: ['https://mysite.com'] })

// Discover tools
const tools = await gateway.discover()
console.log(`Found ${tools.length} tools`)

// Execute a tool in the real browser
const result = await gateway.callTool('search_products', { query: 'shoes' })
console.log(result)

await gateway.dispose()

Testing and Quality

The SDK includes three testing packages. Everything runs deterministically -- no LLM calls required.

Schema-Driven Test Generation

Auto-generate test cases from your tool's inputSchema covering valid inputs, invalid inputs, boundary values, type coercion, and security vectors:

import { generateTestCases, runTestSuite } from '@webmcpregistry/testing'

const cases = generateTestCases(myTool)
// Generates: valid inputs, missing required fields, wrong types,
//            empty strings, boundary values, injection attempts

const results = await runTestSuite([myTool])
console.log(`${results.passed}/${results.total} passed`)

Contract Testing

Capture a snapshot of your tool definitions and detect breaking changes between releases:

import { captureContract, diffContracts } from '@webmcpregistry/testing'

const before = captureContract(tools, 'mysite.com')
// ... deploy changes ...
const after = captureContract(newTools, 'mysite.com')
const diff = diffContracts(before, after)

if (diff.isBreaking) {
  console.error('Breaking changes:', diff.removed, diff.changed.filter(c => c.breaking))
  process.exit(1)
}

Mutation Testing

Verify your test suite catches real problems by introducing schema mutations:

import { generateAllMutations, calculateMutationScore } from '@webmcpregistry/testing'

const mutations = generateAllMutations(tools)
const score = await calculateMutationScore(mutations, testRunner)
console.log(`Mutation score: ${score}%`) // Higher = better fault detection

W3C Conformance Suite

Run 12 scenarios that verify any navigator.modelContext implementation against the W3C draft spec:

import { runConformance, formatReport } from '@webmcpregistry/conformance'
import { installPolyfill, getModelContext } from '@webmcpregistry/core'

installPolyfill()
const report = await runConformance(getModelContext()!, 'polyfill v0.2.1')
console.log(formatReport(report))
// => 100% (12/12) passed

Agent Evaluation

Measure how "obvious" your tool definitions are to AI agents. The eval harness uses deterministic matching to grade tool selection accuracy -- without calling an LLM:

import { createEvalSuite, runEvalSuite } from '@webmcpregistry/evals'

const suite = createEvalSuite(tools, [
  { task: 'Find flights to Tokyo under $500', expectedTool: 'search_flights' },
  { task: 'Book the cheapest option', expectedTool: 'book_flight' },
  { task: 'Cancel my reservation', expectedTool: 'cancel_booking' },
])

const report = runEvalSuite(suite)
console.log(`Tool selection accuracy: ${report.selectionAccuracy}%`)

Agent Discovery

Generate machine-readable manifests so AI agents can discover your tools without loading the page:

import {
  generateManifest,
  generateJsonLd,
  generateLlmsTxt,
  generateAgentsJson,
} from '@webmcpregistry/core'

const siteInfo = { name: 'My Site', url: 'https://mysite.com' }

generateManifest(tools, siteInfo)   // /.well-known/webmcp.json
generateJsonLd(tools, siteInfo)     // JSON-LD structured data
generateLlmsTxt(tools, siteInfo)    // llms.txt for LLM crawlers
generateAgentsJson(tools, siteInfo) // agents.json

Spec Alignment

This SDK tracks the W3C WebMCP Draft Community Group Report (March 9, 2026). Every type in the codebase is explicitly tagged:

Tag Meaning Examples
[SPEC] Matches the W3C draft exactly registerTool, unregisterTool, execute(input, client), ToolAnnotations.readOnlyHint, ModelContextClient
[EXTENSION] SDK additions beyond the spec getTools(), safetyLevel, handler (simplified execute), destructiveHint, confirmationHint, idempotentHint, manifest generation

When the spec evolves, we update. When browsers ship native navigator.modelContext, the polyfill detects it and defers to the native implementation.

See packages/core/src/types.ts for the fully annotated type definitions.

Development

git clone https://github.com/samuelvinay91/webmcpregistry.git
cd webmcpregistry
pnpm install
Command Description
pnpm build Build all packages (Turborepo)
pnpm test Run all tests
pnpm dev Watch mode for all packages
pnpm --filter @webmcpregistry/core test Run core tests only
pnpm --filter @webmcpregistry/core build Build a single package
pnpm --filter @webmcpregistry/docs dev Docs site on localhost:3000

Requirements: Node.js 20+, pnpm 10+. The monorepo uses Turborepo for orchestration, tsup for builds (ESM + CJS + DTS), and Vitest for testing.

Acknowledgments

This SDK implements the WebMCP draft specification created by the W3C Web Machine Learning Community Group. We are grateful to:

  • Spec Editors: Brandon Walderman (Microsoft), Khushal Sagar (Google), Dominic Farolino (Google)
  • Original Explainer Team: Brandon Walderman, Leo Lee, Andrew Nolan (Microsoft); David Bokan, Khushal Sagar, Hannah Van Opstal (Google)
  • MCP Creators: David Soria Parra and Justin Spahr-Summers (Anthropic) for the Model Context Protocol
  • Chrome Tooling: François Beaufort for the Model Context Tool Inspector; GoogleChromeLabs for webmcp-tools
  • Early Implementers: Alex Nahas (@MiguelsPizza) and Jason McGhee (@jasonjmcghee) for sharing implementation experience that informed the spec

This is an independent implementation -- not affiliated with or endorsed by Google, Microsoft, Anthropic, or the W3C. See ACKNOWLEDGMENTS.md for full details.

Contributing

See CONTRIBUTING.md for development setup, coding conventions, and pull request guidelines.

License

Apache 2.0 -- RAPHATECH OU

Top categories

Loading Svelte Themes