Busymate AI

डेवलपर

MCP से अपने AI असिस्टेंट को असली टूल दीजिए

MCP — AI को आपके सिस्टम से जोड़ने का खुला मानक — के ज़रिए असिस्टेंट को असली टूल दीजिए। इसे वेब, iOS, Android और डेस्कटॉप पर लाइए। सब कुछ किसी भी MCP क्लाइंट से संभालिए।

claude mcp add --transport http busymate-ai https://busymate.ai/mcp
TERMINAL$claude mcp add --transport http busymate-ai https://busymate.ai/mcpजुड़ाJSON-RPC 2.0 · tools/call{ "jsonrpc": "2.0", "id": 12, "method": "tools/call", "params": { "name": "get_my_account", "arguments": {} } }{ "jsonrpc": "2.0", "id": 12, "result": { "content": [{ "type": "text", "text": "…" }] } }

जुड़ने के रास्ते

तय कीजिए कहाँ से शुरू करना है

असिस्टेंट को अपनी वेबसाइट में जोड़ें

आपके चुने हुए किसी भी पेज पर एक स्क्रिप्ट टैग — लॉन्चर और अतिथि चैट तुरंत काम करने लगते हैं।

अपने iOS ऐप के भीतर AI सपोर्ट रखें

चैट को WKWebView में लोड करें; तीन संदेशों वाला एक छोटा ब्रिज आपके उपयोगकर्ताओं को साइन-इन कराता है।

अपने Android ऐप के भीतर AI सपोर्ट रखें

चैट को WebView में लोड करें; एक JavaScript इंटरफ़ेस आपके उपयोगकर्ताओं को साइन-इन कराता है।

अपने MCP सर्वर को टूल के रूप में जोड़ें

आपका अपना MCP सर्वर असिस्टेंट की कार्रवाइयाँ बन जाता है — हर ग्राहक की ओर से।

हर वर्कस्पेस अपने टर्मिनल से संभालिए

प्लैटफ़ॉर्म को Claude Code, Cursor या किसी भी MCP क्लाइंट से OAuth के ज़रिए चलाइए।

AI एजेंट्स को अपनी साइट पढ़ने दें

/llms.txt पर आपकी साइट का सादा-पाठ नक्शा, AI एजेंट्स के लिए लिखा हुआ।

01क्विकस्टार्ट

यह सब कैसे जुड़ता है

आपका ऐप ही सत्य का स्रोत बना रहता है। असिस्टेंट को एक अल्पकालिक हस्ताक्षरित टोकन मिलता है जो बताता है कि कौन मौजूद है, और वह आपके टूल को एक अलग, सीमित दायरे वाले एक्टर के रूप में कॉल करता है।

आपके ग्राहकआपकी वेबसाइट या ऐपअसिस्टेंटआपके सिस्टमआपकी सेटिंग्सअपने-आप लागू

01

आपका ऐप

पहचान और अकाउंट डेटा रखता है; दो मिनट का ऐसा टोकन हस्ताक्षरित करता है जो बताता है कि कौन साइन-इन है।

02

असिस्टेंट

आपके वर्कस्पेस की सेटिंग्स लागू करता है: सामग्री, मॉडल, टूल के एक्सेस स्तर, पुष्टि चरण, हैंडऑफ़।

03

आपका MCP सर्वर

एक बार में एक उपयोगकर्ता के लिए टूल का जवाब देता है, और उपयोगकर्ता की पहचान साइन-इन बियरर टोकन से लेता है — टूल के आर्ग्युमेंट से कभी नहीं।

जुड़ने के 7 तरीके, असिस्टेंट एक: वेब एम्बेड · साइन-इन ग्राहक · iOS · Android · डेस्कटॉप · REST API · आपका MCP सर्वर

YOUR HELP SITErobots-aware1–50 pagesIndexRetrieve for an answerwith a source

02साइन-इन ग्राहक

पहले से साइन-इन ग्राहक को पहचानें

ताकि असिस्टेंट भरोसा कर सके कि पूछने वाला कौन है, आपके बैकएंड का एक प्रमाणित एंडपॉइंट आपकी स्थायी ग्राहक id और कुछ सुरक्षित प्रदर्शन फ़ील्ड के साथ एक अल्पकालिक टोकन (ES256 JWT) पर हस्ताक्षर करता है।

टोकन अधिकतम 120 सेकंड चलता है, उसमें एक-बार का nonce और jti होता है, और आपके टेनेंट का नाम होता है। निजी कुंजी और आपका प्रोडक्ट सेशन ब्राउज़र या चैट तक कभी नहीं पहुँचते।

