webmcp-builder
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWebMCP Tool Development Guide
WebMCP 工具开发指南
Overview
概述
WebMCP is a browser API that lets web developers expose their application's functionality as "tools" — JavaScript functions with natural language descriptions and structured schemas — that AI agents, browser assistants, and assistive technologies can invoke. Think of it as turning a web page into an MCP server, but the tools run in client-side JavaScript instead of on a backend.
The key insight: WebMCP enables collaborative, human-in-the-loop workflows where users and agents work together within the same web interface. The user stays in control, the UI updates in real time, and the agent gets structured access to app functionality instead of having to scrape or automate the UI.
WebMCP also benefits accessibility — users with accessibility needs can complete tasks via conversational or agentic interfaces instead of relying solely on the accessibility tree, which many websites haven't fully implemented. See Accessibility-Focused Tool Design for concrete patterns.
WebMCP aligns closely with MCP tool schemas (, , , ), so developers familiar with MCP can reuse their knowledge. The key difference: WebMCP tools run client-side in the browser, not on a backend server. The browser intermediates between the page and the agent, which allows it to enforce security policies and maintain backwards compatibility as MCP evolves. For always-on server-to-server tool access without a browser, use a traditional MCP server instead.
namedescriptioninputSchemaexecuteWebMCP是一款浏览器API,允许Web开发者将其应用的功能封装为「工具」——即带有自然语言描述和结构化Schema的JavaScript函数,AI Agent、浏览器助手及辅助技术均可调用这些工具。你可以把它理解为将网页转变为MCP服务器,但工具运行在客户端JavaScript中,而非后端服务器。
核心亮点:WebMCP支持协作式的人在环工作流,用户与Agent可在同一Web界面内协同工作。用户始终保持控制权,UI实时更新,Agent能以结构化方式访问应用功能,无需通过爬取或自动化UI来实现操作。
WebMCP还对可访问性有帮助——有访问需求的用户可通过对话式或Agent驱动的界面完成任务,无需完全依赖许多网站尚未充分实现的可访问性树。具体模式可参考面向可访问性的工具设计。
WebMCP与MCP工具Schema(、、、)高度对齐,熟悉MCP的开发者可复用已有知识。核心区别在于:WebMCP工具运行在浏览器客户端,而非后端服务器。浏览器作为页面与Agent之间的中间层,可执行安全策略,并在MCP演进时保持向后兼容性。如果需要无需浏览器的持续服务器对服务器工具访问,请使用传统MCP服务器。
namedescriptioninputSchemaexecuteQuick Start
快速开始
Here's a minimal, complete WebMCP tool — feature detect, register, execute, and return a result:
js
// Check if the browser supports WebMCP
if ("modelContext" in navigator) {
navigator.modelContext.registerTool({
name: "greet_user",
description: "Returns a personalized greeting for the given name.",
inputSchema: {
type: "object",
properties: {
name: { type: "string", description: "The person's name" }
},
required: ["name"]
},
execute: ({ name }) => {
document.getElementById("greeting").textContent = `Hello, ${name}!`;
return `Greeted ${name} successfully.`;
}
});
}This covers the four essentials: feature detection (), tool registration (), execution logic (update the DOM), and an informative return value. Everything below expands on this pattern.
"modelContext" in navigatorregisterTool以下是一个完整的极简WebMCP工具示例——包含特性检测、注册、执行及结果返回:
js
// 检查浏览器是否支持WebMCP
if ("modelContext" in navigator) {
navigator.modelContext.registerTool({
name: "greet_user",
description: "Returns a personalized greeting for the given name.",
inputSchema: {
type: "object",
properties: {
name: { type: "string", description: "The person's name" }
},
required: ["name"]
},
execute: ({ name }) => {
document.getElementById("greeting").textContent = `Hello, ${name}!`;
return `Greeted ${name} successfully.`;
}
});
}这个示例涵盖了四个核心要点:特性检测()、工具注册()、执行逻辑(更新DOM)以及信息丰富的返回值。下文将基于此模式展开详细说明。
"modelContext" in navigatorregisterToolProcess
开发流程
Phase 1: Understand the Requirements
阶段1:明确需求
Before writing any code, clarify what the web app needs to expose to agents:
- What actions should agents be able to perform? List the core operations (e.g., "add item", "search", "filter results", "submit form").
- What data should agents be able to read? Identify read-only queries (e.g., "get current state", "list items").
- Does the tool set change based on UI state? Single-page apps may need to register/unregister tools as the user navigates between views.
- What user interactions need confirmation? Destructive or irreversible actions (purchases, deletions) should use .
agent.requestUserInteraction()
Guiding questions to ask before coding:
- What existing JavaScript functions already do what you need? (Wrap them — don't rewrite.)
- What's the app's framework? (Vanilla JS, React, Vue, etc. — this determines the UI sync pattern.)
- Are there form validations or business rules that tools must respect?
- What data is sensitive and should NOT be exposed as tool parameters?
- Will the app be served over HTTPS in production? (Some browsers restrict to secure contexts.)
modelContext
编写代码前,先理清Web应用需要向Agent开放哪些功能:
- Agent应能执行哪些操作? 列出核心操作(例如:「添加项目」「搜索」「筛选结果」「提交表单」)。
- Agent应能读取哪些数据? 确定只读查询(例如:「获取当前状态」「列出项目」)。
- 工具集是否随UI状态变化? 单页应用可能需要在用户切换视图时注册/注销工具。
- 哪些用户操作需要确认? 破坏性或不可逆操作(如购买、删除)应使用。
agent.requestUserInteraction()
编码前需思考的引导问题:
- 现有JavaScript函数中已有哪些能实现所需功能?(直接封装——无需重写。)
- 应用使用的框架是什么?(原生JS、React、Vue等——这决定了UI同步模式。)
- 是否存在工具必须遵守的表单验证规则或业务逻辑?
- 哪些敏感数据不应作为工具参数暴露?
- 生产环境中应用是否通过HTTPS提供服务?(部分浏览器仅在安全上下文环境中允许使用。)
modelContext
Phase 2: Design the Tools
阶段2:工具设计
Good WebMCP tools share these qualities:
- Action-oriented names: Use verb-noun format like ,
add_item,search_flights. Kebab-case (set_filters) or snake_case (add-item) are both acceptable — pick one and be consistent.add_item - Clear descriptions: The description is what the agent reads to decide whether to use the tool. Be specific about what the tool does, what it returns, and any constraints.
- Minimal required parameters: Only mark parameters as required if the tool truly cannot function without them. Use sensible defaults for optional parameters.
- Structured input schemas: Use JSON Schema (,
type,properties,required,enum) so agents know exactly what to pass.description - Informative return values: Return text or structured content that tells the agent what happened. Include enough context for the agent to decide what to do next.
优秀的WebMCP工具具备以下特质:
- 面向动作的命名:使用动词-名词格式,如、
add_item、search_flights。短横线分隔(set_filters)或下划线分隔(add-item)均可——选择一种并保持一致。add_item - 清晰的描述:描述是Agent判断是否使用该工具的依据。需明确说明工具的功能、返回内容及任何约束条件。
- 最少必填参数:仅将工具真正不可或缺的参数标记为必填项。为可选参数设置合理默认值。
- 结构化输入Schema:使用JSON Schema(、
type、properties、required、enum),让Agent明确知晓需传入的参数格式。description - 信息丰富的返回值:返回文本或结构化内容,告知Agent操作结果。需包含足够上下文,以便Agent决定下一步操作。
Bad vs. Good Examples
反面与正面示例
Tool naming:
- ❌ — vague, agent can't tell what it does
data - ✅ — specific, action-oriented
get_cart_contents
Descriptions:
- ❌ — agent has no idea what to expect
"Does stuff with the form" - ✅ — agent knows inputs, outputs, and failure modes
"Submits the contact form with the given name, email, and message. Returns a confirmation ID or validation errors."
Parameters:
- ❌ Requiring and
user_emailon a search tool that doesn't need themuser_location - ✅ Only requiring , with optional
querydefaulting to 10max_results
工具命名:
- ❌ ——表述模糊,Agent无法判断其功能
data - ✅ ——表述具体,面向动作
get_cart_contents
描述:
- ❌ ——Agent完全无法预期结果
"Does stuff with the form" - ✅ ——Agent清楚了解输入、输出及失败场景
"Submits the contact form with the given name, email, and message. Returns a confirmation ID or validation errors."
参数:
- ❌ 搜索工具要求传入和
user_email,但实际并不需要user_location - ✅ 仅要求传入,可选参数
query默认值为10max_results
Tool Granularity
工具粒度
Balance between too many fine-grained tools and too few coarse ones:
- Too fine: ,
set_font_size,set_font_color→ agent needs many calls for simple tasksset_font_family - Too coarse: → agent can't predict behavior, errors are vague
do_everything(instructions) - Right level: for creative apps, or individual CRUD tools for data apps
edit_design(instructions)
When in doubt, start with one tool per user-facing action (each button, form submission, or filter corresponds to a tool).
需在过多细粒度工具与过少粗粒度工具之间找到平衡:
- 过细:、
set_font_size、set_font_color→Agent完成简单任务需多次调用set_font_family - 过粗:→Agent无法预测行为,错误信息模糊
do_everything(instructions) - 合适粒度:创意应用使用,数据应用使用独立的CRUD工具
edit_design(instructions)
拿不定主意时,先为每个用户可见的操作(每个按钮、表单提交或筛选器)对应一个工具。
Phase 3: Implement
阶段3:实现开发
Project Structure
项目结构
WebMCP tools live in your web app's frontend code. A typical organization:
my-app/
├── index.html
├── style.css
├── script.js # App logic + WebMCP tool registrationFor larger apps, separate WebMCP code into its own module:
my-app/
├── index.html
├── style.css
├── script.js # App logic
├── webmcp.ts # WebMCP tool definitions and registrationWebMCP工具位于Web应用的前端代码中。典型的组织方式如下:
my-app/
├── index.html
├── style.css
├── script.js # 应用逻辑 + WebMCP工具注册对于大型应用,可将WebMCP代码分离到独立模块:
my-app/
├── index.html
├── style.css
├── script.js # 应用逻辑
├── webmcp.ts # WebMCP工具定义与注册Complete Minimal Tool
完整极简工具示例
Here's a complete tool you can copy-paste as a starting point — it includes feature detection, registration, execution with error handling, and an informative return value:
js
window.addEventListener('load', () => {
if ("modelContext" in navigator) {
navigator.modelContext.registerTool({
name: "add_todo",
description: "Add a new todo item to the list. Returns confirmation with the current item count.",
inputSchema: {
type: "object",
properties: {
text: { type: "string", description: "The text of the todo item" }
},
required: ["text"]
},
annotations: {
readOnlyHint: false,
idempotentHint: false
},
execute: ({ text }) => {
if (!text.trim()) {
return "Error: Todo text cannot be empty.";
}
addTodo(text); // Call your existing app function
renderTodoList(); // Update the UI
return `Added todo: "${text}". You now have ${getTodoCount()} items.`;
}
});
}
});以下是一个可直接复制使用的完整工具示例——包含特性检测、注册、带错误处理的执行逻辑及信息丰富的返回值:
js
window.addEventListener('load', () => {
if ("modelContext" in navigator) {
navigator.modelContext.registerTool({
name: "add_todo",
description: "Add a new todo item to the list. Returns confirmation with the current item count.",
inputSchema: {
type: "object",
properties: {
text: { type: "string", description: "The text of the todo item" }
},
required: ["text"]
},
annotations: {
readOnlyHint: false,
idempotentHint: false
},
execute: ({ text }) => {
if (!text.trim()) {
return "Error: Todo text cannot be empty.";
}
addTodo(text); // 调用现有应用函数
renderTodoList(); // 更新UI
return `Added todo: "${text}". You now have ${getTodoCount()} items.`;
}
});
}
});The WebMCP API
WebMCP API
The API lives on . Always feature-detect before using it, and always do so inside a callback — never at the top level of a script. Browser extensions and runtimes that inject do so during or after page load; checking too early will always find it missing.
navigator.modelContextwindow.addEventListener('load', ...)navigator.modelContext⚠️ HTTP required:is only available when the page is served over HTTP or HTTPS (e.g.navigator.modelContext). It will not be injected onhttp://localhost:8080URLs. Always run a local dev server during development.file://
js
window.addEventListener('load', () => {
if ("modelContext" in navigator) {
// WebMCP is supported — register tools here
}
});There are two registration approaches:
Approach 1: (batch registration)
provideContextRegisters all tools at once. Calling it again replaces all previously registered tools. Good for simple apps or when the full tool set is known upfront.
js
navigator.modelContext.provideContext({
tools: [
{
name: "add-todo",
description: "Add a new todo item to the list",
inputSchema: {
type: "object",
properties: {
text: { type: "string", description: "The text of the todo item" }
},
required: ["text"]
},
execute: ({ text }, agent) => {
addTodo(text);
return {
content: [
{ type: "text", text: `Added todo: "${text}"` }
]
};
}
}
]
});Approach 2: / (incremental)
registerToolunregisterToolAdd or remove individual tools. Better for SPAs where available tools change based on UI state.
js
navigator.modelContext.registerTool({
name: "search_flights",
description: "Search for flights with the given parameters.",
inputSchema: {
type: "object",
properties: {
origin: {
type: "string",
description: "3-letter IATA airport code for origin",
pattern: "^[A-Z]{3}$"
},
destination: {
type: "string",
description: "3-letter IATA airport code for destination",
pattern: "^[A-Z]{3}$"
}
},
required: ["origin", "destination"]
},
execute: async ({ origin, destination }) => {
const results = await searchFlights(origin, destination);
return `Found ${results.length} flights from ${origin} to ${destination}.`;
}
});
// Later, when navigating away from search:
navigator.modelContext.unregisterTool("search_flights");该API位于对象上。使用前务必先进行特性检测,且必须在回调中执行——绝不能在脚本顶层执行。注入的浏览器扩展和运行时会在页面加载期间或之后完成注入;过早检测会始终返回未找到。
navigator.modelContextwindow.addEventListener('load', ...)navigator.modelContext⚠️ 需HTTP环境:仅在页面通过HTTP或HTTPS提供服务时可用(例如navigator.modelContext)。在http://localhost:8080协议的URL下无法注入。开发期间请始终运行本地开发服务器。file://
js
window.addEventListener('load', () => {
if ("modelContext" in navigator) {
// WebMCP已支持——在此注册工具
}
});有两种注册方式:
方式1:(批量注册)
provideContext一次性注册所有工具。再次调用会替换之前注册的所有工具。适用于简单应用或预先知晓完整工具集的场景。
js
navigator.modelContext.provideContext({
tools: [
{
name: "add-todo",
description: "Add a new todo item to the list",
inputSchema: {
type: "object",
properties: {
text: { type: "string", description: "The text of the todo item" }
},
required: ["text"]
},
execute: ({ text }, agent) => {
addTodo(text);
return {
content: [
{ type: "text", text: `Added todo: "${text}"` }
]
};
}
}
]
});方式2: / (增量注册)
registerToolunregisterTool添加或移除单个工具。更适用于单页应用,此类应用中可用工具会随UI状态变化。
js
navigator.modelContext.registerTool({
name: "search_flights",
description: "Search for flights with the given parameters.",
inputSchema: {
type: "object",
properties: {
origin: {
type: "string",
description: "3-letter IATA airport code for origin",
pattern: "^[A-Z]{3}$"
},
destination: {
type: "string",
description: "3-letter IATA airport code for destination",
pattern: "^[A-Z]{3}$"
}
},
required: ["origin", "destination"]
},
execute: async ({ origin, destination }) => {
const results = await searchFlights(origin, destination);
return `Found ${results.length} flights from ${origin} to ${destination}.`;
}
});
// 后续离开搜索页面时:
navigator.modelContext.unregisterTool("search_flights");Tool Definition Shape
工具定义结构
Each tool object has these fields:
| Field | Required | Description |
|---|---|---|
| Yes | Unique identifier for the tool |
| Yes | Natural language description of what the tool does |
| Yes | JSON Schema object describing the parameters |
| Yes | Function |
| No | JSON Schema describing the return value structure |
| No | Hints like |
每个工具对象包含以下字段:
| 字段 | 是否必填 | 描述 |
|---|---|---|
| 是 | 工具的唯一标识符 |
| 是 | 工具功能的自然语言描述 |
| 是 | 描述参数的JSON Schema对象 |
| 是 | 实现工具功能的函数,格式为 |
| 否 | 描述返回值结构的JSON Schema |
| 否 | 提示信息,如 |
The execute
Function
executeexecute
函数
executeThe execute function receives two arguments:
- : An object with the parameters the agent passed, matching your
params.inputSchema - : An interface for interacting with the agent during execution.
agent
It can be synchronous or async (return a Promise). The return value is sent back to the agent.
Return formats:
js
// Simple text response
execute: ({ query }) => {
return `Found 5 results for "${query}"`;
}
// Structured content response (MCP-aligned)
execute: ({ name }) => {
return {
content: [
{ type: "text", text: `Item "${name}" created successfully.` }
]
};
}
// Return data for the agent to process
execute: () => {
return JSON.stringify(getAppState());
}execute函数接收两个参数:
- :Agent传入的参数对象,与你定义的
params匹配。inputSchema - :执行期间与Agent交互的接口。
agent
函数可以是同步或异步(返回Promise)。返回值将发送回Agent。
返回格式:
js
// 简单文本响应
execute: ({ query }) => {
return `Found 5 results for "${query}"`;
}
// 结构化内容响应(与MCP对齐)
execute: ({ name }) => {
return {
content: [
{ type: "text", text: `Item "${name}" created successfully.` }
]
};
}
// 返回供Agent处理的数据
execute: () => {
return JSON.stringify(getAppState());
}Recommended Return Format
推荐返回格式
✅ Recommended: always include a field and the new device state.
successReturning a plain string (e.g. ) is valid, but some agents treat an
ambiguous response as a potential error. To give the agent unambiguous confirmation,
return a JSON-stringified object with:
"Light turned on."- — explicit boolean indicating whether the action succeeded.
success: true/false - — human-readable description of what happened.
message - — the updated state of the device(s) affected by the call, so the agent can verify the outcome without a follow-up
new_statecall.get_* - On failure, include instead of
error.new_state
js
// ✅ Success — clear confirmation + updated state
execute: ({ light_id, action }) => {
state.lights[light_id].on = (action === 'on');
renderLight(light_id);
return JSON.stringify({
success: true,
message: `${light_id} light turned ${action}.`,
new_state: { light_id, on: state.lights[light_id].on },
});
}
// ✅ Failure — explicit flag so the agent knows to retry or report
execute: ({ light_id, action }) => {
if (!VALID_IDS.includes(light_id)) {
return JSON.stringify({
success: false,
error: `Unknown light_id "${light_id}". Valid options: ${VALID_IDS.join(', ')}.`,
});
}
// ...
}For tools that affect multiple devices at once (e.g. a scene), include the full
post-action snapshot in so the agent doesn't need a separate status read.
new_state✅ 推荐:始终包含字段和新的设备状态。
success返回纯字符串(例如)是有效的,但部分Agent会将模糊响应视为潜在错误。为给Agent明确的确认信息,建议返回JSON字符串化的对象,包含:
"Light turned on."- —— 明确的布尔值,指示操作是否成功。
success: true/false - —— 人类可读的操作结果描述。
message - —— 受调用影响的设备的更新状态,以便Agent无需后续调用
new_state接口即可验证结果。get_* - 失败时,用****字段替代
error。new_state
js
// ✅ 成功——明确的确认信息 + 更新后的状态
execute: ({ light_id, action }) => {
state.lights[light_id].on = (action === 'on');
renderLight(light_id);
return JSON.stringify({
success: true,
message: `${light_id} light turned ${action}.`,
new_state: { light_id, on: state.lights[light_id].on },
});
}
// ✅ 失败——明确的标志,让Agent知晓需重试或上报错误
execute: ({ light_id, action }) => {
if (!VALID_IDS.includes(light_id)) {
return JSON.stringify({
success: false,
error: `Unknown light_id "${light_id}". Valid options: ${VALID_IDS.join(', ')}.`,
});
}
// ...
}对于影响多个设备的工具(例如场景控制工具),请在中包含操作后的完整快照,这样Agent无需单独调用状态读取接口。
new_stateUser Interaction During Tool Execution
工具执行期间的用户交互
For actions that need user confirmation, use :
agent.requestUserInteraction()js
execute: async ({ product_id }, agent) => {
const confirmed = await agent.requestUserInteraction(async () => {
return new Promise((resolve) => {
const ok = confirm(`Purchase product ${product_id}?`);
resolve(ok);
});
});
if (!confirmed) {
throw new Error("Purchase cancelled by user.");
}
executePurchase(product_id);
return `Product ${product_id} purchased.`;
}对于需要用户确认的操作,使用:
agent.requestUserInteraction()js
execute: async ({ product_id }, agent) => {
const confirmed = await agent.requestUserInteraction(async () => {
return new Promise((resolve) => {
const ok = confirm(`Purchase product ${product_id}?`);
resolve(ok);
});
});
if (!confirmed) {
throw new Error("Purchase cancelled by user.");
}
executePurchase(product_id);
return `Product ${product_id} purchased.`;
}Annotations
注释信息
Annotations help agents understand tool behavior without reading the implementation:
js
annotations: {
readOnlyHint: true, // Tool only reads data, no side effects
destructiveHint: false, // Tool doesn't delete or irreversibly modify data
idempotentHint: true, // Calling multiple times with same args has same effect
openWorldHint: false // Tool doesn't interact with external systems
}⚠️ Annotation values must be booleans (/true), not strings (false/"true"). Passing strings will cause a runtime validation error ("false",expected: "boolean").code: "invalid_type"
注释信息可帮助Agent无需阅读实现代码即可理解工具行为:
js
annotations: {
readOnlyHint: true, // 工具仅读取数据,无副作用
destructiveHint: false, // 工具不会删除或不可逆地修改数据
idempotentHint: true, // 使用相同参数多次调用,结果一致
openWorldHint: false // 工具不与外部系统交互
}⚠️ 注释值必须为布尔值(/true),而非字符串(false/"true")。传入字符串会导致运行时验证错误("false",expected: "boolean")。code: "invalid_type"
Advanced Patterns
高级模式
For advanced implementation details, please see Advanced Patterns. Topics include:
- Choosing a UI Synchronization pattern (Direct DOM, Custom Events, Framework State) — with a decision guide
- Dynamic Tool Registration for SPAs
- Error Handling Patterns (DOM not found, network failure, invalid state, timeout)
- Useful tips (Web Workers, event, returning
toolactivated)outputSchema
如需了解高级实现细节,请查看高级模式。涵盖主题包括:
- UI同步模式选择(直接DOM操作、自定义事件、框架状态)——含决策指南
- 单页应用的动态工具注册
- 错误处理模式(未找到DOM、网络故障、无效状态、超时)
- 实用技巧(Web Workers、事件、返回
toolactivated)outputSchema
Phase 4: Testing and Validation
阶段4:测试与验证
Manual Testing Checklist
手动测试清单
Verify these before moving to automated evals:
- Feature detection: App works normally when is undefined (browsers without WebMCP support)
navigator.modelContext - HTTP server: App is served over or
http://, nothttps://file:// - Load event: Tool registration is deferred to
window.addEventListener('load', ...) - Annotation types: All annotation values are booleans (/
true), not stringsfalse - Tool schema validation: accurately describes what
inputSchemaexpects — mismatches cause agent errorsexecute - UI sync: After each tool call, the UI visually reflects the change
- Return values: Every returns a JSON object with
execute, asuccess: true/false, andmessage(ornew_state) so the agent gets unambiguous confirmation — avoid returning plain strings that agents may misinterpret as errorserror - Error handling: Tools return for invalid inputs, not unhandled exceptions or bare error strings
{ success: false, error: "..." } - Edge cases: Test with missing optional parameters, empty strings, boundary values
- Optional parameter defaults: Call tools with only required parameters — defaults should apply correctly
- Destructive actions: Confirm is used for purchases, deletions, etc.
requestUserInteraction() - Multiple calls: Calling the same tool twice in a row doesn't break state
在进行自动化评估前,先验证以下内容:
- 特性检测:当未定义时(不支持WebMCP的浏览器),应用仍能正常运行
navigator.modelContext - HTTP服务器:应用通过或
http://提供服务,而非https://file:// - 加载事件:工具注册延迟至回调中执行
window.addEventListener('load', ...) - 注释类型:所有注释值均为布尔值(/
true),而非字符串false - 工具Schema验证:准确描述
inputSchema函数所需参数——不匹配会导致Agent错误execute - UI同步:每次工具调用后,UI可直观反映变化
- 返回值:每个函数均返回包含
execute、success: true/false及message(或new_state)的JSON对象,为Agent提供明确的确认信息——避免返回可能被Agent误判为错误的纯字符串error - 错误处理:工具对无效输入返回,而非未处理的异常或纯错误字符串
{ success: false, error: "..." } - 边界情况:测试缺失可选参数、空字符串、边界值等场景
- 可选参数默认值:仅传入必填参数调用工具——默认值应正确生效
- 破坏性操作:购买、删除等操作已使用确认
requestUserInteraction() - 多次调用:连续两次调用同一工具不会破坏应用状态
Automated Evaluation
自动化评估
Use the WebMCP Evals CLI to test tool selection against AI agents. Write eval cases with natural language prompts and expected tool calls, then run them against your tool schema. For detailed setup and usage, see Testing WebMCP Tools.
使用WebMCP Evals CLI测试AI Agent的工具选择能力。编写包含自然语言提示和预期工具调用的评估用例,然后针对你的工具Schema运行测试。如需详细设置和使用说明,请查看测试WebMCP工具。
Reference
参考文档
Building
开发相关
- Advanced WebMCP Patterns — UI synchronization, SPA routing, error handling, patterns & tips
- Simple vanilla JS examples — Pizza maker, restaurant booking, complete end-to-end example, accessibility patterns
- React/TypeScript example — Flight search app with dynamic tool registration, complete component example
- WebMCP高级模式——UI同步、单页应用路由、错误处理、模式与技巧
- 原生JS简单示例——披萨制作器、餐厅预订、完整端到端示例、可访问性模式
- React/TypeScript示例——带动态工具注册的航班搜索应用、完整组件示例
Quality
质量保障
- Testing guide — Manual checklist and automated evaluation with the Evals CLI
- Security & privacy guide — Prompt injection, output injection walkthrough, over-parameterization, and a pre-ship checklist
- 测试指南——手动测试清单及使用Evals CLI进行自动化评估
- 安全与隐私指南——提示注入、输出注入实战、参数过度暴露、发布前检查清单
Advanced
高级主题
- Service worker patterns — Background tool execution, session management, discovery, and routing
- Service Worker模式——后台工具执行、会话管理、发现与路由