Entwickler

Sonny MCP Beta

Verbinde MCP-fähige KI-Assistenten – Claude und jeden Client, der das Model Context Protocol spricht – mit deinem Arbeitsbereich, mit denselben Berechtigungen und Grenzen wie bei der öffentlichen API.

Leitfaden zur öffentlichen API lesen

Schnellstart

  1. 01

    Sonny zu Claude hinzufügen

    Füge in Claude oder Cowork einen benutzerdefinierten Connector mit der URL https://www.usesonny.com/api/mcp hinzu. Sonny unterstützt die automatische Client-Registrierung, du musst also keine Client-ID und kein Secret kopieren.

  2. 02

    Zugriff auf den Arbeitsbereich freigeben

    Claude öffnet Sonny in deinem Browser. Melde dich an, prüfe die angefragten Berechtigungen und wähle den Arbeitsbereich, den du verbinden möchtest. OAuth 2.1 mit PKCE beschränkt die daraus entstehenden Access- und Refresh-Tokens auf genau diese Freigabe.

  3. 03

    Bitte deinen Assistenten, Sonny zu nutzen

    Tools beschreiben sich selbst, ein Prompt wie „Liste meine offenen Unterhaltungen auf“ reicht also aus. Assistenten sehen, welche Tools nur lesen und welche etwas verändern oder löschen – ein guter Client fragt also nach, bevor er etwas ändert.

Claude Code

claude mcp add --transport http sonny https://www.usesonny.com/api/mcp

JSON-Konfiguration für Clients

{
  "mcpServers": {
    "sonny": {
      "url": "https://www.usesonny.com/api/mcp"
    }
  }
}

Kompatibilität mit API-Schlüsseln

Kann ein Client OAuth nicht abschließen, erstelle unter Einstellungen → Entwickler einen Schlüssel mit eingeschränkten Berechtigungen und sende ihn als Authorization-Bearer-Header. API-Schlüssel werden für Server-zu-Server-Verbindungen und ältere Clients weiterhin voll unterstützt.

"Authorization": "Bearer sonny_your_key"

So hält Sonny Tool-Aufrufe sicher

Ein Arbeitsbereich, gewählte Berechtigungen
Jeder Aufruf läuft im Arbeitsbereich, der bei der OAuth-Zustimmung gewählt wurde, oder in dem Arbeitsbereich, zu dem der API-Schlüssel gehört. Ein Tool funktioniert nur, wenn die Zugangsdaten die nötige Berechtigung haben.
Ehrliche Tool-Annotationen
Tools, die nur lesen, sind als schreibgeschützt markiert; Tools, die aktualisieren oder löschen, sind als destruktiv markiert, damit dein Client vor dem Handeln nachfragen kann.
Dieselben Geschäftsregeln
Tools führen genau die Workflows der öffentlichen API aus – Änderungsverlauf, Benachrichtigungen und Webhooks verhalten sich so, als hätte ein Teammitglied die Änderung vorgenommen.

Einen Assistenten auf einen Posteingang beschränken

Ausgewählte Kanäle eines API-Schlüssels gelten automatisch für jeden Tool-Aufruf. API-Schlüssel und OAuth-Verbindungen folgen außerdem dem aktuellen Kanalzugriff des verbundenen Teammitglieds. Bei OAuth-Verbindungen oder Schlüsseln mit Zugriff auf alle Kanäle enthalten Arbeitsbereiche oft mehrere Quellen – eine pro Produkt oder Marke. Lass deinen Assistenten einmal list_sources aufrufen, um sie zu finden, und dann sourceId an list_conversations übergeben, damit Fragen zu einem Produkt nur dessen Unterhaltungen liefern. Jede Unterhaltung trägt außerdem ihre eigene sourceId, sodass sich die Ergebnisse überprüfen lassen.

