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/mcpBaş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.
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
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.
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.
<!-- 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.
// 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.
// 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.
// 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.
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.
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.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
- 01Marka, SEO, web adresiniz ve önerilen soruları ayarlayın.
- 02Oturum açma sisteminizi kaydedin: veren, JWKS, hedef kitle, talepler ve belirteç yaşı.
- 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.
- 04Devir kurallarını belirleyin, Gelen kutusuna ekip atayın, çalışma saatlerini ve yanıt hedeflerini tanımlayın.
- 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.
- 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.
- 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.
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
- Korumalı kaynak meta verisi (RFC 9728)
- https://busymate.ai/.well-known/oauth-protected-resource/mcp
İstemcinin hangi çalışma alanlarını yönetebileceğine, oturum açtığınız hesap karar verir. Her değişiklik onay ister.
Claude Code
claude mcp add --transport http busymate-ai https://busymate.ai/mcpPlatformu 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.
{
"mcpServers": {
"platform-management": {
"type": "http",
"url": "https://busymate.ai/mcp"
}
}
}Son değişiklikler
Neler yayımlandı
İ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.