ابزارهای جاوا اسکریپت عامل‌گرا

ویژگی‌های وب: document.modelContext

‫Imperative API از document.modelContext.registerTool() برای تعریف برنامه‌نویسی‌شده ابزارهای جاوااسکریپت استفاده می‌کند. این روش برای «برنامه‌های تک‌صفحه‌ای» (SPA) که در آن‌ها ابزارها باید براساس مسیر فعلی یا وضعیت کاربر اضافه یا حذف شوند ایده‌آل است.

‫WebMCP براساس معماری تولیدکننده/مصرف‌کننده عمل می‌کند:

  • صفحه‌های وب تولیدکننده ابزار هستند: ابزارها را بااستفاده از document.modelContext.registerTool() تعریف و ثبت می‌کنید. این تمام چیزی است که یک صفحه وب برای پیاده‌سازی نیاز دارد. برای نمایش ابزارها به نماینده‌ها، لازم نیست getTools() یا executeTool() را در صفحه فراخوانی کنید.
  • عوامل مرورگر و افزونه مصرف‌کنندگان اصلی هستند: عوامل ارائه‌شده توسط یا ازطریق مرورگر — ازجمله عامل داخلی مرورگر، افزونه‌های مرورگر، DevTools، و دستیارهای سطح سیستم — ابزارهای ثبت‌شده را به‌صورت خارج از باند ازطریق سازوکارهای پلاتفرم داخلی کشف و فراخوانی می‌کنند.
  • عوامل درون‌صفحه و مجموعه داده‌های تست: 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() فقط اسناد دارای مبدأ یکسان را پُرسمان می‌کند.
  • مطابقت مبدأ: مبدأ خود سند ثبت‌کننده همیشه دسترسی دارد. مبدأهای مشخص‌شده در exposedTo اجازه دارند ابزار را ازطریق document.modelContext.getTools({ fromOrigins: [...] }) کاوش کنند و آن را ازطریق document.modelContext.executeTool() اجرا کنند.
  • الزامات امنیتی: هر مبدأ در exposedTo باید به‌طور بالقوه قابل‌اعتماد باشد (HTTPS یا localhost). ارسال مبدأ نامعتبر یا ناامن باعث می‌شود registerTool() با SecurityError رد شود.
  • Scope: exposedTo اکتشاف بین‌سندی درون‌صفحه‌ای را در سراسر قاب‌ها در درخت سند کنترل می‌کند.

درحال تعریف پارامترها

پارامترها (params) بااستفاده از ویژگی inputSchema تعریف می‌شوند. این باید یک شیء طرح‌واره JSON باشد که داده‌های ساختاریافته موردانتظار ابزار را توصیف می‌کند.

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 },
});

الگوهای اجرا

فراخوانی برگشتی execute همیشه دو آرگومان دریافت می‌کند: شیء ورودی، و شیء گزینه‌ها که حاوی AbortSignal — execute(inputObject, { signal }) است.

چه زمانی از async execute استفاده شود

وقتی ابزار شامل عملیاتی است که Promise برمی‌گرداند یا تکمیل آن زمان می‌برد، از async استفاده کنید:

  • فراخوانی‌های شبکه: واکشی داده‌ها از میانای برنامه‌سازی کاربردی.
  • فضای ذخیره‌سازی ناهمگام: دسترسی به 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(...). درعوض، یک محموله خطای ساختاریافته را ازطریق مقدار بازگشتی عادی ابزار برگردانید تا عامل هوش مصنوعی جزئیات تشخیصی را دریافت کند و بتواند خوداصلاحی یا تلاش مجدد انجام دهد:

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;
}

Only re-throw when the execution was cancelled (signal.aborted is true).

لغو کردن اجراهای درحال انجام

لغو توسط کاربر یا نماینده آغاز می‌شود. اجباری: هر ابزاری که درخواست‌های شبکه یا کارهای ناهمگام طولانی‌مدت دیگر را انجام می‌دهد باید از signal پیروی کند، درغیراین‌صورت اجراهای لغوشده همچنان منابع را مصرف می‌کنند و می‌توانند پس‌از اینکه نماینده به کار دیگری پرداخت، داده‌های قدیمی را در واسط کاربر بنویسند.

  • میاناهای برنامه‌سازی کاربردی که سیگنال می‌پذیرند (خواننده‌های fetch()،‏ addEventListener()،‏ ReadableStream): signal را مستقیماً عبور دهید.
  • میاناهای برنامه‌سازی کاربردی که (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 }
});

پرچم‌گذاری ابزارهای پیامدی

