Busymate AI

Geliştiriciler

Yapay zekâ asistanınıza MCP ile gerçek araçlar verin

Yapay zekâyı sistemlerinize bağlamanın açık standardı olan MCP üzerinden asistana gerçek araçlar verin. Web’de, iOS’ta, Android’de ve masaüstünde yayına alın. Her şeyi herhangi bir MCP istemcisinden yönetin.

claude mcp add --transport http busymate-ai https://busymate.ai/mcp
TERMİNAL$claude mcp add --transport http busymate-ai https://busymate.ai/mcpbağlandı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": "…" }] } }

Başlangıç yolları

Nereden başlayacağınızı seçin

Asistanı web sitenize ekleyin

İzin verdiğiniz her sayfaya tek bir script etiketi — başlatıcı ve konuk sohbeti hemen çalışır.

iOS uygulamanızın içine yapay zekâ desteği koyun

Sohbeti bir WKWebView’de yükleyin; küçük, üç mesajlık bir köprü kullanıcılarınızın oturumunu açar.

Android uygulamanızın içine yapay zekâ desteği koyun

Sohbeti bir WebView’de yükleyin; tek bir JavaScript arayüzü kullanıcılarınızın oturumunu açar.

MCP sunucunuzu araç olarak bağlayın

Kendi MCP sunucunuz, her müşteri adına asistanın işlemlerine dönüşür.

Her çalışma alanını terminalinizden yönetin

Platformu Claude Code, Cursor ya da herhangi bir MCP istemcisinden OAuth üzerinden kullanın.

Yapay zekâ ajanlarının sitenizi okumasını sağlayın

/llms.txt adresinde, yapay zekâ ajanları için yazılmış düz metin bir site haritası.

01Hızlı başlangıç

Parçalar nasıl birleşiyor

Doğruluk kaynağı uygulamanız olarak kalır. Asistan, kimin orada olduğunu söyleyen kısa ömürlü imzalı bir belirteç alır ve araçlarınızı ayrı, kapsamı sınırlı bir aktör olarak çağırır.

MüşterilerinizWeb siteniz ya da uygulamanızAsistanSistemlerinizAyarlarınızotomatik uygulanır

01

Uygulamanız

Kimliği ve hesap verilerini tutar; kimin oturum açtığını söyleyen iki dakikalık bir belirteç imzalar.

02

Asistan

Çalışma alanınızın ayarlarını uygular: içerik, modeller, araç erişim düzeyleri, onay adımları, devir.

03

MCP sunucunuz

Araçları her seferinde tek bir kullanıcı için yanıtlar; kullanıcıyı araç argümanlarından değil, oturum açmış taşıyıcı belirteçten alır.

Bağlanmanın 7 yolu, tek asistan: Web gömme · Oturum açmış müşteriler · iOS · Android · Masaüstü · REST API · MCP sunucunuz

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

02Oturum açmış müşteriler

Zaten oturum açmış müşteriyi tanıyın

Asistanın kimin sorduğuna güvenebilmesi için, arka ucunuzdaki kimliği doğrulanmış tek bir uç nokta, sabit müşteri kimliğiniz ve birkaç güvenli görüntüleme alanıyla kısa ömürlü bir belirteç (bir ES256 JWT) imzalar.

Belirteç en fazla 120 saniye yaşar, tek kullanımlık bir nonce ve jti taşır ve kiracınızı adlandırır. Özel anahtar ve ürün oturumunuz tarayıcıya ya da sohbete asla ulaşmaz.

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

Belirteç kimin orada olduğunu söyler, neler yapabileceğini değil. Bakiyeleri, cihazları, ayarları ve her değişikliği yalnızca tek bir kullanıcı için yanıt veren araçların arkasında tutun.

03Web ve tam sayfa

Gömülü başlatıcı için tek bir script

SDK kimliğe ihtiyaç duyduğunda arka ucunuzdan ister, konuklar için çalışır, giriş ve çıkıştan sonra yenilenir, dış bağlantıları çerçevenin dışında açar ve üçüncü taraf çerezine ihtiyaç duymaz.

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>

Tam sayfa sohbeti kendi adresinizde açın

Oturum açmış bir kullanıcı asistanınızın adresini ya da özel alan adınızı açtığında, oturum belirtecini URL parçasında iletin. Sayfa, değişimden önce onu temizler.

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

Dar bir mesaj köprüsüne sahip WKWebView

Yalnızca sürümlenmiş üç mesaja izin verin: kimlik isteği, kimlik yanıtı ve dış URL. Kimliği, uygulamanın mevcut kimliği doğrulanmış API istemcisi üzerinden üretin.

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

İzin listesine alınmış tek arayüzlü WebView

Gezinmeyi kiracı AI kaynağında tutun, dış bağlantıları sistem tarayıcısına gönderin ve genel amaçlı yerel yöntemler sunmayın.

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.

06Masaüstü

Aynı protokol Electron, Tauri ve yerel kabuklara uyar

Yalıtılmış bir WebView kullanın, görünüm içinde yeni pencereleri reddedin, güvenli URL’leri dışarıda açın ve kimlik isteklerini ayrıcalıklı ana katman üzerinden yanıtlayın.

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 araçları

Asistana müşteri veritabanınızı vermeden araçlar verin

Keşif aşamasında eksiksiz şemalar yayımlayın. Her araca üç erişim düzeyinden birini verin, onay kartı gerektiren değişiklikleri işaretleyin ve her çağrıda yetkiyi yeniden doğrulayın.

Herkese açık

Sohbet eden herkes çağırabilir. Fiyatlar, durum, özellikler.

