Help us improve
Share bugs, ideas, or general feedback.
From web-ai-skills
Implements and debugs browser WebMCP integrations in JavaScript/TypeScript web apps for exposing imperative or declarative tools via modelContext.
npx claudepluginhub webmaxru/ai-native-dev --plugin web-ai-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/web-ai-skills:webmcpThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Step 1: Identify the browser integration surface**
Guides adding WebMCP to web applications for AI accessibility, LLM UI tools, and MCP browser automation. Covers design principles, tool architecture, and testing workflows.
Sets up WebMCP projects: enables Chrome flags or MCP-B polyfill, scaffolds tool registration via navigator.modelContext, configures dev environment for AI agent tools on new websites.
Converts existing web apps to hybrid MCP Apps that render standalone or inline in MCP hosts, using shared UI code, context detection, and server tool registration.
Share bugs, ideas, or general feedback.
Step 1: Identify the browser integration surface
node scripts/find-webmcp-targets.mjs . to inventory likely frontend files and existing WebMCP markers when a Node runtime is available.package.json, HTML entry point, and framework bootstrap files manually to identify the browser app boundary.Step 2: Choose the WebMCP shape
references/webmcp-reference.md before writing code.references/declarative-api.md when the feature can be expressed as an HTML form flow or needs agent-invoked submit handling.references/compatibility.md when native availability, Chrome preview setup, or draft-versus-preview behavior matters.references/troubleshooting.md when registration, schema serialization, or agent-driven form execution fails.ModelContextClient.requestUserInteraction().Step 3: Implement tool registration
assets/model-context-registry.template.ts and adapt it to the framework, state model, and file layout in the workspace when using the imperative API.const modelContext = document.modelContext || navigator.modelContext; and guard subsequent registration on its presence. Prefer document.modelContext (the current surface) and keep navigator.modelContext only as a fallback for older Chrome 146–149 builds.modelContext.registerTool() using a stable name (1–128 ASCII alphanumeric/_/-/. characters), a positive description, an object inputSchema, and an execute callback.annotations.readOnlyHint to true only for tools that do not modify state.annotations.untrustedContentHint to true when the tool's output may contain data from untrusted sources.AbortController whose signal was passed to registerTool(); during the Chrome 148 transition window, also call modelContext.unregisterTool?.() with optional chaining before aborting.<form> with toolname and tooldescription, and let form controls define the parameter surface.toolparamdescription to produce clear parameter descriptions for declarative fields.toolautosubmit only when the page should submit automatically after the agent populates the form.Step 4: Wire agent-driven UX safely
client.requestUserInteraction() instead of bypassing the UI.preventDefault() before respondWith() and return structured validation errors for agent-invoked submits.toolactivated, toolcancel, agentInvoked, and WebMCP form pseudo-classes only behind compatibility-aware UI logic.Step 5: Validate behavior
respondWith() handling.references/compatibility.md before treating runtime failures as application bugs.document.modelContext and navigator.modelContext are missing, confirm the code is running in a secure browser window context and then check the preview requirements in references/compatibility.md.navigator.modelContext is present, the page is running on an older Chrome 146–149 preview build; keep the document.modelContext || navigator.modelContext fallback in place but plan to drop navigator.modelContext once the deprecation window closes.registerTool() throws InvalidStateError, check for duplicate names, empty name or description values, or tool names that exceed 128 characters or contain disallowed characters (only ASCII alphanumeric, _, -, . are allowed).registerTool() throws NotAllowedError, check whether the tools Permissions Policy feature is denied; cross-origin iframes need allow="tools" from the embedding document.registerTool() throws TypeError or JSON serialization errors, replace non-serializable or circular inputSchema values with plain JSON-compatible objects.provideContext, clearContext, or toolparamtitle, treat those surfaces as obsolete for current implementations.references/declarative-api.md and references/troubleshooting.md before changing the tool contract.