Eine kostengünstige Support-Schleife betreiben

  1. Änderungen finden: Initialisiere mit dem dauerhaften sync-Feed, speichere nextCursor nach jeder verarbeiteten Seite und dedupliziere Ereignis-IDs. Um Arbeit auszuwählen, rufe list_conversations mit sourceId, awaitingReply: true, snoozed: "false" und compact: true auf. Interne Notizen verdecken keine unbeantworteten Kundennachrichten.
  2. Nur neuen Text lesen: Rufe für jede geänderte Unterhaltung list_messages mit deiner letzten Nachrichten-ID oder einem ISO-Zeitstempel in after auf und setze includeHtml: false, sofern du das E-Mail-HTML nicht wirklich brauchst.
  3. Auf Bilder und Videos warten: Wenn list_messages readsInProgress zurückgibt, führe den Aufruf aus dessen nextStep aus. Sein waitSeconds hält die Antwort zurück, bis Bildauswertungen und Video-Transkripte fertig sind – du musst also nicht selbst warten.
  4. Kundenkontext laden: get_conversation liefert identityVerified, signierte verifiedTraits sowie die Ursprungsseite und den Client-Kontext der Unterhaltung. Gibt es eine contact.id, übergib diese ID an list_conversations, um die früheren Unterhaltungen des Kunden zu laden.
  5. Bei Bedarf wecken: Nutze einen nach Quellen gefilterten Webhook für message.created, um den Agent sofort zu wecken, und hole dann per Sync auf. Der dauerhafte Feed funktioniert unabhängig von der Webhook-Zustellung. Richte den Webhook mit Zugangsdaten für alle Kanäle ein und beschränke seine Quellen-IDs; der Agent behält seine auf die Quelle beschränkten Zugangsdaten für den laufenden Betrieb.

Tool-Katalog

Jede Operation der öffentlichen API ist als Tool verfügbar. Die nötige Berechtigung steht jeweils daneben.

get_connection_info
Read connection access
conversations:read
get_conversation_context
Read support context
conversations:read
list_conversation_checks
Read conversation checks
conversations:read
record_conversation_check
Record a conversation check
conversations:write
get_status
Check Sonny status
conversations:read
create_conversation
Create a conversation from a form
conversations:write
upload_attachment
Upload a message attachment
attachments:write
list_properties
List custom properties
contacts:read
get_contact_properties
Read contact properties
contacts:read
set_contact_property
Set a contact property
contacts:write
list_contact_memories
Read customer memories
contact-memory:read
create_contact_memory
Save a customer memory
contact-memory:write
delete_contact_memory
Remove a customer memory
contact-memory:write
get_report
Read a support report
reporting:read
sync
Read workspace changes
conversations:read
batch_update_conversations
Update conversations in a batch
conversations:write
list_members
List members
members:read
list_teams
List teams
members:read
list_tags
List tags
tags:read
create_tag
Create a tag
tags:write
get_tag
Get a tag
tags:read
update_tag
Update a tag
tags:write
delete_tag
Delete a tag
tags:write
add_conversation_tag
Add a conversation tag
conversations:write
remove_conversation_tag
Remove a conversation tag
conversations:write
list_contacts
List contacts
contacts:read
create_contact
Create a contact
contacts:write
get_contact
Get a contact
contacts:read
update_contact
Update a contact
contacts:write
archive_contact
Archive a contact
contacts:write
erase_contact
Permanently erase a contact
contacts:write
list_channels
List conversation channels
conversations:read
list_sources
List sources
conversations:read
list_conversations
List conversations
conversations:read
get_conversation
Get a conversation
conversations:read
update_conversation
Update a conversation
conversations:write
list_messages
List messages
messages:read
create_internal_note
Create an internal note
messages:write
edit_message
Edit a sent reply
messages:send
send_message
Send a reply to the customer
messages:send
list_webhooks
List webhook endpoints
webhooks:read
create_webhook
Create a webhook endpoint
webhooks:write
list_webhook_events
List webhook event types
webhooks:read
update_webhook
Update a webhook endpoint
webhooks:write
delete_webhook
Delete a webhook endpoint
webhooks:write
test_webhook
Queue a test event
webhooks:write
list_webhook_deliveries
List webhook deliveries
webhooks:read
retry_webhook_delivery
Retry a failed delivery
webhooks:write
list_kb_articles
List knowledge base articles
kb:read
create_kb_article
Create a knowledge base article
kb:write
get_kb_article
Get a knowledge base article
kb:read
update_kb_article
Update a knowledge base article
kb:write
delete_kb_article
Delete a knowledge base article
kb:write
list_kb_categories
List knowledge base categories
kb:read
create_kb_category
Create a knowledge base category
kb:write
update_kb_category
Update a knowledge base category
kb:write
delete_kb_category
Delete a knowledge base category
kb:write
get_csat_summary
Get CSAT scores
csat:read
list_csat_ratings
List CSAT ratings
csat:read
get_conversation_csat
Get a conversation's CSAT rating
csat:read
reorder_kb_articles
Reorder knowledge base articles
kb:write
upsert_kb_article
Sync a knowledge base article
kb:write
reorder_kb_categories
Reorder knowledge base categories
kb:write
upsert_kb_category
Sync a knowledge base category
kb:write
get_kb_category
Get a knowledge base category
kb:read
get_help_center
Get help center settings
kb:read
update_help_center
Update help center settings
kb:write
upload_kb_media
Upload a help center image
kb:write
list_kb_audiences
List audiences
kb:read
create_kb_audience
Create audience
kb:write
update_kb_audience
Update audience
kb:write
delete_kb_audience
Delete audience
kb:write

