Zum Inhalt springen

Apps

Für Entwickler, die einen Client mit OpenBot verbinden oder den Server erweitern. Die Beispiele brauchen die auf dieser Seite genannten Rechte. Beginne mit dem Entwicklerhandbuch.

Eine App ist ein externer Dienst, den der Bot nutzen kann. Jede App ist im Web mit dem OpenBot App Protocol veröffentlicht. Diese Seite zeigt dir, wie du eine App mit deinem Konto verbindest, dich bei ihr anmeldest und sie in Turns nutzt.

Alle Beispiele nutzen ein Nutzer-Token. Dieselben Aufrufe funktionieren auch mit dem Session-Cookie. Siehe Authentifizierung.

Wort Bedeutung
Card URL Die feste HTTPS-Adresse der Server Card der App. Sie ist die Identität der App.
Connection Eine App, die in deinem Konto gespeichert ist, mit deinen Einstellungen und deiner Anmeldung. Du kannst bis zu 30 haben.
Connection draft Ein gespeichertes Ergebnis der Suche. Du prüfst es, bevor du eine Connection erstellst. Es gilt 24 Stunden.
App operation Ein gespeicherter Aufruf aus einem Turn an eine App, mit seinem Status und Ergebnis.

Gib OpenBot die Adresse der App. Das kann eine Domain sein, eine Seite der App, ein Link zu einem Catalog oder ein Link zu einer Card. Ein QR-Code enthält denselben HTTPS-Link.

Terminal window
curl -X POST https://api.example.com/v1/connection-drafts \
-H "Authorization: Bearer $OPENBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "input": "apps.example.com" }'

Die Antwort ist ein Entwurf (Draft) mit dem Status 201. Behalte seine id und revision. Das Feld discovery hat eine von zwei Arten:

  • Single hat einen candidate.
  • Multiple hat eine Liste candidates. Bitte den Nutzer, einen auszuwählen. OpenBot fügt nie einen ganzen Catalog hinzu.

Jeder Kandidat hat eine cardUrl, die card, eine Liste endpoints und die sources, die zu ihm geführt haben. Jeder Endpoint hat einen index und die requirements, die er braucht, zum Beispiel einen Header für einen API-Schlüssel.

Wenn du nur schauen willst, ohne einen Entwurf zu speichern, schicke denselben Body an POST /v1/apps/discover. Die Suche fügt nie eine App hinzu, meldet sich nie an und ruft nie eine App auf.

draftId muss die UUID des gespeicherten Entwurfs sein. Alte v4- und neue v7-Werte funktionieren. Die API weist anderen Text vor dem Zugriff auf die Speicherung zurück. Externe Connection-IDs behalten ihr bisheriges Format.

Zeige dem Nutzer den Namen der App, ihre Quelle und den Endpoint. Erstelle dann die Connection (Verbindung). Du musst "confirmed": true schicken.

Terminal window
curl -X POST https://api.example.com/v1/connections \
-H "Authorization: Bearer $OPENBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"draftId": "<draft id>",
"revision": 0,
"cardUrl": "https://apps.example.com/mcp/server-card",
"remoteIndex": 0,
"name": "Work calendar",
"values": { "header:X-API-Key": "<secret>" },
"confirmed": true
}'

Die Keys in values kommen aus den requirements des Endpoint. Sie sehen so aus: variable:<name>, header:<name> oder header:<name>:variable:<name>. OpenBot verschlüsselt diese Werte. Spätere Lese-Aufrufe zeigen nur Werte, die nicht geheim sind.

OpenBot liest die Card noch einmal, bevor es speichert. Die neue Connection nutzt die id des Entwurfs als eigene id. Wenn du denselben Request noch einmal schickst, bekommst du dieselbe Connection zurück.

Terminal window
curl -X POST https://api.example.com/v1/connections/<connection id>/verify \
-H "Authorization: Bearer $OPENBOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"commandKey":"check-connection-1"}'