Your backendThe browserThe assistantsigns the tokenthe key never leavescarries itchecks your JWKS120s maxchecked
server/bmai-identity.tstypescript
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 ज़रूरत पड़ने पर आपके बैकएंड से पहचान माँगता है, अतिथियों के लिए भी चलता है, लॉगिन और लॉगआउट के बाद ताज़ा होता है, बाहरी लिंक फ़्रेम के बाहर खोलता है, और उसे किसी थर्ड-पार्टी कुकी की ज़रूरत नहीं।

index.htmlhtml
<!-- 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>

पूरे पेज की चैट अपने पते पर खोलें

जब कोई साइन-इन उपयोगकर्ता आपके असिस्टेंट का पता या आपका कस्टम डोमेन खोले, तो साइन-इन टोकन URL फ़्रैगमेंट में भेजें। पेज एक्सचेंज से पहले उसे हटा देता है।

open-assistant.tstypescript
// 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

सिर्फ़ तीन संस्करणित संदेशों की अनुमति दें: पहचान अनुरोध, पहचान प्रतिक्रिया और बाहरी URL। पहचान ऐप के मौजूदा प्रमाणित API क्लाइंट से बनाएँ।

AssistantBridge.swiftswift
// 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

नेविगेशन को अपने टेनेंट AI ओरिजिन तक रखें, बाहरी लिंक सिस्टम ब्राउज़र में भेजें और कोई सामान्य-उद्देश्य नेटिव विधि उजागर न करें।

AssistantBridge.ktkotlin
// 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 इस्तेमाल करें, इन-व्यू नई विंडो न खुलने दें, सुरक्षित URL बाहर खोलें, और पहचान के अनुरोधों का जवाब विशेषाधिकार वाली होस्ट परत से दें।

assistant-renderer.tstypescript
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" };
});

07MCP टूल

असिस्टेंट को टूल दीजिए, अपना ग्राहक डेटाबेस नहीं

डिस्कवरी पर पूरे स्कीमा प्रकाशित करें। हर टूल को तीन एक्सेस स्तरों में से एक दें, उन बदलावों को चिह्नित करें जिन्हें पुष्टि कार्ड चाहिए, और हर कॉल पर अधिकार दोबारा जाँचें।

सार्वजनिक

चैट करने वाला कोई भी इसे कॉल कर सकता है। कीमतें, स्थिति, ख़ूबियाँ।

पहचाना गया

साइन-इन उपयोगकर्ता ज़रूरी। ऑर्डर की स्थिति, अकाउंट से जुड़े जवाब।

डेलिगेटेड

साइन-इन उपयोगकर्ता की ओर से एक सीमित एक्टर टोकन या उपयोगकर्ता की अपनी OAuth अनुमति से काम करता है।

हर बदलाव की पुष्टि सर्वर पर होती है। confirm_tools में सूचीबद्ध टूल चलने से पहले एक पुष्टि कार्ड पर रुकते हैं; और वैसा हर टूल नाम भी, जिसे असिस्टेंट पहचानता नहीं। विजेट फ़्रेम कभी कोई बदलाव नहीं चलाते।

oauth-requirements.txttext
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
delegated-call.jsonjson
// 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), जब प्लैटफ़ॉर्म आपके MCP सर्वर के लिए OAuth क्लाइंट होता है।
  • टोकन एक्सचेंज (RFC 8693), जहाँ कॉन्फ़िगर किया गया हो।

08हैंडऑफ़ और इनसाइट्स

तय कीजिए कि कब कोई व्यक्ति बीच में आए

यह कब सौंपता है

ग्राहक किसी व्यक्ति से बात माँगे, कोई टूल विफल हो, रिफ़ंड आपकी सीमा से ऊपर हो, कोई कीवर्ड दिखे, या आपका तय किया कोई भी इवेंट हो।

आपकी टीम को कैसे पता चलता है

एक इनबॉक्स; बातचीत हाथ से, बारी-बारी या सबसे कम खुली चैट वाले को सौंपी जाती है; सूचनाएँ ऐप में, Web Push, APNs और निजी Telegram पर।

आपकी टीम ज़िम्मा लेती है

बातचीत देखें, संदर्भ के साथ जुड़ें, उसी चैट में जवाब दें; जब तक कोई व्यक्ति सक्रिय है, असिस्टेंट कोई बदलाव नहीं करता।

इनसाइट्स