Tanımlı

Oturum açmış bir kullanıcı gerektirir. Sipariş durumu, hesap yanıtları.

Yetkilendirilmiş

Kapsamı sınırlı bir aktör belirteci ya da kullanıcının kendi OAuth izniyle, oturum açmış kullanıcı adına hareket eder.

Her değişiklik sunucuda onaylanır. confirm_tools içinde listelediğiniz araçlar çalışmadan önce bir onay kartında durur; asistanın tanımadığı her araç adı da öyle. Bileşen çerçeveleri asla bir değişiklik çalıştırmaz.

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.

Platformun konuştuğu diller

Platform ister sunucunuza istemci olsun ister MCP istemciniz için sunucu, aynı protokol seti geçerlidir.

  • PKCE (S256) ile OAuth 2.1; genel istemciler dinamik olarak kaydolur (RFC 7591).
  • Yetkilendirme sunucusu meta verisi (RFC 8414) ve korumalı kaynak meta verisi (RFC 9728) üzerinden keşif.
  • İzinler: authorization_code ve refresh_token; yetkilendirme yanıtı vereni taşır (RFC 9207).
  • Platform, MCP sunucunuza karşı OAuth istemcisi olduğunda kaynak göstergeleri (RFC 8707).
  • Yapılandırıldığı yerde belirteç değişimi (RFC 8693).

08Devir ve içgörüler

Bir insanın ne zaman devreye gireceğinin kurallarını belirleyin

Ne zaman devreder

Bir müşteri insan ister, bir araç başarısız olur, bir iade limitinizin üzerindedir, bir anahtar kelime geçer ya da tanımladığınız herhangi bir olay gerçekleşir.

Ekibinize nasıl haber verilir

Tek bir Gelen kutusu; elle, sırayla ya da en az açık sohbeti olana atama; uygulama içinde, Web Push, APNs ve kişisel Telegram üzerinden uyarılar.

Ekibiniz devralır

Görüşmeyi izleyin, bağlamıyla birlikte katılın, aynı sohbette yanıtlayın; bir insan etkinken asistan hiçbir değişiklik yapmaz.

İçgörüler

Tekrarlayan sorular, eksik bilgiler ve başarısız yollar; gerçek görüşmelerden gruplanır ve kanıtlara bağlantı verir.

09Çalışma alanı oturumu

Kendi kullanıcı tabanınızı ve kimlik doğrulamanızı koruyun

Çalışma alanının oturum açma ve hesap URL’lerini Console’da yapılandırın. Oturum aç’ı seçen bir konuk çerçeveden çıkar, sizin ürününüzde kimliğini doğrular ve tam olarak geldiği URL’ye döner. Ardından arka ucunuz tek kullanımlık bir oturum belirteci sağlar; Busymate AI kullanıcının parolasını ya da imzalama anahtarınızı asla almaz.

Bir değişiklik yalnızca oturum açmış kullanıcının kendi verisine dokunur. Hesap araçları müşteriyi yetkilendirilmiş aktörden alır, her çağrıda yetkiyi yeniden doğrular ve yapılandırdığınız değişikliklerde onay ister.

10Canlıya çıkış listesi

Canlıya çıkış kontrol listesi

  1. 01Marka, SEO, web adresiniz ve önerilen soruları ayarlayın.
  2. 02Oturum açma sisteminizi kaydedin: veren, JWKS, hedef kitle, talepler ve belirteç yaşı.
  3. 03MCP’yi bağlayın, her aracın erişim düzeyini belirleyin, okumaların kendi kapsamıyla sınırlı, yazmaların onaylı olduğunu kanıtlayın.
  4. 04Devir kurallarını belirleyin, Gelen kutusuna ekip atayın, çalışma saatlerini ve yanıt hedeflerini tanımlayın.
  5. 05Konukları, oturum açmış kullanıcıları, çıkışı ve hesap değiştirmeyi, yeniden oynatılan belirteçleri ve değiştirilmiş bir çalışma alanı kimliğini test edin.
  6. 06Tam sayfa sohbeti, gömülü bileşeni, iOS’u, Android’i, masaüstünü, erişilebilirliği ve dış bağlantıları kontrol edin.
  7. 07Yalnızca kontrol ettiğiniz sürümü yayımlayın; bağlantı ve alan adı sağlığını izleyin.

Çalışma alanınızı kurmaya hazır mısınız?

Console’un Entegrasyon sayfası, yayımladığınız ayarlardan her yüzey için kodu ve ayarları üretir.

Console’u aç

Yönetim MCP’si

Her çalışma alanını herhangi bir MCP istemcisinden yönetin

OAuth 2.1 ile MCP üzerinden 218 yönetim aracı. İstemci ilk bağlantıda tarayıcıda bir oturum açma penceresi açar; hiçbir şey yapıştırılmaz.

Keşif belgeleri

MCP uç noktası
https://busymate.ai/mcp
Yetkilendirme sunucusu meta verisi (RFC 8414)
https://busymate.ai/.well-known/oauth-authorization-server/mcp

İstemcinin hangi çalışma alanlarını yönetebileceğine, oturum açtığınız hesap karar verir. Her değişiklik onay ister.

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

Platformu herhangi bir MCP istemcisinden yönetin

Cursor, Claude Desktop ve bir mcp.json okuyan her istemci bu girdiyi kabul eder; uzak URL alan istemciler yukarıdaki uç noktayı kullanır.

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

İlk aracınızı bugün bağlayın

MCP sunucunuzu kaydedin, her aracı kimin kullanabileceğini seçin, yayımlayın. Asistan onu aynı dakika kullanabilir.