Änderungen und Prüfungen einer Verbindung sind dauerhafte Befehle. verify, revalidate, PUT /v1/connections/:connectionId und der Endpunkt für manuelle Änderungen brauchen einen commandKey. Sie geben HTTP 202 mit einer executionId zurück. Nutze bei Netzfehlern denselben Schlüssel erneut. Lies den Fortschritt unter /v1/executions/:executionId/observe. Das Schließen des Streams bricht den Befehl nicht ab. Nutze dafür den Abbruch-Endpunkt der Ausführung.

Lies das gespeicherte Ergebnis mit GET /v1/connections/:connectionId/executions/:executionId. Die Antwort enthält execution und result. Eine fertige Prüfung gibt Verified mit den Listen der Fähigkeiten oder Unavailable zurück. Lies die Verbindung, um ihren aktuellen Zustand zu sehen. Eine fertige Änderung gibt Updated mit der neuen Revision zurück. Die SDK-Helfer Connections.verify, update, updateManual und revalidate erstellen einen Schlüssel pro Befehl. Eine Verbindung nimmt nur eine Änderung zugleich an. Änderungen, manuelle Änderungen und erneute Validierung brauchen die aktuelle Revision. Eine Prüfung braucht nur ihren Befehlsschlüssel.

Status Fehler Was du tun kannst
409 ConnectionConflict Lies reason: CandidateChanged, RevisionChanged, DraftExpired, AlreadyAdded oder LimitReached.
422 ConnectionConfigurationInvalid Fülle die Einstellungen aus, deren Namen in keys stehen.
422 AppDiscoveryFailed Prüfe die Adresse. reason und issues sagen, was fehlgeschlagen ist.
403 AppRestricted Die Installation sperrt diese App. Siehe restriction.reason und restriction.appealUrl.

Das Feld availability sagt dir, ob der Bot eine Connection nutzen kann.

_tag Bedeutung
Unverified Gespeichert, aber noch nicht geprüft.
Available Geprüft und bereit.
PendingAuthorization Die App braucht eine Anmeldung mit einem Konto. scopes listet den Zugang, den sie verlangt.
AuthorizationExpired Die Anmeldung funktioniert nicht mehr. Erneuere sie oder melde dich neu an.
ConnectionFailed Die letzte Prüfung ist fehlgeschlagen. message sagt, warum.
NeedsRevalidation Die App hat ihren Endpoint oder ihre Anmelde-Anforderungen geändert. Prüfe sie noch einmal.
CleanupPending Das Entfernen ist nicht fertig geworden. Versuche noch einmal, sie zu entfernen.
Restricted Die Installation sperrt diese App.
PendingConfiguration Die Connection braucht mehr Einstellungen.

Nach der Annahme eines Befehls steht ein Fehler in der Ausführung, mit einer sicheren category und einer errorId. Anbietertext und volle Ursache bleiben im verschlüsselten Fehlerdatensatz. Sind die Plattform-Einstellungen nicht lesbar, gibt das Lesen der OAuth-Client-Metadaten 503 SettingsUnavailable.

Wenn du @openbot-build/protocol allein nutzt, haben MCP-Fehler eine sichere ClientError-Meldung. Netzwerk-, SDK- und Schema-Details bleiben in einer privaten Cause. Sie enthält alle Gründe des Fehlers. Diese Details kommen nicht in das normale Log oder das öffentliche Fehlerschema.

Client.errorCause(error) gibt eine Option mit einer Redacted<Cause> zurück, wenn der Fehler private Details hat. Nur ein vertrauenswürdiger Fehlerhandler soll diesen Wert öffnen. Verschlüssele ihn vor dem Speichern. Client.withCause(error, cause) lässt deinen Protokolladapter Details auf dieselbe Weise behalten. OpenBot speichert sie im verschlüsselten Fehlerdatensatz. Der öffentliche Index behält dieselbe private Ursache an einem Unconfirmed- Ergebnis. reason und der feste Text in issue sind sicher für die Anzeige. Der Host muss die private Ursache speichern, bevor er das Ergebnis codiert.

