Entwickler
Geben Sie Ihrem KI-Assistenten echte Tools — mit MCP
Geben Sie dem Assistenten echte Tools über MCP, den offenen Standard für die Anbindung von KI an Ihre Systeme. Bringen Sie ihn ins Web, auf iOS, Android und Desktop. Verwalten Sie alles aus jedem MCP-Client.
claude mcp add --transport http busymate-ai https://busymate.ai/mcpEinstiege
Wählen Sie Ihren Startpunkt
Den Assistenten zu Ihrer Website hinzufügen
Ein Script-Tag auf jeder Seite, die Sie freigeben — Launcher und Gast-Chat funktionieren sofort.
KI-Support in Ihre iOS-App holen
Laden Sie den Chat in eine WKWebView; eine kleine Brücke aus drei Nachrichten meldet Ihre Nutzer an.
KI-Support in Ihre Android-App holen
Laden Sie den Chat in eine WebView; eine JavaScript-Schnittstelle meldet Ihre Nutzer an.
Ihren MCP-Server als Tools verbinden
Ihr eigener MCP-Server wird zu den Aktionen des Assistenten, im Auftrag jedes einzelnen Kunden.
Jeden Workspace aus dem Terminal verwalten
Steuern Sie die Plattform aus Claude Code, Cursor oder jedem MCP-Client über OAuth.
KI-Agenten Ihre Website lesen lassen
Eine Textkarte Ihrer Website unter /llms.txt, geschrieben für KI-Agenten.
01Schnellstart
So greift alles ineinander
Ihre App bleibt die Quelle der Wahrheit. Der Assistent erhält ein kurzlebiges signiertes Token, das sagt, wer anwesend ist, und ruft Ihre Tools als eigener, eingegrenzter Actor auf.
01
Ihre App
Hält Identität und Kontodaten; signiert ein Zwei-Minuten-Token, das sagt, wer angemeldet ist.
02
Der Assistent
Wendet die Einstellungen Ihres Workspace an: Inhalte, Modelle, Zugriffsstufen der Tools, Bestätigungsschritte, Übergabe.
03
Ihr MCP-Server
Beantwortet Tools für genau einen Nutzer und nimmt den Nutzer aus dem angemeldeten Bearer-Token — nie aus den Tool-Argumenten.
7 Wege zur Anbindung, ein Assistent: Web-Embed · Angemeldete Kunden · iOS · Android · Desktop · REST-API · Ihr MCP-Server
02Angemeldete Kunden
Erkennen Sie den bereits angemeldeten Kunden
Damit der Assistent weiß, wer fragt, signiert ein authentifizierter Endpunkt in Ihrem Backend ein kurzlebiges Token (ein ES256-JWT) mit Ihrer stabilen Kunden-ID und wenigen unbedenklichen Anzeigefeldern.
Das Token lebt höchstens 120 Sekunden, trägt eine einmalige Nonce und jti und benennt Ihren Tenant. Der private Schlüssel und Ihre Produktsitzung erreichen weder den Browser noch den Chat.
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 });
});Das Token sagt, wer da ist — nicht, was diese Person darf. Halten Sie Guthaben, Geräte, Einstellungen und jede Änderung hinter Tools, die nur für einen Nutzer antworten.
03Web und Vollbild
Ein Script für einen eingebetteten Launcher
Das SDK fragt Ihr Backend nach einer Identität, wenn es eine braucht, funktioniert für Gäste, aktualisiert sich nach Login und Logout, öffnet externe Links außerhalb des Frames und braucht keine Drittanbieter-Cookies.
<!-- 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>Den Vollbild-Chat unter Ihrer Adresse öffnen
Öffnet ein angemeldeter Nutzer die Adresse Ihres Assistenten oder Ihre eigene Domain, übergeben Sie das Anmelde-Token im URL-Fragment. Die Seite löscht es vor dem Austausch.
// 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 mit einer schmalen Nachrichtenbrücke
Erlauben Sie nur die drei versionierten Nachrichten: Identitätsanfrage, Identitätsantwort und externe URL. Erzeugen Sie die Identität über den bestehenden authentifizierten API-Client der App.
// 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 mit einer freigegebenen Schnittstelle
Beschränken Sie die Navigation auf den KI-Ursprung Ihres Mandanten, öffnen Sie externe Links im Systembrowser und stellen Sie keine allgemeinen nativen Methoden bereit.
// 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.06Desktop
Dasselbe Protokoll passt zu Electron, Tauri und nativen Shells
Nutzen Sie eine isolierte WebView, verbieten Sie neue Fenster in der View, öffnen Sie sichere URLs extern und beantworten Sie Identitätsanfragen über die privilegierte Host-Schicht.
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-Tools
Geben Sie dem Assistenten Tools, ohne ihm Ihre Kundendatenbank zu geben
Veröffentlichen Sie vollständige Schemata bei der Discovery. Geben Sie jedem Tool eine von drei Zugriffsstufen, markieren Sie die Änderungen, die eine Bestätigungskarte brauchen, und prüfen Sie die Autorisierung bei jedem Aufruf erneut.
Öffentlich
Jeder im Chat darf es aufrufen. Preise, Status, Funktionen.
Identifiziert
Braucht einen angemeldeten Nutzer. Bestellstatus, Kontoauskünfte.
Delegiert
Handelt im Auftrag des angemeldeten Nutzers über ein eingegrenztes Actor-Token oder die eigene OAuth-Berechtigung des Nutzers.
Jede Änderung wird auf dem Server bestätigt. Tools, die Sie in confirm_tools eintragen, halten vor der Ausführung an einer Bestätigungskarte an; ebenso jeder Tool-Name, den der Assistent nicht kennt. Widget-Frames führen nie eine Änderung aus.
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.Was die Plattform spricht
Dieselben Protokolle gelten, ob die Plattform Client zu Ihrem Server ist oder Server für Ihren MCP-Client.
- OAuth 2.1 mit PKCE (S256); öffentliche Clients registrieren sich dynamisch (RFC 7591).
- Discovery über Authorization-Server-Metadaten (RFC 8414) und Protected-Resource-Metadaten (RFC 9728).
- Grants: authorization_code und refresh_token; die Autorisierungsantwort trägt den Issuer (RFC 9207).
- Resource Indicators (RFC 8707), wenn die Plattform der OAuth-Client zu Ihrem MCP-Server ist.
- Token Exchange (RFC 8693), wo konfiguriert.
08Übergabe und Insights
Legen Sie fest, wann ein Mensch übernimmt
Wann übergeben wird
Ein Kunde bittet um einen Menschen, ein Tool schlägt fehl, eine Rückerstattung liegt über Ihrem Limit, ein Stichwort taucht auf, oder ein beliebiges Ereignis, das Sie festlegen.
Wie Ihr Team benachrichtigt wird
Eine Inbox; Zuweisung von Hand, reihum oder an die Person mit den wenigsten offenen Chats; Hinweise in der App, per Web Push, APNs und persönlichem Telegram.
Ihr Team übernimmt
Das Gespräch mitlesen, mit dem Kontext einsteigen, im selben Chat antworten; der Assistent nimmt keine Änderungen vor, solange ein Mensch aktiv ist.
Insights
Wiederkehrende Fragen, fehlendes Wissen und gescheiterte Wege, gruppiert aus echten Gesprächen, mit Links zu den Belegen.
09Workspace-Login
Behalten Sie Ihre eigene Nutzerbasis und Authentifizierung
Konfigurieren Sie Login- und Konto-URLs des Workspace in der Console. Ein Gast, der Anmelden wählt, verlässt den Frame, authentifiziert sich in Ihrem Produkt und kehrt genau zur Ausgangs-URL zurück. Ihr Backend liefert dann ein einmaliges Anmelde-Token; Busymate AI erhält nie das Passwort des Nutzers oder Ihren Signaturschlüssel.
Eine Änderung berührt immer nur die eigenen Daten des angemeldeten Nutzers. Konto-Tools nehmen den Kunden aus dem delegierten Actor, prüfen die Autorisierung bei jedem Aufruf erneut und fragen bei den Änderungen nach, die Sie festlegen.
10Start-Checkliste
Checkliste für den Produktivstart
- 01Branding, SEO, Web-Adresse und vorgeschlagene Fragen einrichten.
- 02Ihre Anmeldung registrieren: Issuer, JWKS, Audience, Claims und Token-Alter.
- 03MCP verbinden, für jedes Tool die Zugriffsstufe setzen, sicherstellen, dass Lesezugriffe auf den eigenen Nutzer beschränkt sind und Änderungen bestätigt werden.
- 04Übergaberegeln festlegen, die Inbox besetzen, Zeiten und Reaktionsziele setzen.
- 05Gäste, angemeldete Nutzer, Logout und Kontowechsel, wiederverwendete Token und eine vertauschte Workspace-ID testen.
- 06Vollbild-Chat, Embed, iOS, Android, Desktop, Barrierefreiheit und externe Links prüfen.
- 07Nur die geprüfte Version veröffentlichen; Verbindungs- und Domain-Zustand im Blick behalten.
Bereit, Ihren Workspace einzurichten?
Die Integrationsseite der Console erzeugt aus Ihren veröffentlichten Einstellungen den Code und die Einstellungen für jede Oberfläche.
Management-MCP
Jeden Workspace aus jedem MCP-Client verwalten
218 Management-Tools über MCP mit OAuth 2.1. Der Client öffnet bei der ersten Verbindung eine Anmeldung im Browser; nichts wird eingefügt.
Discovery-Dokumente
- MCP-Endpunkt
- https://busymate.ai/mcp
- Authorization-Server-Metadaten (RFC 8414)
- https://busymate.ai/.well-known/oauth-authorization-server/mcp
- Protected-Resource-Metadaten (RFC 9728)
- https://busymate.ai/.well-known/oauth-protected-resource/mcp
Das Konto, mit dem Sie sich anmelden, bestimmt, welche Workspaces der Client verwalten darf. Jede Änderung fragt nach einer Bestätigung.
Claude Code
claude mcp add --transport http busymate-ai https://busymate.ai/mcpVerwalten Sie die Plattform über jeden MCP-Client
Cursor, Claude Desktop und jeder Client, der eine mcp.json liest, akzeptieren diesen Eintrag; Clients, die eine Remote-URL erwarten, nehmen den Endpunkt oben.
{
"mcpServers": {
"platform-management": {
"type": "http",
"url": "https://busymate.ai/mcp"
}
}
}Neueste Änderungen
Was neu ist
Verbinden Sie heute Ihr erstes Tool
MCP-Server registrieren, festlegen, wer welches Tool nutzen darf, veröffentlichen. Der Assistent kann es in derselben Minute nutzen.