Getting Started With WebMCP: Make Your Website Agent-Ready in 15 Minutes

A practical guide to WebMCP — the W3C standard that turns your website into a structured tool for AI agents. Two HTML attributes. Zero JavaScript required.

March 8, 2026

Getting Started With WebMCP: Make Your Website Agent-Ready in 15 Minutes

Google and Microsoft just shipped something that changes how AI agents interact with the web. It's called WebMCP, it's a W3C standard, and you can start using it today with two HTML attributes.

This guide covers everything: the declarative API for quick wins, the imperative API for senior engineers who want full control, a Nuxt/Vue integration pattern, and why your CEO should care about this before your competitors figure it out.


What WebMCP Actually Is

WebMCP (Web Model Context Protocol) is a browser-native API that lets your website expose structured tools to AI agents. Instead of agents scraping your DOM, parsing screenshots, or guessing what buttons do — they call your tools directly with typed parameters and get structured responses.

Think of it as an API for the browser tab.

Before WebMCP: An AI agent takes a 2,000-token screenshot of your page, tries to OCR the text, guesses which element is a search box, attempts to type into it, hopes the CSS selector hasn't changed since last week.

After WebMCP: The agent calls searchProducts({ query: "wireless headphones", maxPrice: 150 }) and gets back a structured JSON response. 20 tokens. Instant.

That's an 89% reduction in token usage and it works even when you redesign your UI.

The Business Translation

For the executives reading this: WebMCP means your website shows up in AI agent workflows. When a customer tells ChatGPT "find me a web design agency that does AI work," the agent doesn't just read your homepage — it can interact with your site. Search your services. Check availability. Start a conversation. The sites that expose these tools get used. The ones that don't get skipped.


The Two-Attribute Version (Declarative API)

You already have HTML forms. You're about to make them agent-readable.

Before

<form action="/api/contact" method="POST">
  <input name="name" type="text" required />
  <input name="email" type="email" required />
  <select name="service">
    <option value="ai">AI Solutions</option>
    <option value="design">Web Design</option>
    <option value="marketing">Digital Marketing</option>
  </select>
  <textarea name="message"></textarea>
  <button type="submit">Send</button>
</form>

After

<form action="/api/contact" method="POST"
      toolname="request_consultation"
      tooldescription="Request a free consultation with Pfaff Digital about AI, design, or marketing services">
  <input name="name" type="text" required
         toolparamdescription="Full name of the person requesting consultation" />
  <input name="email" type="email" required
         toolparamdescription="Email address for follow-up" />
  <select name="service"
          toolparamdescription="Which service area: AI solutions, web design, or digital marketing">
    <option value="ai">AI Solutions</option>
    <option value="design">Web Design</option>
    <option value="marketing">Digital Marketing</option>
  </select>
  <textarea name="message"
            toolparamdescription="Brief description of the project or question"></textarea>
  <button type="submit">Send</button>
</form>

That's it. Two attributes on the form (toolname, tooldescription). One attribute per input (toolparamdescription). The browser automatically generates a JSON schema from the form's types, validation rules, and required attributes. The agent sees a structured tool and knows exactly how to use it.

The human stays in the loop by default. When an agent invokes a declarative tool, the browser brings the form into focus, populates the fields visually, and waits for the user to confirm. You can override this with toolautosubmit="true" for read-only operations like search — but never for actions that modify data.


The JavaScript Version (Imperative API)

For anything beyond simple form submissions — stateful interactions, multi-step workflows, API calls, conditional logic — you need the imperative API.

if ('modelContext' in navigator) {
  navigator.modelContext.registerTool({
    name: 'search_services',
    description: 'Search available services and get details including pricing ranges and typical timelines',
    inputSchema: {
      type: 'object',
      properties: {
        query: {
          type: 'string',
          description: 'What the business needs help with'
        },
        category: {
          type: 'string',
          enum: ['ai', 'design', 'marketing', 'all'],
          description: 'Service category to filter by'
        }
      },
      required: ['query']
    },
    annotations: {
      readOnlyHint: true
    },
    async execute({ query, category }) {
      const results = await fetch(`/api/services?q=${query}&cat=${category || 'all'}`);
      const data = await results.json();
      return {
        content: [{
          type: 'text',
          text: JSON.stringify(data)
        }]
      };
    }
  });
}

Key Details for Senior Engineers

The annotations object controls security behavior. readOnlyHint: true tells the browser this tool doesn't modify state, which may allow agents to invoke it without user confirmation. Always set this for search and query operations. Omit it for anything that writes data.

The execute function receives two arguments: input (the typed parameters) and client (a ModelContextClient object). The client gives you access to requestUserInteraction():