Manche Apps brauchen das eigene Konto des Nutzers. OpenBot nutzt dafür OAuth mit PKCE. Der Nutzer meldet sich beim Anbieter der App an, nicht bei OpenBot.

  1. Starte den Ablauf. Schicke die revision der Connection. Lass scopes leer, um die Scopes zu nutzen, die die App verlangt. returnTo ist ein Pfad mit demselben Ursprung. Der Standard ist /.

    Terminal window
    curl -X POST https://api.example.com/v1/connections/<connection id>/authorization \
    -H "Authorization: Bearer $OPENBOT_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{ "commandKey": "begin-app-sign-in-1", "revision": 0, "scopes": [], "returnTo": "/apps" }'
  2. Die Antwort ist HTTP 202 mit einem Ausführungsbeleg. Lies GET /v1/app-authorization-actions/:executionId bis zum Abschluss und dann result. Der Link ist erst nach dem Speichern des Ablaufs verfügbar. Nutze bei einer verlorenen Antwort denselben Befehlsschlüssel und Inhalt:

    • AuthorizationStarted hat eine flowId und eine authorizationUrl. Öffne die URL im Browser des Nutzers.
    • IssuerSelectionRequired listet issuers. Bitte den Nutzer, einen auszuwählen. Starte dann noch einmal mit issuer.
    • AuthorizationNotRequired heißt, dass die App keine Anmeldung braucht.
  3. Der Nutzer meldet sich an. Der Anbieter schickt den Browser an https://api.example.com/auth/apps/callback.

  4. OpenBot schickt den Browser an returnTo?authorization=<flowId>. Wenn der Browser keine OpenBot-Session hat, geht er zu /?authorization=<flowId>. Dein Client meldet den Nutzer zuerst an (siehe Authentifizierung).

  5. Dein Client beendet den Ablauf:

    Terminal window
    curl -X POST https://api.example.com/v1/app-authorizations/<flow id>/complete \
    -H "Authorization: Bearer $OPENBOT_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{ "commandKey": "finish-app-sign-in-1" }'

Um den Ablauf zu sehen, rufe GET /v1/app-authorizations/:flowId auf. Sein status ist Waiting, Received, Processing, Succeeded, Cancelled oder Failed. Der Abschluss gibt HTTP 202 mit einer Ausführungsquittung zurück. Nutze bei einer verlorenen Antwort denselben commandKey. Ein angemeldeter Callback sendet den Befehl mit dem ursprünglichen Aufrufer. Dessen Token begrenzt die Rechte weiter. executionId verweist auf die gemeinsame Ausführungs-API. GET /v1/app-authorization-actions/:executionId gibt Zustand und sicheres Ergebnis zurück. Das Schließen eines Beobachters bricht den Befehl nicht ab. Nutze dafür die Abbruch-API der Ausführung. Ein unbekanntes Ergebnis beim Code-Austausch wartet auf eine Entscheidung. Der Code wird nicht von selbst erneut gesendet.

Die OAuth-Client-ID von OpenBot ist ein öffentliches Dokument unter https://api.example.com/v1/apps/client-metadata. Anbieter lesen es. Darum musst du OpenBot nicht bei jedem Anbieter registrieren.

Um dich bei der App abzumelden, sende DELETE /v1/connections/:connectionId/authorization mit { "commandKey" }. Die Antwort ist HTTP 202. OpenBot schließt aktive App-Scopes. Dann löscht es die lokale Anmeldung und speichert die entfernte Bereinigung in einer Transaktion. Lies GET /v1/app-authorization-actions/:executionId. Die execution kann completed sein, während result noch RevocationPending ist. Das Feld cleanupExecutions gibt die gespeicherten Zustände der Bereinigung. Nach deren Ende ist das Ergebnis Revoked, oder LocalOnly, wenn der Anbieter keine Tokens widerrufen kann.

Die Bereinigung wartet, solange eine Verbindung oder ein Entwicklertest in einem OpenBot-Konto denselben Aussteller und dieselbe OAuth-Client-ID nutzt. Ein Anbieter kann verwandte Tokens zusammen widerrufen. Verschiedene Tokenwerte zeigen nicht, dass ein Widerruf sicher ist. Fehlgeschlagene entfernte Aufrufe nutzen gespeicherte Timer für neue Versuche. Auch eine Erneuerung speichert die Bereinigung der alten Zugangsdaten. Das lokale Entfernen kann davor enden.