از Chrome 154،‏ 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 به‌عنوان یک راهنمایی برخورد کنید، نه یک سازوکار اجرایی. این ویژگی به‌تنهایی مانع اجرا نمی‌شود و مرورگرهایی که قدیمی‌تر از این راهنمایی هستند اصلاً پیام‌واره‌ای نشان نمی‌دهند. هرگونه تأیید درون‌برنامه‌ای را که کنش ازقبل تضمین می‌کند حفظ کنید.

ابزارهای اشکال‌زدایی پرچم‌گذاری

از Chrome 156،‏ annotations از debugging پشتیبانی می‌کند. برای ابزارهایی که برای اشکال‌زدایی و ابزار توسعه‌دهندگان ساخته شده‌اند، به‌جای تکالیف کاربر نهایی، annotations.debugging را روی true تنظیم کنید. نمونه‌ها: تخلیه وضعیت داخلی برنامه، تغییر پرچم‌های ویژگی، یا کاشت داده‌های آزمایشی. این کار به عامل‌ها اجازه می‌دهد ابزارهای مختص توسعه‌دهنده را از ابزارهایی که برای اقدام ازطرف کاربر طراحی شده‌اند تشخیص دهند. به‌طور پیش‌فرض روی 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() نیاز ندارند. برای اینکه عامل‌های مرورگر، افزونه‌های مرورگر، DevTools، و دستیارهای سطح سیستم بتوانند ابزارهای شما را به‌صورت خارج از باند کشف و اجرا کنند، فقط کافی است document.modelContext.registerTool() را فراخوانی کنید.

روش‌های getTools() و executeTool() به‌طور خاص برای مصرف‌کنندگانی که در محیط جاوا اسکریپت اجرا می‌شوند وجود دارند:

  1. عوامل جاوا اسکریپت درون‌صفحه‌ای: دستیار هوش مصنوعی، ابزارک کمک‌خلبان، یا میانای گپ که مستقیماً در صفحه جاسازی شده است (یا در داخل <iframe> اجرا می‌شود) و باید ابزارهایی را که صفحه اطراف یا قاب‌های قابل‌دسترسی در درخت سند ارائه می‌دهند شناسایی کند و آن‌ها را ازطرف کاربر فراخوانی کند.
  2. آزمایش و اشکال‌زدایی خودکارسازی‌شده: مجموعه‌های آزمایشی (مانند Playwright،‏ Vitest، یا آزمایش‌های واحد درون مرورگر) که فراداده ابزار ثبت‌شده را بازرسی می‌کنند و فراخوانی‌های ابزار عامل را بدون نیاز به مهار LLM خارجی زنده شبیه‌سازی می‌کنند.

درحال کاوش ابزارهای دردسترس با getTools()

عوامل درون‌صفحه document.modelContext.getTools() را فراخوانی می‌کنند تا آرایه‌ای از اشیای RegisteredTool را از سند فعلی و هر قاب قابل‌دسترسی در درخت سند بازیابی کنند.

از Chrome 155،‏ RegisteredTool.inputSchema مستقیماً به‌عنوان شیء جاوا اسکریپت (کپی عمیق طرح‌واره ارائه‌شده در زمان ثبت‌نام) برگردانده می‌شود. جهش دادن این شیء طرحواره واقعی ابزار ثبت‌شده را تغییر نمی‌دهد.

// 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) را برای اجرای ابزار ثبت‌شده فراخوانی می‌کنند. ابزار در سندی که در آن ثبت شده است اجرا می‌شود و وعده به نتیجه رشته‌ای‌شده‌ای که توسط فراخوان برگشتی execute ابزار برگردانده شده است حل می‌شود.

از Chrome 155،‏ executeTool() یک شیء جاوا اسکریپت ساده را مستقیماً برای inputObject می‌پذیرد، که با قالب ورودی‌ای که فراخوان برگشتی 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 لغو شد.
  • ابزار پیش‌از اجرا لغو ثبت‌نام شده است یا با خطای زمان اجرای مدیریت‌نشده مواجه می‌شود.

الگوی کارخانه ابزار

برای ارسال بافت (مانند فروشگاه‌ها یا نمونه‌های برنامه) به ابزارهای خود، از توابع کارخانه استفاده کنید.

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 جهانی هستند (نیازی به وارد کردن نیست)، برای تایپ کردن کارخانه‌های ابزار مفید هستند.

پشتیبانی چارچوب

اجباری: اگر برنامه از React،‏ Angular، یا Vue استفاده می‌کند، ابزارها را ازطریق ادغام WebMCP رسمی آن چارچوب که در زیر فهرست شده است ثبت کنید. document.modelContext.registerTool() را از مؤلفه‌ها فراخوانی نکنید یا پوشاننده چرخه حیات خودتان را ننویسید. هر ادغام ازقبل تشخیص ویژگی، پاک‌سازی AbortSignal، و ابزارهای محدودسازی را برای چرخه حیات عنصر یا تزریق‌کننده مدیریت می‌کند. این میاناهای برنامه‌سازی کاربردی آزمایشی هستند، بنابراین قبل‌از نوشتن کد، امضای فعلی را در انواع یا اسناد بسته جستجو کنید.