Agent-Workflows

Sichten, handeln und synchron bleiben

REST und MCP teilen dieselben Berechtigungen und Workflows. Zugangsdaten können deinen aktuellen Kanalzugriff nur einschränken; entfernst du einen Kanal aus deiner Mitgliedschaft, verschwindet er auch aus deinen Integrationen.

Unterhaltungen mit Handlungsbedarf finden

Filtere nach awaitingReply, unread, unassigned, assigneeId, agentGroupId, snoozed, priority oder tagIds. awaitingReply ignoriert interne Notizen; unread bezieht sich auf das authentifizierte Teammitglied. unassigned bedeutet: keine einzelne zuständige Person, auch wenn ein Team zugewiesen ist. Labels passen, wenn eine der angegebenen IDs zutrifft.

list_conversations({ status: "open", awaitingReply: true, compact: true, sort: "waitingSince", direction: "asc" })

Sortiere nach waitingSince, lastMessageAt, createdAt oder geschäftlicher Priorität mit der Richtung asc oder desc. Bei Gleichstand entscheidet die ID. Ohne Angabe gelten compact=false und snoozed=any. In REST akzeptiert tagIds kommagetrennte IDs; MCP akzeptiert auch ein Array. waitingSince beginnt mit der ersten eingehenden Nachricht nach der letzten Antwort; Nachfragen und interne Notizen setzen den Wert nicht zurück. Führe diesen Scan der Warteschlange regelmäßig aus, auch wenn kein Webhook eintrifft, damit alte Threads wieder auftauchen.

Aufholen, ohne den Posteingang neu zu lesen

Nutze sync mit conversations:read. Der dauerhafte Feed enthält Änderungen an Unterhaltungen, Labels, Nachrichten, Kontakteigenschaften, Gedächtnis-Einträgen sowie Löschvorgänge. Jede Payload braucht zusätzlich ihre eigene Lese-Berechtigung: Nachrichtentexte brauchen messages:read, Gedächtnis-Einträge contact-memory:read. Eingeschränkte Zugangsdaten erhalten nur erlaubte Kanäle.

  1. Starte ohne Cursor, folge nextCursor, bis hasMore false ist, und speichere diesen Cursor.
  2. Lies die aktuellen Unterhaltungs- und Kontaktlisten sowie den Verlauf, den du für deinen Ausgangszustand brauchst.
  3. Spiele ab dem gespeicherten Cursor erneut ab, um Änderungen während dieses Lesens aufzufangen. Verarbeite jede Seite und speichere dann nextCursor.

Dedupliziere anhand der Ereignis-id: Die Wiedergabe erfolgt mindestens einmal, nachgelagerte Aktionen brauchen also einen eigenen Duplikatschutz. Eine Anfrage ohne Cursor deckt die letzte Stunde ab, keinen vollständigen Snapshot. Ereignisse werden 30 Tage aufbewahrt; HTTP 410 resync_required heißt: neu initialisieren. Initialisiere auch neu, nachdem du Berechtigungen oder Kanalzugriff erweitert hast. Verwende limit bis 100 und maxBodyChars bis 10.000 (Standard 500). Setze compact=true für die Nachrichtenfelder textPreview/textTruncated mit maximal 200 Zeichen statt body/bodyTruncated. Webhooks können einen Agent wecken; der Feed bleibt auch ohne Webhook-Abonnements oder bei einem Rückstau in der Webhook-Zustellung verfügbar.

Prüfungen einmal festhalten und das Ergebnis teilen