Jede Bereinigung gehört zur Organisation des Quellvorgangs. Ein Dienst führt die Arbeit aus. Du kannst Zustand und Ereignisse nur lesen, wenn die aktuellen Regeln dir das Lesen des Quellvorgangs erlauben. Andere Organisationen können diese Ausführung nicht finden.


Aufgabe Request
Auflisten oder lesen GET /v1/connections, GET /v1/connections/:connectionId
Umbenennen, aus- oder einschalten PUT /v1/connections/:connectionId mit { "commandKey", "revision", "name", "enabled" }
Die Anmeldung erneuern POST /v1/connections/:connectionId/refresh
Eine geänderte App prüfen Erstelle einen neuen Entwurf aus der Card URL. Dann POST /v1/connections/:connectionId/revalidate.
Entfernen DELETE /v1/connections/:connectionId

Eine Erneuerung nimmt { "commandKey" } an und gibt HTTP 202 zurück. Das Ergebnis ist Refreshed. Sie verlangt keine weiteren Rechte. Sie kann das alte Token aufbrauchen. Ein unbekanntes Ergebnis wartet daher auf eine Entscheidung. Endet die Arbeit nach dem Senden ohne neue Zugangsdaten, wird die Verbindung deaktiviert und als AuthorizationExpired markiert. Melde sie erneut an. Die SDK-Helfer AppAuthorizations.begin, complete, refresh und revoke behalten einen Befehlsschlüssel für Netzwerkwiederholungen.

Wenn eine App ihren Endpoint, private Einstellungen, ihren Anbieter oder ihre Scopes ändert, wird die Connection NeedsRevalidation. Der Bot kann sie nicht nutzen, bis du sie prüfst. Schicke { "commandKey", "revision", "draftId", "remoteIndex", "values", "confirmed": true } an revalidate. OpenBot schickt keine alten Tokens an einen neuen Endpoint. Eine App, die eine Anmeldung braucht, braucht dann eine neue Anmeldung.

Entfernen nimmt { "commandKey" } an und gibt HTTP 202 zurück. OpenBot schaltet die Verbindung aus und schließt ihre aktiven App-Scopes auf allen Knoten. Antwortet ein Knoten nicht, bleibt dieser Schritt offen. Gespeicherte Ergebnisse bleiben nach verlorenen Antworten lesbar. Die letzte Transaktion löscht die Verbindung und lokale Tokens und übergibt die entfernte Bereinigung an eine eigene Ausführung. Removed bedeutet, dass das lokale Entfernen fertig ist. Es bestätigt nicht den Widerruf aller entfernten Freigaben. Lies dafür cleanupExecutions in der Berechtigungsaktion. Nutze nach verlorenen Antworten denselben Schlüssel. Ein Abbruch vor dem Entfernen lässt die Verbindung aus. Ein neuer Befehl kann das Entfernen beenden.

Ein geschlossener App-Client behält das volle Ergebnis des Schließens. Der Aufrufer kann seinen Scope nach dem Ende des Servers erneut schließen, ohne bereits beendete Dienste aufzurufen. Schlug das erste Schließen fehl, geben spätere Aufrufe diesen Fehler weiter.

Du kannst auch einen MCP-Server verbinden, der keine Server Card hat. Schicke POST /v1/connections/manual mit einer neuen UUID als id, einem name, der HTTPS-url, "transport": "streamable-http" und headers. Ändere sie mit PUT /v1/connections/:connectionId/manual mit commandKey, der aktuellen revision und der vollständigen neuen Konfiguration. null behält den bisherigen Header-Wert. Lasse einen Header aus headers weg, um ihn zu entfernen. Ein neuer Header braucht einen Wert. Manuelle Connections kommen nie in den öffentlichen App Index.