چارچوب بسته میانای برنامه‌سازی کاربردی سندنگار
React 18+ use-webmcp-tool useWebMCP(options): یک فراخوانی برای هر ابزار npmjs.com/package/use-webmcp-tool
Angular @angular/core، @angular/forms/signals provideExperimentalWebMcpTools([...]) (ارائه‌دهندگان برنامه یا مسیر)، declareExperimentalWebMcpTool(...) (سرویس‌های داخلی)، provideExperimentalWebMcpForms() + گزینه experimentalWebMcpTool در «فرم‌های سیگنال» 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) را ارسال کنید. نباید فراخوانی ترکیب‌پذیر یا قلاب را در شرطی بپیچید.
  • ادغام‌ها ممکن است نتایج و خطاها را دربرگیرند (برای مثال به‌عنوان { content, isError }). قبل‌از تکیه بر نحوه رسیدن خطاها به نماینده، اسناد ادغام را بررسی کنید.

یادداشت‌های میانای برنامه‌سازی کاربردی

  • annotations: (اختیاری) واژه‌نامه‌ای برای فراداده ابزار.
    • readOnlyHint: (اختیاری) اگر ابزار هیچ وضعیتی را تغییر نمی‌دهد و فقط داده‌ها را می‌خواند، روی true تنظیم کنید. این کار به نماینده‌ها کمک می‌کند تصمیم بگیرند چه زمانی برای فراخوانی ابزار امن است.
    • consequentialHint: (اختیاری، Chrome نسخه ۱۵۴ و بالاتر) برای کنش‌های پرخطر، برگشت‌ناپذیر، یا کنش‌های دنیای واقعی، روی true تنظیم کنید تا عامل‌ها ابتدا تأیید کاربر را درخواست کنند.
    • untrustedContentHint: (اختیاری) وقتی ابزار محتوایی را برمی‌گرداند که سایت شما آن را کنترل نمی‌کند، مثل نوشتار تولیدشده توسط کاربر یا پاسخ‌های میانای برنامه‌سازی کاربردی شخص ثالث، روی true تنظیم کنید.
    • اشکال‌زدایی: (اختیاری، Chrome نسخه ۱۵۶ و بالاتر) وقتی ابزار برای اشکال‌زدایی و ابزار توسعه‌دهنده است و نه برای کارهای کاربر نهایی، روی true تنظیم کنید. پیش‌فرض‌ها به false.
  • گزینه‌های ثبت‌نام:
    • signal: (اختیاری) یک AbortSignal که برای لغو ثبت ابزار در زمانی که دیگر به آن نیاز نیست استفاده می‌شود.
    • ‫exposedTo: (اختیاری) آرایه‌ای از رشته‌های مبدأ امن که کنترل می‌کند کدام اسناد در درخت سند مجاز به کشف و اجرای ابزار در مرزهای قاب هستند.
  • گزینه‌های کاوش ابزار (ModelContextGetToolOptions):
    • fromOrigins: (اختیاری) آرایه‌ای از رشته‌های مبدأ امن برای پُرسمان در قاب‌های دردسترس. فراخوانی getTools() بدون fromOrigins فقط اسناد با مبدأ یکسان را پُرسمان می‌کند.
  • قالب برگشتی: تابع execute می‌تواند هر مقدار قابل‌سریال‌سازی JSON (شیء، آرایه، رشته، عدد، بولی) را برگرداند. پیام استثنای ایجادشده از execute به نماینده بازارسال نمی‌شود، بنابراین خطاهای قابل‌اجرا را به‌عنوان بار داده خطای ساختاریافته (مثلاً { error: "..." }) ازطریق مقدار برگشتی ابزار برگردانید تا نماینده بتواند آن‌ها را بخواند و براساس آن‌ها اقدام کند.
  • زمینه امن: WebMCP به HTTPS نیاز دارد. همه مبدأها در exposedTo و fromOrigins باید به‌طور بالقوه قابل‌اعتماد باشند.
  • منسوخ‌شده/برداشته‌شده: navigator.modelContext (منسوخ‌شده در Chromium 150)، unregisterTool()، provideContext()، و clearContext() دیگر پشتیبانی نمی‌شوند.

راهبردهای جایگزین

میانای برنامه‌سازی کاربردی WebMCP Imperative باید با تشخیص ویژگی استفاده شود تا از سازگاری با مرورگرهایی که هنوز از WebMCP پشتیبانی نمی‌کنند اطمینان حاصل شود.

if ('modelContext' in document) {
  // Register tools
}