Bevor du eine Untersuchung wiederholst, lies list_conversation_checks (GET /api/v1/conversations/{conversationId}/checks). Speichere ein Ergebnis mit record_conversation_check (PUT auf denselben Pfad) und gib key, result, checkedBy und optional eine reference für die Karten-ID oder URL an. Zum Beispiel: key=product-version, result=Shopstar Go verified, checkedBy=Engineer, reference=card-X. Sonny speichert die authentifizierte actorId und den Zeitstempel checkedAt. Wird ein key erneut verwendet, ersetzt das nur diese Prüfung; es ist der aktuelle Stand, kein Verlaufsprotokoll. Lesen braucht conversations:read, Schreiben conversations:write, beides beschränkt auf den Kanal der Unterhaltung. Diese Aufrufe senden keine Antwort und markieren die Anfrage nicht als beantwortet.

Arbeit im Stapel zuweisen und aktualisieren

Finde aktive, zuweisbare Teammitglieder und Teams mit list_members / list_teams (members:read). Die Antworten enthalten Verfügbarkeit und tatsächlichen Kanalzugriff, aber keine E-Mail-Adressen. Mit conversations:write änderst du status, priority, assigneeId, agentGroupId, snoozedUntil, snoozedUntilReply, addTagIds oder removeTagIds.

batch_update_conversations({
  conversationIds: ["conversation_1", "conversation_2"],
  updates: { agentGroupId: "team_1", assignment: "round_robin" }
})

Round-Robin wählt ein verfügbares Teammitglied, das Zugriff auf den Kanal der Unterhaltung hat. Gibt es kein passendes Mitglied, liefert eine einzelne Aktualisierung 409 und ein Stapel-Eintrag schlägt fehl. Jeder Stapel akzeptiert bis zu 100 eindeutige IDs und wendet pro Unterhaltung einen Patch atomar an. Prüfe jedes { id, ok, error? }-Ergebnis; einzelne Einträge können fehlschlagen. Stapel unterliegen dem normalen anfragebasierten Rate-Limit, ohne Gewichtung nach Anzahl der Einträge.

Kundenkontext mit Sonny AI teilen

Liste, speichere und entferne Gedächtnis-Einträge zu Kontakten mit contact-memory:read/write. Gib sowohl contactId als auch eine zugängliche sourceId an; der Kontakt muss auf dieser Quelle eine Unterhaltung haben. Gespeicherte Fakten durchlaufen dieselbe Validierung, Duplikatbehandlung und dieselben Limits wie in der App und werden als manuelle Gedächtnis-Einträge gespeichert.

Lies Eigenschaftsdefinitionen unter /api/v1/properties und lies oder setze Werte unter /api/v1/contacts/{contactId}/properties. MCP stellt list_properties, get_contact_properties und set_contact_property bereit. Dafür sind contacts:read/write und Zugriff auf alle Kanäle nötig. Gib genau eine propertyId oder einen propertyName an, mit einem String-Wert oder null zum Leeren. Text-, Zahlen-, URL-, Datums- und Auswahlwerte werden gegen die Felddefinition geprüft.

set_contact_property({ contactId: "contact_1", propertyName: "Plan", value: "Pro" })
list_contacts({ property: { Plan: "Pro" } })

Eigenschaftsfilter vergleichen exakt gespeicherte Strings; mehrere Eigenschaften müssen alle zutreffen. Per API geschriebene Werte sind im Co-Pilot und im Autoresponder als API-Daten gekennzeichnet. Bestehende Regeln für verifizierte Kunden und Quellen gelten weiterhin. Normale, manuell gepflegte interne Feldwerte bleiben aus diesem KI-Kontext ausgeschlossen.

Dieselben Berichte lesen wie dein Team

Rufe mit reporting:read get_report({ kind, filters }) auf. Verfügbare Arten sind overview, volume, response-times, agents, sources, tags, csat, ai, knowledge, leads und online-hours. overview kombiniert Anzahlen, Antwortzeiten und CSAT. Filter sind period (1–365 Tage, Standard 30), from/to als Paar (to ist exklusiv), granularity (day/month), source, assigneeId und tagId. source akzeptiert all, all-chat, all-email, website:{id} oder email:{id}.