Wenn ein Turn läuft, gibt OpenBot dem Modell ein Tool für jede Fähigkeit deiner nutzbaren Connections. Jeder Tool-Name sieht so aus: openbot_<hash>. Seine Beschreibung beginnt mit dem Namen der App, dem Namen der Connection und dem Namen der Fähigkeit.

  • Tools werden zu Tools, die das Modell aufrufen kann. Tools, deren visibility kein model enthält, bleiben für das Modell versteckt.
  • Resources, resource templates und prompts werden zu Lese-Tools.

Jeder Aufruf eines App-Tools geht zuerst durch die Prüfung der Fähigkeit. Der erste Aufruf eines Tools macht meistens einen Request, den ein Entscheider beantwortet. Ein Grant oder eine Rule kann dann spätere Aufrufe abdecken. Das Lesen von Resources und Prompts braucht keine Entscheidung. Das gilt auch für Tools, die die Organization in ihren Einstellungen als Lesen markiert hat. Hinweise der App entscheiden das nie. Jedes App-Tool hat einen zusätzlichen Parameter openbot_reason für den Grund des Bot. OpenBot schickt ihn nie an die App.

Das Modell bekommt auch drei Helfer-Tools. Sie fügen nie eine App hinzu, melden sich nie an und geben nie eine Aktion frei.

Tool Was es tut
openbot_search_apps Sucht im öffentlichen App Index nach einer fehlenden Fähigkeit.
openbot_app_details Liest die öffentlichen Details und Quellen einer App über ihre Card URL.
openbot_app_access Listet die Connections des Nutzers und was sie zum Einrichten oder Anmelden brauchen.

Wenn die Platform Code Mode einschaltet, bekommt das Modell auch openbot_code_api und openbot_run_code. Damit schreibt der Bot ein kurzes Programm, das diese Tools der Apps aufruft. Jeder Aufruf im Programm nimmt denselben Weg wie ein normaler Aufruf eines App-Tools.

Jeder App-Aufruf hat eine Geschäfts-ID id und eine executionId. Lesen Sie ihn mit GET /v1/chats/:chatId/app-operations oder GET /v1/app-operations/:id. Das Ergebnis hat den gemeinsamen Ausführungsstatus status, einen sicheren failure mit Fehler-ID und result. Mit der Ausführungs-API lesen Sie Ereignisse, stoppen Arbeit und entscheiden über unbekannte externe Ergebnisse.

Wenn die App Eingaben braucht, ist result._tag gleich InputRequired. Die Frage steht in result.request. Senden Sie die Antwort mit dieser round und einem neuen commandKey. Bei einem verlorenen Empfangsbeleg verwenden Sie denselben Schlüssel und Inhalt erneut.

{
"commandKey": "input-answer-1",
"round": 1,
"responses": {
"<input key>": { "action": "accept", "content": { "label": "Team sync" } }
}
}

Senden Sie dies an POST /v1/app-operations/:id/inputs. Die Antwort ist 202 mit einem Ausführungsbeleg. Die App ist damit noch nicht fertig. Beobachten Sie die Ausführung bis zum Ende. AppCalls.respond im SDK erzeugt einen Schlüssel und behält ihn bei Netzwerkfehlern. Die Antworten folgen dem MCP-Eingabeschema.

Eine Ausführung mit outcome_unknown wartet auf eine Entscheidung. Prüfen Sie vor einem neuen Versuch den externen Zustand. Sie sendet einen unbestätigten Schreibaufruf nicht selbst erneut.


Nach einem Upgrade bleiben gespeicherte App-Aufrufe mit ihren bisherigen IDs über dieselbe API für den Verlauf lesbar. Jeder Lesezugriff prüft Ihr aktuelles Konto und Ihren Zugriff auf den Chat. Interne Fehlerdetails bleiben privat; das öffentliche Ergebnis nennt die Fehlerart und ID. Ohne gespeicherten Aufrufer kann ein alter Aufruf nicht durch weitere Eingaben fortgesetzt werden. Prüfen Sie ein unbekanntes Ergebnis im Dienst, bevor Sie einen neuen Aufruf starten.

