المطوّرون
امنح مساعد الذكاء الاصطناعي أدوات حقيقية عبر MCP
امنح المساعد أدوات حقيقية عبر MCP، المعيار المفتوح لربط الذكاء الاصطناعي بأنظمتك. أطلقه على الويب وiOS وAndroid وسطح المكتب. وأدر كل شيء من أي عميل MCP.
claude mcp add --transport http busymate-ai https://busymate.ai/mcpمداخل البدء
اختر من أين تبدأ
أضف المساعد إلى موقعك الإلكتروني
وسم script واحد على أي صفحة تسمح بها — ويعمل زر الدردشة ودردشة الزوار فورًا.
ضع دعم الذكاء الاصطناعي داخل تطبيق iOS
حمّل الدردشة في WKWebView؛ وجسر صغير من ثلاث رسائل يسجّل دخول مستخدميك.
ضع دعم الذكاء الاصطناعي داخل تطبيق Android
حمّل الدردشة في WebView؛ وواجهة JavaScript واحدة تسجّل دخول مستخدميك.
اربط خادم MCP الخاص بك كأدوات
يصبح خادم MCP الخاص بك هو إجراءات المساعد، نيابةً عن كل عميل.
أدر كل مساحة عمل من طرفيتك
شغّل المنصة من Claude Code أو Cursor أو أي عميل MCP عبر OAuth.
دع وكلاء الذكاء الاصطناعي يقرؤون موقعك
خريطة نصية بسيطة لموقعك على /llms.txt، مكتوبة لوكلاء الذكاء الاصطناعي.
01البدء السريع
كيف تتكامل الأجزاء
يبقى تطبيقك مصدر الحقيقة. ويتلقى المساعد رمزًا موقّعًا قصير الأجل يبيّن من الحاضر، ثم يستدعي أدواتك بصفته فاعلًا منفصلًا محدود الصلاحيات.
01
تطبيقك
يحتفظ بالهوية وبيانات الحساب؛ ويوقّع رمزًا صالحًا لدقيقتين يبيّن من سجّل الدخول.
02
المساعد
يطبّق إعدادات مساحة عملك: المحتوى، والنماذج، ومستويات الوصول إلى الأدوات، وخطوات التأكيد، والتحويل.
03
خادم MCP الخاص بك
يجيب عن الأدوات لمستخدم واحد في كل مرة، مستمدًّا هوية المستخدم من الرمز الحامل الموقّع — لا من وسائط الأداة أبدًا.
7 طرق للربط، ومساعد واحد: تضمين الويب · العملاء المسجّلون · iOS · Android · سطح المكتب · REST API · خادم MCP الخاص بك
02العملاء المسجّلون
تعرّف على العميل المسجّل مسبقًا
لكي يثق المساعد بهوية السائل، توقّع نقطة وصول مصادَق عليها واحدة على خادمك رمزًا قصير الأجل (JWT بخوارزمية ES256) يحمل معرّف العميل الثابت لديك وبضعة حقول عرض آمنة.
لا يتجاوز عمر الرمز 120 ثانية، ويحمل رمز nonce ومعرّف jti لمرة واحدة، ويسمّي مساحة عملك. ولا يصل المفتاح الخاص ولا جلسة منتجك إلى المتصفح أو الدردشة إطلاقًا.
import { SignJWT, importJWK } from "jose";
// POST https://YOUR-PRODUCT-DOMAIN/api/bmai/identity — requires YOUR OWN logged-in product session.
app.post("/api/bmai/identity", requireSession, async (req, res) => {
// Fresh on EVERY mint. Never persist the launch token/nonce in localStorage,
// sessionStorage, cookies, React state, or module state: every assistant
// launch consumes this pair exactly once.
const nonce = typeof req.body?.nonce === "string" ? req.body.nonce : "";
if (!/^[A-Za-z0-9_-]{32,200}$/.test(nonce)) return res.status(400).json({ error: "invalid_nonce" });
const key = await importJWK(JSON.parse(process.env.AI_LAUNCH_PRIVATE_JWK), "ES256");
const token = await new SignJWT({
"tenant_id": "00000000-0000-0000-0000-000000000000", // Your product's registered tenant claim
nonce, // equals the sibling field below
name: req.user.displayName, // optional low-sensitivity display claim
})
.setProtectedHeader({ alg: "ES256", kid: process.env.AI_LAUNCH_KEY_ID })
.setIssuer("https://YOUR-PRODUCT-DOMAIN (set when you register the provider)")
.setAudience("busymate-ai")
.setSubject(req.user.id) // IMMUTABLE internal account id; never email/phone/session id
.setJti(crypto.randomUUID()) // one-time (replay-protected)
.setIssuedAt()
.setExpirationTime("120s") // <= registered max age (120s)
.sign(key);
res.set("Cache-Control", "no-store");
res.status(201).json({ token, nonce, expiresIn: 120 });
});الرمز يقول من الحاضر، لا ما يُسمح له بفعله. أبقِ الأرصدة والأجهزة والإعدادات وكل تغيير خلف أدوات لا تجيب إلا لمستخدم واحد.
03الويب والصفحة الكاملة
سكربت واحد لزر دردشة مضمّن
تطلب حزمة SDK الهوية من خادمك عند الحاجة، وتعمل مع الزوار، وتُحدَّث بعد تسجيل الدخول والخروج، وتفتح الروابط الخارجية خارج الإطار، ولا تحتاج إلى ملفات تعريف ارتباط من جهات خارجية.
<!-- Floating "bro" launcher for Your product.
Anonymous chat works immediately on the allowed origins. -->
<script>
function newLaunchNonce() {
const bytes = new Uint8Array(32);
crypto.getRandomValues(bytes);
return btoa(String.fromCharCode(...bytes))
.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
}
window.BusymateAI = {
getIdentity: async () => {
const accessToken = await getProductAccessToken(); // YOUR existing auth helper
if (!accessToken) return null;
const nonce = newLaunchNonce();
const returnTo = new URL(location.href); returnTo.search = ""; returnTo.hash = "";
const r = await fetch("https://YOUR-PRODUCT-DOMAIN/api/bmai/identity", {
method: "POST", credentials: "include", cache: "no-store",
headers: { "content-type": "application/json", authorization: "Bearer " + accessToken },
body: JSON.stringify({ nonce, returnTo: returnTo.href }),
});
if (r.status === 401) return null; // signed out -> anonymous chat
if (!r.ok) throw new Error("AI identity mint failed (" + r.status + ")");
// MUST be a newly minted { token, nonce } pair on every call. Never
// persist either value in localStorage, sessionStorage, cookies, React
// state, or module state.
const identity = await r.json();
if (identity.nonce !== nonce) throw new Error("AI identity nonce mismatch");
return { token: identity.token, nonce: identity.nonce };
},
};
// Call after YOUR product completes login, logout, access-token/session
// rotation, or account switch. Do not send an identity postMessage directly.
window.refreshAssistantIdentity = () =>
window.BusymateAI?.refreshIdentity?.() ?? Promise.resolve();
</script>
<script
src="https://your-assistant.busymate.ai/embed/v1.js"
data-assistant="your-assistant"
data-label="Ask bro"
async></script>افتح الدردشة بملء الصفحة على عنوانك
عندما يفتح مستخدم مسجّل عنوان مساعدك أو نطاقك المخصص، مرّر رمز تسجيل الدخول في جزء العنوان (fragment). وتمسحه الصفحة قبل التبادل.
// Full-page open with identity in the URL FRAGMENT — never sent in the
// request line, referrer, or logs; the destination strips it before exchange.
function newLaunchNonce() {
const bytes = new Uint8Array(32);
crypto.getRandomValues(bytes);
return btoa(String.fromCharCode(...bytes))
.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
}
const nonce = newLaunchNonce();
const accessToken = await getProductAccessToken(); // YOUR existing auth helper
if (!accessToken) throw new Error("Sign in before opening an identified assistant");
const returnTo = new URL(location.href); returnTo.search = ""; returnTo.hash = "";
const response = await fetch("https://YOUR-PRODUCT-DOMAIN/api/bmai/identity", {
method: "POST", credentials: "include", cache: "no-store",
headers: { "content-type": "application/json", authorization: "Bearer " + accessToken },
body: JSON.stringify({ nonce, returnTo: returnTo.href }),
});
if (response.status === 401) throw new Error("Sign in before opening an identified assistant");
if (!response.ok) throw new Error("AI identity mint failed (" + response.status + ")");
const identity = await response.json();
if (typeof identity.token !== "string" || typeof identity.nonce !== "string") {
throw new Error("AI identity mint returned an invalid response");
}
if (identity.nonce !== nonce) throw new Error("AI identity nonce mismatch");
const url = new URL("https://your-assistant.busymate.ai/");
url.hash = new URLSearchParams({
bmai_token: identity.token,
bmai_nonce: identity.nonce,
}).toString();
location.assign(url);04iPhone
WKWebView مع جسر رسائل محدود
اسمح فقط بالرسائل الثلاث ذات الإصدارات: طلب الهوية، والرد على الهوية، والعنوان الخارجي. وأصدِر الهوية عبر عميل واجهة البرمجة المصادَق عليه الموجود أصلًا في التطبيق.
// SDK source: https://busymate.ai/sdk/v1/ios/BusymateAI.swift
// Load https://your-assistant.busymate.ai/?channel=ios in a WKWebView.
final class AssistantBridge: NSObject, WKScriptMessageHandler {
let webView: WKWebView
func userContentController(_ controller: WKUserContentController,
didReceive message: WKScriptMessage) {
guard message.name == "BusymateAI",
let body = message.body as? [String: Any],
body["type"] as? String == "busymate.ai.v1.identity_request"
else { return }
Task { // mint through YOUR authenticated API — never a key in the app
let identity = try await api.mintLaunchIdentity()
let payload: [String: Any] = [
"type": "busymate.ai.v1.identity",
"token": identity.token,
"nonce": identity.nonce,
]
let data = try JSONSerialization.data(withJSONObject: payload)
let json = String(decoding: data, as: UTF8.self)
await webView.evaluateJavaScript("window.postMessage(\(json), '*')")
}
}
}05Android
WebView مع واجهة واحدة ضمن قائمة السماح
احصر التنقل في نطاق الذكاء الاصطناعي الخاص بمساحة العميل، وافتح الروابط الخارجية في متصفح النظام، ولا تعرض أساليب أصلية عامة.
// SDK source: https://busymate.ai/sdk/v1/android/BusymateAI.kt
// Load https://your-assistant.busymate.ai/?channel=android in a WebView.
class AssistantBridge(private val webView: WebView) {
@JavascriptInterface
fun postMessage(raw: String) {
val message = JSONObject(raw)
if (message.optString("type") != "busymate.ai.v1.identity_request") return
lifecycleScope.launch { // mint through YOUR authenticated API client
val identity = api.mintLaunchIdentity()
val response = JSONObject()
.put("type", "busymate.ai.v1.identity")
.put("token", identity.token)
.put("nonce", identity.nonce)
webView.evaluateJavascript(
"window.postMessage(${JSONObject.quote(response.toString())}, '*')", null
)
}
}
}
webView.settings.javaScriptEnabled = true
webView.addJavascriptInterface(AssistantBridge(webView), "BusymateAINative")
// SupportChatNative + support.chat.v1.* remain accepted for shipped apps.06سطح المكتب
البروتوكول نفسه يناسب Electron وTauri والأغلفة الأصلية
استخدم WebView معزولًا، وامنع فتح نوافذ جديدة داخل العرض، وافتح العناوين الآمنة خارجيًا، وأجب عن طلبات الهوية عبر طبقة المضيف ذات الصلاحيات.
import { mountBusymateAI } from "https://busymate.ai/sdk/v1/index.js";
// productAuth is a narrow preload/Tauri command bridge. It calls YOUR
// authenticated backend; no cookie, signing key, or refresh token is exposed
// to the renderer.
const assistant = await mountBusymateAI({
assistant: "your-assistant",
origin: "https://your-assistant.busymate.ai",
label: "Ask bro",
getIdentity: () => window.productAuth.mintAssistantIdentity(),
});
window.productAuth.onSessionChanged(() => assistant.refreshIdentity());
assistant.open();
// Electron main process (Tauri: use the equivalent shell/open allowlist):
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
const target = new URL(url);
if (target.protocol === "https:" || target.protocol === "http:") {
void shell.openExternal(target.href);
}
return { action: "deny" };
});07أدوات MCP
امنح المساعد أدوات دون أن تمنحه قاعدة بيانات عملائك
انشر مخططات كاملة عند الاكتشاف. وامنح كل أداة أحد مستويات الوصول الثلاثة، وحدّد التغييرات التي تحتاج إلى بطاقة تأكيد، وأعد التحقق من الصلاحيات في كل استدعاء.
عام
يجوز لأي شخص يدردش استدعاؤه. الأسعار، والحالة، والميزات.
مُعرَّف
يتطلب مستخدمًا مسجّلًا. حالة الطلبات، وإجابات الحساب.
مفوَّض
يتصرف نيابةً عن المستخدم المسجّل عبر رمز فاعل محدود الصلاحيات أو عبر إذن OAuth الخاص بالمستخدم نفسه.
كل تغيير يُؤكَّد على الخادم. الأدوات التي تدرجها في confirm_tools تتوقف عند بطاقة تأكيد قبل تنفيذها؛ وكذلك أي اسم أداة لا يتعرّف عليه المساعد. ولا تنفّذ إطارات اللوحات أي تغيير إطلاقًا.
MCP endpoint ............ https://YOUR-DOMAIN/mcp
RFC 8707 resource ....... https://YOUR-DOMAIN/mcp (the token is audience-bound to this)
AS metadata (RFC 8414) .. https://YOUR-DOMAIN/.well-known/oauth-authorization-server
Resource meta (RFC 9728) https://YOUR-DOMAIN/.well-known/oauth-protected-resource
Client registration ..... Dynamic (RFC 7591) — public client, no secret
PKCE .................... S256 required (RFC 7636)
Authorization response .. iss parameter checked (RFC 9207)
Grants .................. authorization_code + refresh_token
Delegated tools/call .... no bearer -> 401; user derived from the bearer,
NEVER from an account id in tool arguments
Customer experience ..... one separate Authorize account tools action is expected;
use signed_actor_token instead for automatic SSO// POST https://YOUR-DOMAIN/mcp
// Authorization: Bearer <the per-user OAuth token bro obtained>
{
"jsonrpc": "2.0",
"id": 12,
"method": "tools/call",
"params": { "name": "get_my_account", "arguments": {} }
}
// Your server verifies the bearer, derives the user from its signed subject,
// and returns ONLY that user's data.ما تتحدث به المنصة
تنطبق مجموعة البروتوكولات نفسها سواء كانت المنصة عميلًا لخادمك أو خادمًا لعميل MCP لديك.
- OAuth 2.1 مع PKCE (S256)؛ والعملاء العامّون يسجّلون ديناميكيًا (RFC 7591).
- الاكتشاف عبر بيانات خادم التفويض (RFC 8414) وبيانات المورد المحمي (RFC 9728).
- أنواع المنح: authorization_code وrefresh_token؛ واستجابة التفويض تحمل جهة الإصدار (RFC 9207).
- مؤشرات الموارد (RFC 8707) عندما تكون المنصة هي عميل OAuth لخادم MCP الخاص بك.
- تبادل الرموز (RFC 8693) حيثما كان مُعدًّا.
08التحويل والرؤى
اضبط قواعد تدخّل الإنسان
متى يحوّل المحادثة
عندما يطلب العميل التحدث إلى إنسان، أو تفشل أداة، أو يتجاوز مبلغ الاسترداد حدّك، أو تظهر كلمة مفتاحية، أو أي حدث تحدده أنت.
كيف يُبلَّغ فريقك
صندوق وارد واحد؛ والإسناد يدويًا أو بالتناوب أو لمن لديه أقل عدد من المحادثات المفتوحة؛ والتنبيهات داخل التطبيق وعبر Web Push وAPNs وTelegram الشخصي.
فريقك يتولى الأمر
راقب المحادثة، وانضم إليها مع كامل السياق، ورد في الدردشة نفسها؛ ولا يجري المساعد أي تغييرات ما دام هناك إنسان نشط.
الرؤى
الأسئلة المتكررة، والمعرفة الناقصة، والمسارات الفاشلة، مجمّعة من محادثات حقيقية مع روابط إلى الأدلة.
09تسجيل الدخول لمساحة العمل
احتفظ بقاعدة مستخدميك ونظام المصادقة الخاص بك
اضبط عناوين تسجيل الدخول والحساب لمساحة العمل في لوحة التحكم. فالزائر الذي يختار تسجيل الدخول يغادر الإطار، ويصادق على منتجك، ثم يعود إلى العنوان الأصلي نفسه بالضبط. بعدها يوفّر خادمك رمز تسجيل دخول لمرة واحدة؛ ولا يتلقى Busymate AI أبدًا كلمة مرور المستخدم ولا مفتاح التوقيع لديك.
لا يمسّ أي تغيير سوى بيانات المستخدم المسجّل نفسه. تأخذ أدوات الحساب هوية العميل من الفاعل المفوَّض، وتعيد التحقق من الصلاحيات في كل استدعاء، وتطلب تأكيدًا على التغييرات التي تحددها أنت.
10قائمة تحقق الإطلاق
قائمة تحقق الإطلاق للإنتاج
- 01اضبط الهوية البصرية وتحسين محركات البحث وعنوانك على الويب والأسئلة المقترحة.
- 02سجّل نظام تسجيل الدخول لديك: جهة الإصدار، وJWKS، والجمهور، والادعاءات، وعمر الرمز.
- 03اربط MCP، وحدّد مستوى الوصول لكل أداة، وأثبت أن عمليات القراءة محصورة بصاحبها وأن عمليات الكتابة مؤكَّدة.
- 04اضبط قواعد التحويل، وعيّن فريق صندوق الوارد، وحدّد ساعات العمل وأهداف زمن الاستجابة.
- 05اختبر الزوار، والمستخدمين المسجّلين، وتسجيل الخروج وتبديل الحساب، والرموز المُعاد تشغيلها، ومعرّف مساحة عمل مُبدَّل.
- 06افحص الدردشة بملء الصفحة، والتضمين، وiOS، وAndroid، وسطح المكتب، وإمكانية الوصول، والروابط الخارجية.
- 07لا تنشر إلا النسخة التي فحصتها؛ وراقب صحة الاتصال والنطاق.
هل أنت مستعد لإعداد مساحة عملك؟
تنشئ صفحة التكامل في لوحة التحكم الشيفرة والإعدادات لكل واجهة انطلاقًا من إعداداتك المنشورة.
MCP الإداري
أدر كل مساحة عمل من أي عميل MCP
218 أداة إدارية عبر MCP مع OAuth 2.1. يفتح العميل صفحة تسجيل دخول في المتصفح عند أول اتصال؛ ولا شيء يُلصَق يدويًا.
مستندات الاكتشاف
- نقطة وصول MCP
- https://busymate.ai/mcp
- بيانات خادم التفويض (RFC 8414)
- https://busymate.ai/.well-known/oauth-authorization-server/mcp
- بيانات المورد المحمي (RFC 9728)
- https://busymate.ai/.well-known/oauth-protected-resource/mcp
الحساب الذي تسجّل الدخول به هو ما يحدد مساحات العمل التي يجوز للعميل إدارتها. وكل تغيير يطلب تأكيدًا.
Claude Code
claude mcp add --transport http busymate-ai https://busymate.ai/mcpأدر المنصة من أي عميل MCP
يقبل Cursor وClaude Desktop وأي عميل يقرأ ملف mcp.json هذا الإدخال؛ أما العملاء الذين يقبلون عنوانًا بعيدًا فيأخذون نقطة الوصول أعلاه.
{
"mcpServers": {
"platform-management": {
"type": "http",
"url": "https://busymate.ai/mcp"
}
}
}أحدث التغييرات
ما الذي أُطلق
إصدار البناء 265
Console Artifacts show a public origin label; the docs "Connect Claude Code" section localized in all 14 languages
إصدار البناء 264
Console UI for the 29 MCP-only tools: Artifacts, App Store developer, price override
إصدار البناء 263
Hotfix: connector OAuth start accepts hosted-slug tenants
اربط أول أداة لديك اليوم
سجّل خادم MCP الخاص بك، واختر من يجوز له استخدام كل أداة، ثم انشر. ويمكن للمساعد استخدامها في الدقيقة نفسها.