ה-Imperative API משתמש ב-document.modelContext.registerTool() כדי להגדיר באופן פרוגרמטי כלים של JavaScript. האפשרות הזו אידיאלית לאפליקציות דף יחיד (SPA) שבהן צריך להוסיף או להסיר כלים על סמך הנתיב הנוכחי או מצב המשתמש.
WebMCP פועל בארכיטקטורה של יצרן/צרכן:
- דפי אינטרנט הם יצרני כלים: אתם מגדירים ורושמים כלים באמצעות
document.modelContext.registerTool(). זה כל מה שצריך להטמיע בדף אינטרנט. אין צורך להפעיל אתgetTools()או אתexecuteTool()בדף כדי לחשוף כלים לסוכנים. - הצרכנים העיקריים הם סוכנים של דפדפנים ותוספים: סוכנים שסופקו על ידי הדפדפן או דרכו – כולל הסוכן המובנה של הדפדפן, תוספים לדפדפן, כלי פיתוח ועוזרים ברמת המערכת – מגלים ומפעילים כלים רשומים מחוץ לפס באמצעות מנגנוני פלטפורמה פנימיים.
- סוכנים ומסגרות בדיקה שמשולבים בדף:
getTools()ו-executeTool()קיימים במיוחד בשביל עוזרים דיגיטליים של JavaScript שמשולבים בדף (למשל, ווידג'ט צ'אט מוטמע או<iframe>) וחבילות מקרים לבדיקה אוטומטיות שצריכות לגלות כלים ולהפעיל אותם ישירות בהקשר של הדף.
רישום ומחזור חיים
כדי לרשום כלים, מעבירים אובייקט של הגדרת כלי ואובייקט אופציונלי של אפשרויות (ModelContextRegisterToolOptions), שתומך בשני איברים אופציונליים:
-
signal:AbortSignalשמשמש לביטול הרישום של הכלי כשלא צריך אותו יותר. -
exposedTo: מערך של מחרוזות מקור שקובעות לאילו מסמכים בעץ המסמכים מותר לגלות את הכלי ולהפעיל אותו מעבר לגבולות המסגרת.
טיפול במחזור החיים באמצעות AbortController
WebMCP לא מספק שיטת unregisterTool(). כדי לבטל את הרישום של כלי, צריך להעביר AbortSignal במהלך הרישום ולבטל את האות הזה כשכבר לא צריך את הכלי.
const controller = new AbortController();
await document.modelContext.registerTool({
name: "get_user_preferences",
description: "Retrieves the user's saved preferences.",
inputSchema: { type: "object", properties: {} },
execute() {
const prefs = localStorage.getItem("user_prefs");
return prefs ? JSON.parse(prefs) : { theme: "light" };
},
annotations: { readOnlyHint: true }
}, { signal: controller.signal });
// To unregister the tool (e.g., on component unmount):
controller.abort();
ביטול אות הרישום רק מבטל את הרישום של הכלי, ולא מבטל הפעלות שכבר רצות. כלים שמפעילים עבודה שנמשכת זמן רב חייבים גם לכבד את האות לכל הפעלה שמתואר בהמשך, אחרת ביטול הרישום ישאיר בקשות מיותרות ועדכונים לא רלוונטיים בממשק המשתמש.
שליטה בחשיפה של כלים ממקורות שונים באמצעות exposedTo
כברירת מחדל, כלי רשום הוא פרטי למסמך שבו הוא נרשם ולמסגרות מאותו מקור. אם האפליקציה שלכם מוטמעת ב-<iframe> (או מטמיעה ווידג'טים של צד שלישי) ואתם צריכים מסגרות אב או מסגרות אחיות כדי לגלות את הכלי ולהפעיל אותו, ציינו את מקורות המידע המורשים באמצעות exposedTo.
const controller = new AbortController();
await document.modelContext.registerTool({
name: "get_cart_items",
description: "Retrieves items currently in the user's shopping cart.",
inputSchema: { type: "object", properties: {} },
async execute(input, { signal }) {
return await cartService.getItems({ signal });
},
annotations: { readOnlyHint: true },
}, {
signal: controller.signal,
exposedTo: ["https://checkout.example.com"],
});
- הסכמה הדדית: כדי לגלות כלים ממקורות שונים, צריך להביע הסכמה בשני הצדדים. המסגרת של ספק הכלי מאשרת את מקור הצרכן באמצעות
exposedTo, והמסגרת של הצרכן צריכה לבקש במפורש את מקור הספק באמצעותgetTools({ fromOrigins: [...] }). בליfromOrigins,getTools()שולח שאילתות רק למסמכים מאותו מקור. - התאמת מקור: למקור של המסמך שרושם את ה-Service Worker תמיד יש גישה. מקורות שצוינו ב-
exposedToמקבלים הרשאה לגלות את הכלי דרךdocument.modelContext.getTools({ fromOrigins: [...] })ולהפעיל אותו דרךdocument.modelContext.executeTool(). - דרישת אבטחה: כל מקור ב-
exposedToחייב להיות מהימן (HTTPS או localhost). העברה של מקור לא תקין או לא מאובטח גורמת לדחייה שלregisterTool()עםSecurityError. - היקף:
exposedToשולט בגילוי של מסמכים שונים בדף במסגרות בעץ המסמכים.
הגדרת פרמטרים
הפרמטרים מוגדרים באמצעות המאפיין inputSchema. האובייקט הזה חייב להיות אובייקט JSON Schema שמתאר את הנתונים המובְנים שהכלי מצפה לקבל.
await document.modelContext.registerTool({
name: "calculate_area",
description: "Calculates the area of a rectangle.",
inputSchema: {
type: "object",
properties: {
width: { type: "number", description: "The width of the rectangle." },
height: { type: "number", description: "The height of the rectangle." }
},
required: ["width", "height"]
},
execute(input) {
// input is { width: 10, height: 20 }
return input.width * input.height;
},
annotations: { readOnlyHint: true }
});
תיאורים של כלי כתיבה ופרמטרים
הסוכן כבר מקבל את inputSchema המלא, אז בdescription צריך רק לציין מה הכלי עושה ומתי להשתמש בו. אין לחזור על שמות פרמטרים, סוגים, ערכי enum, ברירות מחדל או מגבלות בו; יש להצהיר עליהם בסכימה (enum, default, minimum/maximum) במקום זאת. תיאורי הפרמטרים פועלים לפי אותו כלל: צריך לציין מה המשמעות של הערך, ולא את הסוג שלו או את הערכים המותרים.
הדפדפן לא מאמת את הארגומנטים מול inputSchema ולא מחיל ערכי default, לכן צריך לבצע את שתי הפעולות ב-execute.
const SORT_ORDERS = ["newest", "price_low_to_high"];
await document.modelContext.registerTool({
name: "search_products",
// Don't list the sort orders here, even via SORT_ORDERS: `enum` already does.
description: "Searches the product catalog by keyword. Use when the user wants to find or compare products.",
inputSchema: {
type: "object",
properties: {
query: { type: "string", description: "Words to search for." },
sort: { type: "string", enum: SORT_ORDERS, default: "newest", description: "Order of the results." },
},
required: ["query"],
},
async execute({ query, sort = "newest" }, { signal }) {
if (typeof query !== "string" || !SORT_ORDERS.includes(sort)) {
return { error: "Pass a search query and a supported sort order.", sortOrders: SORT_ORDERS };
}
return await productService.search({ query, sort }, { signal });
},
annotations: { readOnlyHint: true },
});
דפוסי ביצוע
הקריאה החוזרת (callback) של execute תמיד מקבלת שני ארגומנטים: אובייקט הקלט ואובייקט האפשרויות שכולל AbortSignal – execute(inputObject, { signal }).
When to use async execute
משתמשים ב-async כשהכלי כולל פעולות שמחזירות Promise או שלוקח זמן להשלים אותן:
- קריאות לרשת: אחזור נתונים מ-API.
- אחסון אסינכרוני: גישה ל-IndexedDB.
- אירועים חיצוניים: המתנה לשינוי מצב ספציפי או לסיום של אנימציה.
async execute(input, { signal }) {
const response = await fetch(`/api/data/${input.id}`, { signal });
return await response.json();
}
מתי כדאי להשתמש ב-execute (סינכרוני)
לפעולות מיידיות, השתמשו בפונקציה סינכרונית רגילה. כלי סינכרוני פועל עד לסיום לפני שניתן להבחין בביטול, כך שהוא יכול להתעלם מהאות:
- לוגיקה טהורה: מתמטיקה, סינון או מיון של נתונים שכבר נמצאים בזיכרון.
- מצב סינכרוני: קריאה מ-
localStorageאו ממנהל מצב סינכרוני.
execute(input) {
return input.items.filter(item => item.active);
}
טיפול בשגיאות ב-execute
כשהפונקציה execute מחזירה שגיאה (או מחזירה הבטחה שנדחתה), הנציג מקבל רק הודעה כללית על כשל בביצוע. הודעת השגיאה לא מועברת לנציג. אם הכלי שלכם נתקל בשגיאה שניתן לתקן או לשחזר (כמו קלט לא חוקי, פריטים חסרים או סטטוס HTTP שנכשל), אל throw new Error(...). במקום זאת, החזירו מטען ייעודי (payload) מובנה של שגיאה דרך ערך ההחזרה הרגיל של הכלי, כדי שסוכן ה-AI יקבל את פרטי האבחון ויוכל לתקן את עצמו או לנסות שוב:
execute({ itemName }) {
const item = menuItems.find((entry) => entry.name.toLowerCase() === itemName.toLowerCase());
if (!item) {
// Return the error as a value instead of throwing, so the agent receives the message:
return {
error: `Menu item "${itemName}" not found.`,
availableItems: menuItems.map((entry) => entry.name),
};
}
return item;
}
צריך להפעיל מחדש רק כשההפעלה בוטלה (signal.aborted הוא true).
ביטול הרצות פעילות
הביטול מתבצע על ידי המשתמש או הנציג. חובה: כל כלי שמבצע בקשות לאחזור מהרשת או פעולות אסינכרוניות אחרות שנמשכות זמן רב חייב לכבד את signal, אחרת הפעלות שבוטלו ימשיכו לצרוך משאבים ועלולות לכתוב נתונים לא עדכניים בממשק המשתמש אחרי שהנציג עבר הלאה.
- ממשקי API שמקבלים אות (קוראים של
fetch(),addEventListener(),ReadableStream): מעבירים אתsignalישירות. - ממשקי API שלא (
setTimeout,setInterval, לולאות דגימה, צינורות עיבוד נתונים עם הרבהawait): קוראים ל-signal.throwIfAborted()בין השלבים, ו/או דוחים ב-signal.addEventListener('abort', ...). טיימרים לא מקבלים אותות, אז צריך לנקות אותם בעצמכם במאזין לביטול.
await document.modelContext.registerTool({
name: "fetch_tool",
description: "Fetch the text content of a URL and show it on the page.",
inputSchema: {
type: "object",
properties: {
url: { type: "string", description: "The URL to fetch" },
priority: {
type: "string",
enum: ["high", "low", "auto"],
description: "Relative network priority for the request",
},
},
required: ["url"],
},
execute: async ({ url, priority }, { signal }) => {
const output = document.querySelector("pre");
output.textContent = "Loading…";
try {
// Passing `signal` aborts the network request the moment execution is cancelled.
const response = await fetch(url, { priority, signal });
if (!response.ok) {
output.textContent = "";
return { error: `Request failed with status ${response.status}` };
}
const text = await response.text();
output.textContent = text;
return text;
} catch (err) {
// Roll back the UI state this execution set, so a cancelled run leaves no trace.
output.textContent = "";
if (signal.aborted) {
// The execution was cancelled: re-throw instead of returning an error value.
throw err;
}
// Return other errors as a value instead of throwing, so the agent receives the message.
return { error: err instanceof Error ? err.message : String(err) };
}
},
annotations: { readOnlyHint: true }
});
כלים לסימון תוכן שעלול לגרום נזק
החל מגרסה 154 של Chrome, annotations תומך ב-consequentialHint. הגדירו את הערך true לכלים שמבצעים פעולות בעלות סיכון גבוה, בלתי הפיכות או בעולם האמיתי – הזמנת נסיעות, העברת כספים, שליחת הודעות או מחיקת נתונים. הוא מאותת לסוכנים לבקש אישור מפורש מהמשתמש לפני הביצוע.
await document.modelContext.registerTool({
name: 'book_flight',
description: 'Book a flight for the user with confirmed flight details.',
inputSchema: {
type: 'object',
properties: {
flightId: { type: 'string', description: 'ID of the flight to book' },
passengers: { type: 'number', description: 'Number of tickets to purchase' },
},
required: ['flightId', 'passengers'],
},
execute: async ({ flightId, passengers }, { signal }) => {
// Forward `signal` to the transaction API to honor cancellation:
return await bookFlightReservation({ flightId, passengers }, { signal });
},
annotations: {
readOnlyHint: false, // This tool mutates state (it makes a booking).
consequentialHint: true, // Spends money and is not trivially reversible.
untrustedContentHint: false, // Output is first-party data, not third-party content.
}
});
חובה: צריך להתייחס ל-consequentialHint כהצעה, ולא כמנגנון אכיפה. הוא לא חוסם את ההפעלה בעצמו, ודפדפנים שקדמו לרמז לא יציגו הנחיה בכלל. חשוב להשאיר את האישור בתוך האפליקציה שהפעולה כבר מצריכה.
כלים לסימון ולניפוי באגים
החל מגרסה 156 של Chrome, annotations תומך ב-debugging. מגדירים את annotations.debugging לערך true לכלים שמיועדים לניפוי באגים ולמפתחים, ולא למשימות של משתמשי קצה. דוגמאות: העברת מצב פנימי של אפליקציה, החלפת מצב של feature flags או הוספת נתוני בדיקה. כך הסוכנים יכולים להבחין בין כלים שמיועדים למפתחים בלבד לבין כלים שמיועדים לפעול בשביל המשתמש. ברירת המחדל היא false. סוכנים בדף ומסגרות בדיקה יכולים לקרוא אותו מ-RegisteredTool.annotations.debugging דרך getTools().
await document.modelContext.registerTool({
name: "dump_app_state",
description: "Returns a snapshot of the internal application store for debugging.",
execute() {
return appStore.getState();
},
annotations: {
readOnlyHint: true, // Only reads state.
debugging: true, // Developer tooling, not an end-user action.
}
});
סוכנים ובדיקות בדף (getTools ו-executeTool)
דפי אינטרנט לא צריכים את getTools() או את executeTool() כדי לחשוף כלים לסוכני AI. כדי שסוכני דפדפן, תוספים לדפדפן, כלי פיתוח ועוזרים דיגיטליים ברמת המערכת יוכלו לגלות ולהפעיל את הכלים שלכם מחוץ לפס, אתם רק צריכים לקרוא ל-document.modelContext.registerTool().
השיטות getTools() ו-executeTool() קיימות במיוחד לצרכנים שפועלים בסביבת JavaScript:
- סוכני JavaScript בדף: עוזר אישי מבוסס-AI, ווידג'ט של Copilot או ממשק צ'אט שמוטמעים ישירות בדף (או פועלים בתוך
<iframe>) וצריכים לגלות אילו כלים מוצעים בדף שמסביב או בפריימים נגישים בעץ המסמך, ולהפעיל אותם בשם המשתמש. - בדיקה וניפוי באגים אוטומטיים: חבילות מקרים לבדיקה (כמו Playwright, Vitest או בדיקות יחידה בדפדפן) שבודקות מטא-נתונים של כלים רשומים ומדמות הפעלות של כלי נציג בלי צורך ברתמת LLM חיצונית פעילה.
חיפוש כלים זמינים באמצעות getTools()
סוכנים בדף קוראים ל-document.modelContext.getTools() כדי לאחזר מערך של אובייקטים מסוג RegisteredTool מהמסמך הנוכחי ומכל מסגרת נגישה בעץ המסמכים.
החל מגרסה Chrome 155, RegisteredTool.inputSchema מוחזר ישירות כאובייקט ב-JavaScript (עותק עמוק של הסכימה שסופקה בזמן הרישום). שינוי האובייקט הזה לא משנה את הסכימה בפועל של הכלי הרשום.
// Example: An in-page AI assistant discovering tools available on the page:
const tools = await document.modelContext.getTools();
// In-page agents can listen for tools being registered or unregistered dynamically:
document.modelContext.addEventListener("toolchange", async () => {
const updatedTools = await document.modelContext.getTools();
console.log(`Active tools updated: ${updatedTools.map((t) => t.name).join(", ")}`);
});
כדי לגלות כלים שרשומים בתוך רכיבי iframe צאצאים ממקורות שונים (שחייבים להעניק גישה באופן מפורש דרך exposedTo במהלך הרישום), מעבירים את fromOrigins במילון האפשרויות:
// Query tools registered in the embedded cart frame that exposed them to this checkout origin:
const cartTools = await document.modelContext.getTools({
fromOrigins: ["https://cart.example.com"],
});
הפעלת כלים באמצעות executeTool()
סוכנים בדף וסקריפטים לבדיקה קוראים ל-document.modelContext.executeTool(tool, inputObject, options) כדי להפעיל כלי רשום. הכלי פועל במסמך שבו הוא נרשם, וה-promise פותר את התוצאה שהומרה למחרוזת שהוחזרה על ידי פונקציית ה-callback execute של הכלי.
החל מגרסה 155 של Chrome, הפונקציה executeTool() מקבלת אובייקט ב-JavaScript פשוט ישירות בשביל inputObject, בהתאם לפורמט הקלט שהקריאה החוזרת (callback) של execute בכלי מקבלת.
// 1. Discover the tool (typically done during agent initialization or test setup):
const tools = await document.modelContext.getTools();
const areaTool = tools.find((t) => t.name === "calculate_area");
if (areaTool) {
const controller = new AbortController();
// Example input payload matching the tool's inputSchema:
const inputObject = { width: 10, height: 20 };
const options = { signal: controller.signal };
// 2. Pass input arguments as a JavaScript object, with a JSON string fallback for Chrome <155:
let resultString;
try {
resultString = await document.modelContext.executeTool(areaTool, inputObject, options);
} catch (err) {
if (err?.message?.startsWith("Failed to parse input")) {
resultString = await document.modelContext.executeTool(
areaTool,
JSON.stringify(inputObject),
options
);
} else {
// Re-throw real tool execution or cancellation errors:
throw err;
}
}
console.log("Execution output string:", resultString);
}
ההבטחה שמוחזרת נדחית אם:
-
inputObjectהוא לא אובייקט או שאי אפשר להמיר אותו למחרוזת JSON (למשל, הפניות מעגליות או ערכיBigInt). חשוב לזכור שערכים שהושמטו על ידי סריאליזציה של JSON (כמו פונקציות ו-undefined) יושמטו מהאובייקט שהכלי מקבל, ולא יגרמו לדחייה. - הביצוע בוטל באמצעות
options.signal. - הרישום של הכלי בוטל לפני ההפעלה או שקרתה שגיאת זמן ריצה שלא טופלה.
תבנית Tool Factory
כדי להעביר הקשר (כמו מאגרים או מופעים של אפליקציות) לכלים, משתמשים בפונקציות מפעל.
export function createInventoryTool(inventoryManager) {
return {
name: "get_inventory",
description: "Lists items in the inventory.",
inputSchema: { type: "object", properties: {} },
execute() {
return inventoryManager.getItems();
},
annotations: { readOnlyHint: true }
};
}
סוגי TypeScript
בפרויקטים של TypeScript, אל תכתבו הצהרות ידניות ל-document.modelContext. מתקינים את החבילה הרשמית של webmcp-types (npm install --save-dev webmcp-types) ומוסיפים אותה אל tsconfig.json, כי היא לא נאספת באופן אוטומטי:
{
"compilerOptions": {
"types": ["webmcp-types"]
}
}
- הסוג של
document.modelContextהוא אופציונלי, לכן צריך להגן עליו באמצעותif (document.modelContext)לפני השימוש. - ב-
inputSchemaמוטבע, סוג הקלט שלexecuteנגזר מהסכימה. - סוגים בעלי שם כמו
WebMCP.ModelContextToolהם גלובליים (אין צורך לייבא אותם), והם שימושיים להקלדת פונקציות ליצירת כלים.
תמיכה ב-Framework
חובה: אם האפליקציה משתמשת ב-React, ב-Angular או ב-Vue, צריך לרשום את הכלים דרך שילוב WebMCP הרשמי של המסגרת הזו, שמפורט בהמשך. אל תקראו ל-document.modelContext.registerTool() מרכיבים ואל תכתבו wrapper משלכם למחזור החיים. כל שילוב כבר מטפל בזיהוי תכונות, בניקוי AbortSignal ובכלי הגדרת ההיקף למחזור החיים של הרכיב או המזרק. ממשקי ה-API האלה הם ניסיוניים, אז לפני שכותבים קוד, צריך לחפש את החתימה הנוכחית בסוגים או במסמכים של החבילה.
| Framework | חבילה | API | Docs |
|---|---|---|---|
| React 18+ | use-webmcp-tool |
useWebMCP(options): קריאה אחת לכל כלי |
npmjs.com/package/use-webmcp-tool |
| Angular | @angular/core, @angular/forms/signals |
provideExperimentalWebMcpTools([...]) (ספקי אפליקציות או מסלולים), declareExperimentalWebMcpTool(...) (שירותים פנימיים), provideExperimentalWebMcpForms() + האפשרות experimentalWebMcpTool בטופסי Signal |
angular.dev/ai/webmcp |
| Vue | @vueuse/core |
useWebMCP(options) קומפוזבילי |
vueuse.org/core/usewebmcp |
כל הכללים במדריך הזה עדיין חלים כשמשתמשים בשילובים האלה:
- שומרים על אותה צורה של הגדרת הכלי:
name,description,inputSchema,execute(input, { signal })ו-annotations. - פועלים לפי הכללים לגבי תיאורים והערות.
- מאמתים את הקלט ומחילים את ברירות המחדל בתוך
execute. - מעבירים את
signalלעבודה לטווח ארוך. - כדי להציע כלי רק בחלק מהזמן, צריך להעביר את הערך
enabled(React, Vue). אל תעטפו את ה-hook או את הקריאה לרכיב הקומפוזבילי בתנאי. - שילובים עשויים לעטוף תוצאות ושגיאות (לדוגמה, בתור
{ content, isError }). חשוב לבדוק את מסמכי התיעוד של השילוב לפני שמסתמכים על האופן שבו השגיאות מגיעות לנציג.
הערות לגבי ה-API
- annotations: (אופציונלי) מילון למטא-נתונים של הכלי.
- readOnlyHint: (אופציונלי) מגדירים את הערך
trueאם הכלי לא משנה את המצב ורק קורא נתונים. כך הנציגים יכולים להחליט מתי בטוח להפעיל את הכלי. - consequentialHint: (אופציונלי, Chrome 154 ואילך) מגדירים את הערך
trueלפעולות בעלות השלכות משמעותיות, בלתי הפיכות או בעולם האמיתי, כדי שהסוכנים יבקשו קודם אישור מהמשתמש. - untrustedContentHint: (אופציונלי) מגדירים את הערך
trueכשהכלי מחזיר תוכן שהאתר שלכם לא שולט בו, כמו טקסט שנוצר על ידי משתמשים או תגובות מ-API של צד שלישי. - ניפוי באגים: (אופציונלי, Chrome 156 ואילך) מגדירים את הערך
trueכשהכלי מיועד לניפוי באגים ולכלי למפתחים, ולא למשימות של משתמשי קצה. ברירת המחדל היאfalse.
- readOnlyHint: (אופציונלי) מגדירים את הערך
- אפשרויות הרשמה:
- signal: (אופציונלי)
AbortSignalשמשמש לביטול הרישום של הכלי כשלא צריך אותו יותר. - exposedTo: (אופציונלי) מערך של מחרוזות מקור מאובטחות שקובעות לאילו מסמכים בעץ המסמכים מותר לגלות ולהפעיל את הכלי מעבר לגבולות המסגרת.
- signal: (אופציונלי)
- אפשרויות לחיפוש כלים (
ModelContextGetToolOptions):- fromOrigins: (אופציונלי) מערך של מחרוזות מקור מאובטחות לשליחת שאילתות בפריימים נגישים. הפעלת
getTools()בליfromOriginsשולחת שאילתות רק למסמכים מאותו מקור.
- fromOrigins: (אופציונלי) מערך של מחרוזות מקור מאובטחות לשליחת שאילתות בפריימים נגישים. הפעלת
- פורמט ההחזרה: הפונקציה
executeיכולה להחזיר כל ערך שניתן לסדר ב-JSON (אובייקט, מערך, מחרוזת, מספר, ערך בוליאני). ההודעה על חריגה שנזרקה מ-executeלא מועברת לסוכן, לכן צריך להחזיר שגיאות שניתן לפעול לפיהן כמטעני ייעודיים (payloads) מובְנים של שגיאות (למשל{ error: "..." }) דרך ערך ההחזרה של הכלי, כדי שהסוכן יוכל לקרוא אותן ולפעול לפיהן. - הקשר מאובטח: WebMCP דורש HTTPS. כל המקורות ב-
exposedToוב-fromOriginsחייבים להיות גם מהימנים פוטנציאלית. - הוצאו משימוש או הוסרו: אין יותר תמיכה ב-
navigator.modelContext(הוצא משימוש ב-Chromium 150), ב-unregisterTool(), ב-provideContext()וב-clearContext().
אסטרטגיות חלופיות
כדי להבטיח תאימות עם דפדפנים שעדיין לא תומכים ב-WebMCP, צריך להשתמש ב-WebMCP Imperative API עם זיהוי תכונות.
if ('modelContext' in document) {
// Register tools
}