Manche App-Tools kommen mit einer interaktiven Ansicht. Eine Ansicht ist eine HTML-Seite der App, wie MCP Apps sie festlegt. OpenBot hat keine Benutzeroberfläche. Darum zeigt dein Client die Ansicht. Du kannst diesen Teil überspringen. Jedes Ergebnis hat auch Text.

  1. Öffne die Ansicht für eine Operation: POST /v1/app-operations/:operationId/view mit { "chatId", "itemId" }. Die Antwort hat eine id der Ansicht, die HTML-resource, die tools der Ansicht, die arguments des Aufrufs und das result.
  2. Zeige das HTML in einem iframe. Das Modul @openbot-build/protocol/McpApps hat einen Browser-Host, der das macht. Siehe Protocol.
  3. Gib die Anfragen der Ansicht an OpenBot weiter:
Anfrage der Ansicht Aufruf bei OpenBot
Tools, Resources, Templates auflisten POST /v1/app-views/:viewId/read
Ein Tool aufrufen oder eine Resource lesen POST /v1/app-views/:viewId/actions (gibt 202 und ein Ticket zurück)
Eine Aktion prüfen GET /v1/executions/:executionId/events
Den Kontext des Modells aktualisieren PUT /v1/app-views/:viewId/context
Eine Text-Nachricht schicken POST /v1/app-views/:viewId/messages
Schließen DELETE /v1/app-views/:viewId

Aktions- und Nachrichtenbefehle haben einen commandKey. Nutze einen Schlüssel für jeden Befehl und behalte ihn bei einem neuen Versuch. Die Antwort 202 enthält executionId, chat und turn. Aktionen warten als eigene Turns in der Chat-Warteschlange. Das Ausführungsprotokoll zeigt Kind-Ausführungen, Entscheidungen und Ergebnisse. Eine geschlossene Ansicht nimmt keine Befehle mehr an. Eine angenommene Aktion läuft weiter. Ein Server-Neustart schließt keine Ansicht. Sie endet bei Ablauf oder wenn sich die Verbindung oder die Zugriffsrechte ändern.

Aktionen einer Ansicht gehen durch dieselben Regeln zur Freigabe. Eine Nachricht aus der Ansicht geht als Mitteilung durch die Inbox in den Chat. Der Bot liest sie bei seinem nächsten Schritt, oder sie startet einen neuen Turn. Wenn eine Ansicht nicht öffnen kann, bekommst du 409 AppViewUnavailable. Das Text-Ergebnis ist trotzdem da.


Exportieren, importieren und zurücksetzen

Section titled “Exportieren, importieren und zurücksetzen”

Exportiere deine Liste von Apps. Die Datei enthält keine Geheimnisse und keine Anmeldungen.

Terminal window
curl https://api.example.com/v1/app-experience/export \
-H "Authorization: Bearer $OPENBOT_TOKEN"
{
"format": "openbot-apps-v1",
"apps": [
{
"name": "Work calendar",
"cardUrl": "https://apps.example.com/mcp/server-card",
"remoteIndex": 0
}
]
}

Schicke dasselbe JSON an POST /v1/app-experience/import. Eine Datei kann bis zu 30 Apps enthalten. Der Import erstellt keine Connections. Für jede App bekommst du einen neuen Entwurf oder einen error. Das Feld imported des Entwurfs behält den Namen und den Endpoint. Prüfe jeden Entwurf und erstelle die Connection wie sonst auch.

POST /v1/app-experience/reset nimmt { "commandKey" } an und gibt HTTP 202 zurück. Der Befehl legt die Connections beim Start fest und löscht Entwürfe und gespeicherten App View Zustand. Später hinzugefügte Connections bleiben bestehen. Jede Entfernung hat eine eigene untergeordnete Ausführung. Lies GET /v1/app-experience/resets/:executionId für den Auftrag und seine Kinder oder beobachte die gemeinsamen Ereignisse. Der Auftrag endet erst, wenn alle Kinder erfolgreich sind. Ein Abbruch wartet, bis alle Kinder ihre Arbeit freigeben. Einige Connections können dann bereits gelöscht sein. Die SDK-Helfer AppAuthorizations.remove und reset behalten den Schlüssel für Netzwerkwiederholungen.

Die vollständigen Formen von Request und Antwort findest du in der API-Referenz.