Geliştiriciler
MCP, yapay zekâyı sistemlerinize bağlamak için açık standarttır: sunucunuzu kaydedin, her aracı kimlerin kullanabileceğini seçin, yayınlayın. Asistanı web, iOS, Android ve masaüstüne gönderin ve her çalışma alanını herhangi bir MCP istemcisinden yönetin.
claude mcp add --transport http busymate-ai https://busymate.ai/mcpBaşlangıç yolları
İzin verdiğiniz her sayfaya tek bir script etiketi — başlatıcı ve konuk sohbeti hemen çalışır.
Hesap kimliği, sohbet ve dokunmayla istenen mikrofon izni için sürümlü Swift paketini kurun.
Hesap kimliği, sohbet ve dokunmayla istenen mikrofon izni için sürümlü Android kitaplığını kurun.
Kendi MCP sunucunuz, her müşteri adına asistanın işlemlerine dönüşür.
Platformu Claude, Claude Code, Cursor veya herhangi bir MCP istemcisinden OAuth ile yönetin.
WebMCP: sayfalarınız kendi eylemlerini araçlar olarak listeler — rezervasyon yapma, sipariş verme, durum kontrol etme — onay dahil.
01Hızlı başlangıç
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.
01
Kimliği ve hesap verilerini tutar; kimin oturum açtığını söyleyen iki dakikalık bir belirteç imzalar.
02
Çalışma alanınızın ayarlarını uygular: içerik, modeller, araç erişim düzeyleri, onay adımları, devir.
03
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
02Oturum açmış müşteriler
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.
Token en fazla 120 saniye süreyle geçerlidir, tek kullanımlık bir nonce ve jti taşır ve çalışma alanınızı adlandırır. Özel anahtar ve ürün oturumunuz hiçbir zaman tarayıcıya veya sohbete ulaşmaz.
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: process.env.BMAI_TENANT_ID, // the tenant id shown in Console → Identity
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(process.env.BMAI_ISSUER) // the Issuer you registered in Console → Identity
.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
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.
<!-- Floating "mate" 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, an access-token/session
// rotation, or an account switch — upgrades the live conversation in
// place, same thread. Do not send an identity postMessage directly.
window.assistantIdentityChanged = () =>
window.BusymateAI?.identityChanged?.() ?? Promise.resolve(false);
// Call after YOUR product completes logout. Without this the signed-out
// visitor keeps a verified chat and the previous transcript until the tab
// closes — a privacy defect, not a missing nicety.
window.assistantSignedOut = () =>
window.BusymateAI?.signedOut?.("signed_out");
</script>
<script
src="https://your-assistant.busymate.ai/embed/v1.js"
data-assistant="your-assistant"
data-label="Ask mate"
async></script>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.
// 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
Swift paketi sürümünü sabitleyin. Kimlik doğrulamalı arka ucunuzu bağlayın ve platform kılavuzu ile örnek uygulamayı kullanarak yerel mikrofon izni ekleyin.
iOS kurulumu, yapılandırması ve demosu
// Swift Package: https://github.com/serebano/busymate-ai-sdk-ios.git (exact 1.0.2)
// Full lifecycle + demo: https://busymate.ai/docs/guides/ios-sdk
import WebKit
import BusymateAI
@MainActor
func installAssistant(
on webView: WKWebView,
account: @escaping () -> String?,
mint: @escaping @MainActor (BusymateBridge.MintRequest) async throws -> BusymateBridge.MintToken?
) {
BusymateBridge.install(on: webView, config: .init(
assistant: "your-assistant",
origins: ["https://your-assistant.busymate.ai"],
account: account,
mint: mint
))
// mint calls YOUR authenticated backend with request.nonce; never cache tokens.
// Backend endpoint: https://YOUR-PRODUCT-DOMAIN/api/bmai/identity
webView.load(URLRequest(url: URL(string: "https://your-assistant.busymate.ai/?channel=ios")!))
}
// Microphone: declare NSMicrophoneUsageDescription; install and retain
// BusymateMicrophone before load, and forward WKUIDelegate media permission.
// Call BusymateBridge.accountChanged() on login/logout/account changes.05Android
Android kitaplığı sürümünü sabitleyin. Sohbeti yüklemeden önce kurun ve Activity yaşam döngüsü, mikrofon ve görüntüleyicinin kurtarılması kılavuzunu izleyin.
Android kurulumu, yapılandırması ve demosu
// Gradle installation + lifecycle: https://busymate.ai/docs/guides/android-sdk
// Source: https://github.com/serebano/busymate-ai-sdk-android/tree/1.0.2
import android.webkit.WebView
import ai.busymate.bridge.BusymateBridge
fun installAssistant(
webView: WebView,
account: () -> String?,
mint: (Map<String, Any?>, (BusymateBridge.MintResult) -> Unit) -> Unit
) {
BusymateBridge.install(webView, BusymateBridge.Config(
assistant = "your-assistant",
origins = listOf("https://your-assistant.busymate.ai"),
account = account,
mint = mint
))
// mint calls YOUR authenticated backend with request["nonce"], then done(result).
// Backend endpoint: https://YOUR-PRODUCT-DOMAIN/api/bmai/identity
webView.loadUrl("https://your-assistant.busymate.ai/?channel=android")
}
// Microphone: declare INTERNET + RECORD_AUDIO; construct and retain
// BusymateMicrophone in Activity.onCreate BEFORE STARTED/loadUrl; forward
// WebChromeClient.onPermissionRequest. See the guide for renderer recovery.
// Call BusymateBridge.accountChanged() on login/logout/account changes.06Masaüstü
macOS, Windows, Electron, Linux ve Tauri için resmi SDK'lar barındırılan sohbeti yalıtılmış bir WebView içinde yükler, kimlik isteklerini ayrıcalıklı ana makine katmanı üzerinden yanıtlar ve güvenli URL'leri dışarıda açar. SDK sürümünü sabitleyin ve kimliği doğrulanmış arka ucunuzu mobildeki gibi bağlayın.
Masaüstü kurulumu, yapılandırma ve örnek uygulamalar
// Official desktop SDK for your platform — macOS, Windows, Electron, Linux or Tauri:
// https://github.com/serebano/busymate-ai-sdk-electron (and -macos, -windows, -linux, -tauri).
// Every SDK takes these settings and installs the identity bridge before the first load.
const chatOptions = {
url: "https://your-assistant.busymate.ai/?channel=desktop_sdk", // the window's top-level page
assistant: "your-assistant",
account: () => productAuth.currentUserId(), // null when signed out
// YOUR authenticated backend signs { token, nonce } for request.nonce.
mint: (request) => productAuth.mintAssistantIdentity(request),
};07MCP araçları
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.
Sohbet eden herkes çağırabilir. Fiyatlar, durum, özellikler.
Oturum açmış bir kullanıcı gerektirir. Sipariş durumu, hesap yanıtları.
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.
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 mate 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.Platform ister sunucunuza istemci olsun ister MCP istemciniz için sunucu, aynı protokol seti geçerlidir.
REST API ve webhook'lar
Tek bir çalışma alanı kapsamlı API anahtarı REST uç noktalarının ve MCP sunucusunun kimliğini doğrular. Sohbetleri listeleyin ve okuyun, operatör yanıtı gönderin veya yoklama yerine webhook'a abone olun.
Console → API anahtarlarında bir anahtar oluşturun, ardından bunu Bearer tokeni olarak gönderin.
curl https://busymate.ai/api/v1/conversations \
-H "Authorization: Bearer bmai_sk_..."Tam referans: API rehberi, webhook'lar, OpenAPI belgesi.
08Devir ve içgörüler
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.
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.
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.
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
Ç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
Ç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.
WebMCP
WebMCP, W3C Web Machine Learning Topluluğu Grubu'nun sayfalarının kendi eylemlerini araçlar olarak listelemesi için hazırladığı taslaktır. En küçük değişiklikten tam denetime kadar üç giriş yolu.
book_appointment, check_order_status, start_return — bir araç, bir iş.
"gelecek salı saat onda", "Express" — asistanın tahmin etmek zorunda olduğu dahili kimlik asla.
Bu sayfanın çalıştırabileceği araçları sunun; sayfa ilerlerken kaydını silin.
Bir rezervasyon, bir ödeme, bir iade: işaretleyin ve müşteri çalışmadan önce onaylar.
Onay müşteri ile kalır. Araçlar ziyaretçinin kendi tarayıcısında, sizin etki alanınızda çalışır. Önemli olarak işaretlediğiniz bir araç, müşterinin gördüğü bir onayda durur; exposedTo hangi etki alanlarının bir aracı görebileceğini sınırlar.
En küçük değişiklik: zaten var olan bir formda bir ad ve tek satırlık açıklama. Tarayıcı onu araça dönüştürür; form görünür kalır ve herkes için çalışmaya devam eder.
<form action="/book" toolname="book_appointment"
tooldescription="Book an appointment for a date, a time and a service."
toolautosubmit>
<input name="date" type="date" toolparamdescription="The day, e.g. next Tuesday">
<input name="time" type="time" toolparamdescription="The start time">
<select name="service" toolparamdescription="Which service to book">
<option>Consultation</option>
<option>Follow-up</option>
</select>
<button type="submit">Book</button>
</form>Tam kontrol: tarayıcı API'si. Özellik algılaması yapın — WebMCP olmayan tarayıcılar sayfayı bugünkü haliyle görürler. Chrome 149 ve Edge 150 bunu bir origin trial olarak taşırlar; Firefox ve Safari teklifi incelemektedir.
// The browser API (draft). Load the polyfill BEFORE this file so every browser has it
// (it stands down where the browser is native):
// <script src="https://busymate.ai/webmcp/polyfill-1.0.1.js" integrity="sha384-pLZ5lO3gwZIn8Nim+hDrUQY+bvpliRtZhrS1O1OGRFB3lvoW0sZ71DUFHIk3m+DG" crossorigin="anonymous"></script>
const ctx = document.modelContext ?? navigator.modelContext;
if (!ctx) throw new Error("no WebMCP registry: the polyfill did not load");
ctx?.registerTool({
name: "start_return",
description: "Start a return for a delivered order. Asks the customer to confirm first.",
inputSchema: { type: "object", properties: { orderNumber: { type: "string", description: "The order number, as printed on the receipt" } }, required: ["orderNumber"] },
annotations: { consequentialHint: true },
execute: async ({ orderNumber }) => startReturn(orderNumber),
}, { exposedTo: ["self"] });Asistan zaten kuruluyken, bir çağrı araçlarınızı onun için ve ziyaret eden diğer tüm asistanlar için listeler — tarayıcı API'sinde var olduğu yerde ve asistanın kendi köprüsü aracılığıyla her yerde.
// One call, both transports: the browser's own WebMCP where it exists,
// and the assistant's bridge everywhere else (Safari, Firefox, app WebViews).
BusymateAI.registerPageTools([
{
name: "check_order_status",
description: "Look up an order by its number and say where it is.",
inputSchema: {
type: "object",
properties: { orderNumber: { type: "string", description: "The order number, as printed on the receipt" } },
required: ["orderNumber"],
additionalProperties: false,
},
annotations: { readOnlyHint: true },
execute: async ({ orderNumber }) => (await fetch(`/api/orders/${orderNumber}`)).json(),
},
]);Benimseme kılavuzu ve kopyala-yapıştır istemiTakımınız için düz dilde hazırlanmış sayfa
Yönetim MCP’si
OAuth 2.1 ile MCP üzerinde yönetim araçları. İstemci ilk bağlantıda bir tarayıcı oturum açma penceresi açar; hiçbir şey yapıştırılmaz.
https://busymate.ai/mcp| İstemci | Nasıl bağlandığı |
|---|---|
| Claude | Bağlayıcıyı Claude'un bağlayıcı dizininden ekleyin ve oturum açın; yapıştırılacak bir şey yok. |
| ChatGPT and Codex | Uygulama OpenAI incelemesinde ve henüz listelenmedi. |
| Claude Code (CLI) | Aşağıdaki komutu çalıştırın — tarayıcı OAuth oturumunu yönetir. |
| Cursor | Aşağıdaki mcp.json girdisini Cursor'ın MCP ayarlarına yapıştırın. |
| Diğer MCP istemcileri | İstemciye aşağıdaki uç noktayı verin; OAuth 2.1 keşfi ve PKCE gerisini işler. |
İstemcinin hangi çalışma alanlarını yönetebileceğine, oturum açtığınız hesap karar verir. Her değişiklik onay ister.
claude mcp add --transport http busymate-ai https://busymate.ai/mcpCursor, Claude Desktop ve bir mcp.json okuyan her istemci bu girdiyi kabul eder; uzak URL alan istemciler yukarıdaki uç noktayı kullanır.
{
"mcpServers": {
"busymate-ai": {
"type": "http",
"url": "https://busymate.ai/mcp"
}
}
}Son değişiklikler
derleme 1628
Write confirmation (preview first, then Apply or yes in chat) now applies only in the ChatGPT and Claude apps. Automations and other connected clients write directly again, and every automated caller fails loudly if it ever gets a preview instead of a write .
derleme 1627
The channel sign-in card can now be translated in every supported language. The sign-in card customers see when they connect from a messaging channel was stuck in English because its translation group was never registered. It is now, so the 14 translations can be published.
derleme 1626
The language-mix check now treats OS and AI-client names as product names. Translation publishing works again after the two-step write change. The automatic translation publisher kept answering "published" while its writes were only previews, so new labels stayed in English until someone re-ran it. It now sends the confirmation and refuses a preview answer.