बार-बार आने वाले सवाल, जानकारी में कमी और अटकने वाले रास्ते — असली बातचीत से समूहबद्ध, और प्रमाण के लिंक के साथ।

09वर्कस्पेस लॉगिन

अपना उपयोगकर्ता आधार और प्रमाणीकरण अपने पास रखें

कंसोल में वर्कस्पेस के लॉगिन और अकाउंट URL सेट करें। जो अतिथि साइन इन चुनता है, वह फ़्रेम छोड़कर आपके प्रोडक्ट पर प्रमाणित होता है और ठीक उसी URL पर लौट आता है। इसके बाद आपका बैकएंड एक बार इस्तेमाल होने वाला साइन-इन टोकन देता है; Busymate AI को उपयोगकर्ता का पासवर्ड या आपकी हस्ताक्षर कुंजी कभी नहीं मिलती।

कोई भी बदलाव सिर्फ़ साइन-इन उपयोगकर्ता के अपने डेटा को छूता है। अकाउंट टूल ग्राहक की पहचान डेलिगेटेड एक्टर से लेते हैं, हर कॉल पर अधिकार दोबारा जाँचते हैं, और आपके तय किए गए बदलावों पर पुष्टि माँगते हैं।

10लॉन्च चेकलिस्ट

प्रोडक्शन लॉन्च चेकलिस्ट

  1. 01ब्रांडिंग, SEO, अपना वेब पता और सुझाए गए सवाल सेट करें।
  2. 02अपना साइन-इन रजिस्टर करें: जारीकर्ता, JWKS, ऑडियंस, क्लेम और टोकन की उम्र।
  3. 03MCP जोड़ें, हर टूल का एक्सेस स्तर तय करें, और साबित करें कि पढ़ना स्वयं तक सीमित है और बदलाव पुष्टि के साथ होते हैं।
  4. 04हैंडऑफ़ नियम तय करें, इनबॉक्स में टीम लगाएँ, समय और जवाब के लक्ष्य सेट करें।
  5. 05अतिथि, साइन-इन उपयोगकर्ता, लॉगआउट और अकाउंट बदलना, दोहराए गए टोकन और बदले हुए वर्कस्पेस id — सब आज़माएँ।
  6. 06पूरे पेज की चैट, एम्बेड, iOS, Android, डेस्कटॉप, सुलभता और बाहरी लिंक जाँचें।
  7. 07सिर्फ़ वही संस्करण प्रकाशित करें जिसे आपने जाँचा है; कनेक्शन और डोमेन की सेहत पर नज़र रखें।

अपना वर्कस्पेस सेट करने के लिए तैयार हैं?

कंसोल का इंटीग्रेशन पेज आपकी प्रकाशित सेटिंग्स से हर सतह के लिए कोड और सेटिंग्स बना देता है।

कंसोल खोलें

मैनेजमेंट MCP

हर वर्कस्पेस को किसी भी MCP क्लाइंट से संभालिए

OAuth 2.1 के साथ MCP पर 218 मैनेजमेंट टूल। पहली बार जुड़ते समय क्लाइंट ब्राउज़र में साइन-इन खोलता है; कुछ भी चिपकाना नहीं पड़ता।

डिस्कवरी दस्तावेज़

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

आप जिस अकाउंट से साइन इन करते हैं, वही तय करता है कि क्लाइंट कौन-से वर्कस्पेस संभाल सकता है। हर बदलाव पर पुष्टि माँगी जाती है।

Your MCP clientcreate_artifactJSON-RPCcreated: truehttps://your-assistant.busymate.ai/artifact/…VISIBILITYSitemapGallery

Claude Code

claude-code.shbash
claude mcp add --transport http busymate-ai https://busymate.ai/mcp

किसी भी MCP क्लाइंट से प्लेटफ़ॉर्म प्रबंधित करें

Cursor, Claude Desktop और हर वह क्लाइंट जो mcp.json पढ़ता है, यह एंट्री स्वीकार करता है; जो क्लाइंट रिमोट URL लेते हैं, वे ऊपर दिया गया एंडपॉइंट लेते हैं।

mcp.jsonjson
{
  "mcpServers": {
    "platform-management": {
      "type": "http",
      "url": "https://busymate.ai/mcp"
    }
  }
}

अपना पहला टूल आज ही जोड़ें

अपना MCP सर्वर रजिस्टर करें, तय करें कि हर टूल कौन इस्तेमाल कर सकता है, और प्रकाशित करें। असिस्टेंट उसी मिनट से उसका उपयोग कर सकता है।