async execute(input, client) {
  const confirmed = await client.requestUserInteraction(async () => {
    return showConfirmationDialog({
      action: 'Schedule a discovery call',
      details: input
    });
  });
  
  if (!confirmed) {
    return { content: [{ type: 'text', text: '{"status":"cancelled"}' }] };
  }
  
  // Proceed with the action
}

This pattern is critical for any destructive or transactional operation. The agent pauses, the browser shows your UI, the human confirms or cancels. Full audit trail.

Tool lifecycle management: Use unregisterTool('tool_name') when context changes — for example, when a user navigates to a different section of your SPA. In a component-based framework, register on mount, unregister on unmount.


The Vue/Nuxt Pattern

Here's a composable that handles registration and cleanup:

// composables/useWebMCPTool.ts
import type { Ref } from 'vue'

interface WebMCPTool {
  name: string
  description: string
  inputSchema: Record<string, unknown>
  annotations?: { readOnlyHint?: boolean }
  execute: (input: any, client?: any) => Promise<{ content: Array<{ type: string; text: string }> }>
}

export function useWebMCPTool(tool: WebMCPTool | Ref<WebMCPTool | null>) {
  const registered = ref(false)

  const register = async () => {
    if (!import.meta.client) return
    if (!('modelContext' in navigator)) return

    const t = unref(tool)
    if (!t) return

    try {
      await (navigator as any).modelContext.registerTool(t)
      registered.value = true
    } catch (e) {
      console.warn(`[WebMCP] Failed to register tool "${t.name}":`, e)
    }
  }

  const unregister = async () => {
    if (!registered.value) return
    const t = unref(tool)
    if (!t) return

    try {
      await (navigator as any).modelContext.unregisterTool(t.name)
      registered.value = false
    } catch (e) {
      // Tool may already be unregistered
    }
  }

  onMounted(register)
  onBeforeUnmount(unregister)

  return { registered }
}

Use it in any component:

<script setup lang="ts">
useWebMCPTool({
  name: 'get_portfolio',
  description: 'Get recent project examples with descriptions and outcomes',
  inputSchema: {
    type: 'object',
    properties: {
      category: {
        type: 'string',
        enum: ['ai', 'design', 'marketing'],
        description: 'Filter projects by service category'
      }
    }
  },
  annotations: { readOnlyHint: true },
  async execute({ category }) {
    const projects = await $fetch('/api/projects', { params: { category } })
    return {
      content: [{ type: 'text', text: JSON.stringify(projects) }]
    }
  }
})
</script>

Clean, composable, and the tool exists exactly as long as the component does.


What to Implement First

Week 1 — Read-only tools (lowest risk, highest signal):

  • Site search
  • Service/product catalog lookup
  • Store/office locator
  • FAQ query

Week 2 — Existing forms:

  • Contact forms
  • Newsletter signup
  • Quote request
  • Support ticket submission

Week 3 — Complex workflows:

  • Multi-step booking
  • Custom quote builder
  • Onboarding wizard

Start with readOnlyHint: true tools. No state changes, no risk, immediate value.


Security: The Non-Negotiable Checklist

WebMCP is still a DevTrial. The API surface will change. But these security principles won't:

  1. Never expose admin actions without requestUserInteraction()
  2. Validate all inputs as untrusted — agent-provided parameters are user input
  3. Set readOnlyHint accurately — lying about it breaks trust with the browser
  4. Keep tool count under 50 per page — focus on high-value interactions
  5. Log agent invocationsSubmitEvent.agentInvoked lets you distinguish human from agent submissions server-side
  6. HTTPS only — WebMCP APIs are restricted to secure contexts

The Competitive Angle

Here's the part your CEO needs to hear:

AI agents are becoming a traffic source. When a potential customer asks Claude "find me someone who builds custom AI applications," the agent navigates to websites. The sites with WebMCP tools get interacted with — the agent can search services, check case studies, and initiate contact. The sites without WebMCP get a quick text scrape and maybe a mention.

This is the SEO equivalent of structured data circa 2015. The early adopters got rich snippets while everyone else wondered why their click-through rates were dropping. WebMCP is the structured data of the agent era.

The window is now. Chrome 146 hits stable around March 2026. The developers who build familiarity with navigator.modelContext today will be ready. Everyone else will be reading tutorials later.


Try It Live

We built an interactive WebMCP demo that shows exactly what an AI agent sees when it visits an agent-ready page. It renders the tool registry in real time, shows the JSON schema the browser generates, and lets you invoke tools manually.

Try the WebMCP Demo →


Resources