Berichte nutzen dieselben Abfragen wie das Dashboard und die aktuellen Zugriffsprüfungen. knowledge berücksichtigt Datum und erlaubte Kanäle, unabhängig von gewählter Quelle, zuständiger Person oder Label. online-hours misst die Anwesenheit zugänglicher Teammitglieder im Arbeitsbereich; die Anzahl der Unterhaltungen bleibt auf Kanäle beschränkt. Die bestehenden /csat-Endpunkte behalten ihre eigene Berechtigung csat:read und können eine andere Grundgesamtheit beschreiben.

Dateien mit Antworten oder internen Notizen senden

Erteile attachments:write und lade für eine Unterhaltung eine Datei bis 25 MB hoch. upload_attachment erwartet conversationId, fileName, contentType und dataBase64. Die Antwort enthält eine id und expiresAt. Übergib innerhalb einer Stunde bis zu 10 attachmentIds an eine Antwort oder Notiz. Jeder Upload ist an deinen Benutzer und die Unterhaltung gebunden und kann nur einmal verwendet werden. Ungenutzte Uploads werden nach Ablauf entfernt.

send_message({ conversationId: "conversation_1", attachmentIds: ["upload_1"] })

Antworten erfordern messages:send; interne Notizen erfordern messages:write und erreichen niemals Kunden. Nachrichten nur mit Anhängen werden unterstützt. E-Mail-Antworten enthalten Dateien bis zur E-Mail-Größengrenze und Download-Links für den Rest; Offline-Chat-E-Mails enthalten Datei-Links. Links in E-Mails bleiben nutzbar, solange der Anhang existiert, sodass Empfänger sie auch später öffnen können. Wer die E-Mail weiterleitet, teilt den Zugriff auf diese Dateien. Prüfe emailDeliveryStatus auf Zustellfehler.

Autorisierte Nachrichten-Abrufe enthalten downloadUrl, downloadExpiresAt, aiStatus, aiDescription und aiExtractedText sowie videoTranscripts für verlinkte Videos (Loom, Vimeo und andere). Download-Links gelten 15 Minuten; lies die Nachricht erneut für frische Links. Neue Uploads über API/MCP werden privat gespeichert. Ältere Anhänge bleiben öffentlich und sind mit access=legacy_public gekennzeichnet: Ihre ursprüngliche URL läuft nicht ab. Das Lesen einer Nachricht startet die Bildauswertung, wenn der Arbeitsbereich Sonny AI hat. Bildauswertungen und Video-Transkripte sind kurz nach Eingang einer Nachricht fertig: Solange noch welche laufen, beginnt die Antwort mit readsInProgress, dessen nextStep den genauen nächsten Aufruf angibt. Übergib waitSeconds (bis 30), um in einer einzigen Anfrage darauf zu warten. Kundenseitige Widget- und Echtzeit-Nachrichten enthalten nie Extraktionen oder Transkripte.

Vollständige Request- und Response-Verträge ansehen

Wissensdatenbank

Aus einer externen Quelle synchronisieren

Synchronisiere Artikel und Kategorien über stabile externe IDs, importiere Markdown oder HTML, lade Bilder hoch, lege die Reihenfolge fest und verwalte Leser-Zielgruppen. Ein wiederholtes Upsert aktualisiert die vorhandenen Inhalte.

  1. Wähle die sourceId deines Kanals und erteile kb:read und kb:write. Für die optionale Erkennung braucht list_sources zusätzlich conversations:read.
  2. Erstelle die Kategorie und synchronisiere dann einen Artikel als Entwurf. Prüfe Formatierung und Zugriff, bevor du veröffentlichst.
  3. Richte den Zugriff auf das Hilfecenter ein, veröffentliche und teste die Leseransicht. Nutze Paginierung und stabile externe IDs für spätere Aktualisierungen.
Vollständige MCP-Sync-Anleitung ansehen

Kunden-Zielgruppen verwalten

Erstelle Gruppen aus verifizierten Kundenmerkmalen und wende sie auf ein Hilfecenter, eine Kategorie oder einen Artikel an. Alle geerbten Einschränkungen müssen zutreffen. API- und MCP-Zugangsdaten handeln innerhalb ihrer Berechtigungen als Mitarbeitende; nutze die Vorschau und teste eine echte Kundensitzung, um den Leserzugriff zu prüfen.

Hilfecenter-Zielgruppen einrichten und testen

Verwandte Anleitungen