WebMCP Implementation Examples
Copy-paste registerTool() patterns for the most common WebMCP use cases: e-commerce, SaaS, content sites, and forms.
The minimal tool
Every tool needs three fields: name, description, and inputSchema. The execute function runs in the browser when the agent calls the tool.
navigator.modelContext.registerTool({
name: "getPageTitle",
description: "Get the title of the current page",
inputSchema: { type: "object", properties: {}, required: [] },
execute: async () => ({ title: document.title })
})E-commerce: add to cart
The most common e-commerce tool. The agent passes a product ID and quantity; the execute function calls your existing cart API or dispatches a DOM event.
navigator.modelContext.registerTool({
name: "addToCart",
description: "Add a product to the shopping cart",
inputSchema: {
type: "object",
properties: {
productId: { type: "string", description: "Product SKU or ID" },
quantity: { type: "number", description: "Number of units", minimum: 1 }
},
required: ["productId", "quantity"]
},
execute: async ({ productId, quantity }) => {
const res = await fetch("/cart/add", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ id: productId, quantity })
})
const data = await res.json()
return { success: res.ok, cartCount: data.item_count }
}
})E-commerce: search products
navigator.modelContext.registerTool({
name: "searchProducts",
description: "Search the product catalogue and return matching items",
inputSchema: {
type: "object",
properties: {
query: { type: "string", description: "Search query" },
maxItems: { type: "number", description: "Max results to return", default: 5 }
},
required: ["query"]
},
execute: async ({ query, maxItems = 5 }) => {
const res = await fetch(`/search?q=${encodeURIComponent(query)}&limit=${maxItems}`)
const data = await res.json()
return {
results: data.products.map(p => ({
id: p.id, title: p.title, price: p.price, url: p.url
}))
}
}
})SaaS: create a record
For authenticated SaaS apps — the execute function runs in the browser using the user's existing session cookies. No token passing required.
navigator.modelContext.registerTool({
name: "createTask",
description: "Create a new task in the current project",
inputSchema: {
type: "object",
properties: {
title: { type: "string", description: "Task title" },
assignee: { type: "string", description: "Assignee username (optional)" },
dueDate: { type: "string", description: "Due date as YYYY-MM-DD (optional)" }
},
required: ["title"]
},
execute: async ({ title, assignee, dueDate }) => {
const res = await fetch("/api/tasks", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title, assignee, due_date: dueDate })
})
const task = await res.json()
return { taskId: task.id, url: task.url }
}
})Content site: search articles
navigator.modelContext.registerTool({
name: "searchArticles",
description: "Search published articles by keyword",
inputSchema: {
type: "object",
properties: {
query: { type: "string", description: "Search keyword" },
maxItems: { type: "number", description: "Max results", default: 3 }
},
required: ["query"]
},
execute: async ({ query, maxItems = 3 }) => {
const res = await fetch(`/api/search?q=${encodeURIComponent(query)}&n=${maxItems}`)
const data = await res.json()
return { articles: data.hits.map(h => ({ title: h.title, url: h.url, excerpt: h.excerpt })) }
}
})Form: newsletter subscribe
Expose subscription forms as tools so agents can complete them without DOM interaction.
navigator.modelContext.registerTool({
name: "subscribeNewsletter",
description: "Subscribe an email address to the newsletter",
inputSchema: {
type: "object",
properties: {
email: { type: "string", format: "email", description: "Email address to subscribe" }
},
required: ["email"]
},
execute: async ({ email }) => {
const res = await fetch("/api/newsletter/subscribe", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email })
})
return { success: res.ok }
}
})Using Aigentably instead of writing this manually
All of the above can be defined in the Aigentably dashboard — no JavaScript to write. You define the tool name, description, input schema fields, and the execute logic (which Aigentably wraps in executeJs), then paste one script tag. The snippet fetches your tool definitions and calls registerTool() automatically.
The benefit: you can update tools without deploying code. Change the inputSchema, update the execute logic, or add new tools — it takes effect the next time the snippet loads.
Related
Add WebMCP to your site in 30 seconds
Define tools in the dashboard. No code to write or deploy.
Get started free