MCP
Customermates bietet einen MCP-Endpoint unter /api/v1/mcp, über den Claude, ChatGPT, Cursor und weitere Agent-Clients das CRM direkt lesen und schreiben.
Customermates exponiert einen MCP-Endpoint unter https://customermates.com/api/v1/mcp. Ein verbundener Client entdeckt automatisch alle 48 CRM-Tools. Es gibt zwei Wege zu verbinden:
- Custom Connector (OAuth): für Claude (Web, Desktop, Mobile) und ChatGPT. URL einfügen, anmelden, freigeben. Kein Key zu verwalten. Starten Sie auf Mit einem Custom Connector verbinden.
- API-Key: für CLI- und Editor-Clients (Claude Code, Codex, Cursor, Gemini CLI) und rohe HTTP-Aufrufe. Den 64-Zeichen-Key im Header
x-api-keyoder einer Konfigurationsdatei senden.
Für das End-to-End-Setup auf einer Seite springen Sie zu Ihrem Client: Claude Desktop, ChatGPT, Claude Code, Codex, Cursor oder Gemini. Diese Seite ist die Protokoll-Referenz.
Wann MCP passt
- Ihre KI soll das CRM lesen und schreiben, ohne dass Sie IDs kopieren.
- Die KI soll Fähigkeiten entdecken, statt dass Sie API-Calls von Hand schreiben.
- Ein Endpoint für Claude, ChatGPT, Cursor, Codex und weitere Clients.
Nehmen Sie stattdessen OpenAPI, wenn ein Entwickler oder Integrations-Service genau weiß, welchen Endpoint er braucht. OpenAPI ist die kanonische HTTP-Referenz. MCP ist die Agent-native Oberfläche darüber.
Der Endpoint
POST https://customermates.com/api/v1/mcp
Content-Type: application/json
Accept: application/json, text/event-stream
x-api-key: <ihr-64-zeichen-key>Der Endpoint spricht Model Context Protocol (Streamable-HTTP-Variante). tools/list liefert jedes Tool mit JSON Schema. tools/call ruft ein Tool per Name auf.
Da es die Streamable-HTTP-Variante ist, muss jede Anfrage Accept: application/json, text/event-stream senden. Ohne diesen Header liefert der Endpoint 406 Not Acceptable. Die dokumentierten Client-Anleitungen konfigurieren den unterstützten Verbindungsweg; rohe HTTP-Aufrufe mit curl oder Skripten müssen den Header explizit ergänzen.
Der x-api-key-Header ist die API-Key-Methode. Der Key ist 64 Zeichen lang, base62 (a-z, A-Z, 0-9), und erbt die Rechte des Users, der ihn erstellt hat. Es gibt kein Scoping pro Key. Custom-Connector-Clients (Claude, ChatGPT) authentifizieren sich stattdessen per OAuth und senden ein Bearer-Token, das sie für Sie holen und erneuern. Siehe Mit einem Custom Connector verbinden.
Client verbinden
Einen AI-Client mit dem Workspace zu verbinden sind immer dieselben drei Schritte:
API-Key erstellen
Profil → API Keys → Neuer Key. Entweder das geführte Setup für Claude, ChatGPT, Cursor oder Gemini wählen, oder einen Standard-Key für die eigene Integration. Der Key wird nur einmal angezeigt, also vor dem Schließen des Dialogs kopieren.
Client auf den Endpoint zeigen lassen
Dem Client
POST https://customermates.com/api/v1/mcpmit demx-api-key-Header aus dem vorherigen Schritt geben, oder per OAuth verbinden, wo der Client das unterstützt. Die Guides pro Client in der Tabelle unten enthalten die genaue Konfiguration.Prüfen, ob die Tools ankommen
Den Client nach seinen Tools fragen. Alle 48 sollten erscheinen, und
get_workspace_contextist der natürliche erste Aufruf: er liefert User, Company, Rollen und verbundene Accounts auf einmal.
| Client | Methode | Guide |
|---|---|---|
| Claude Web & Mobile | Custom Connector (OAuth) | Mit einem Custom Connector verbinden |
| Claude Desktop | Connector (OAuth) oder Config-Key | Claude Desktop verbinden |
| ChatGPT | Connector (OAuth) oder Key-Header | ChatGPT verbinden |
| Claude Code | API-Key | Claude Code verbinden |
| Codex | API-Key | Codex verbinden |
| Cursor | API-Key | Cursor verbinden |
| Gemini CLI | API-Key | Gemini verbinden |
| Beliebiger MCP-Client | Key-Header | Endpoint und Header oben nutzen |
Der Server stellt beim Verbinden Anweisungen bereit. Ob ein Client sie an das Modell übergibt und wie das Modell ihnen folgt, hängt vom konkreten Client ab. Clients mit MCP-Prompt-Unterstützung können zusätzlich den eingebauten get-started-Prompt für einen personalisierten Start ausführen.
Server-Instructions, Prompts und Toolsets
Der Server sendet beim Verbinden Hinweise zum Ablauf: zuerst das Schema lesen, IDs vor dem Schreiben suchen, Beziehungen nur über manage_record_links ändern und vor Löschen oder Senden nachfragen. Diese Hinweise bilden keine serverseitig erzwungene Freigabe. Prüfen Sie, wie der gewählte Client die Anweisungen an das Modell weitergibt und Bestätigungen behandelt, bevor Sie Schreib-, Lösch- oder Messaging-Zugriff gewähren. In Clients mit MCP-Prompt-Unterstützung kann ein eingebauter Get-Started-Prompt den Workspace für den Einstieg zusammenfassen.
Die volle 48-Tool-Oberfläche ist der Standard. Hängen Sie ?toolsets= an die Endpoint-URL, um sie einzugrenzen, zum Beispiel /api/v1/mcp?toolsets=records,messaging. Keys und Details stehen unter Eingrenzen mit ?toolsets=.
Wie die Tool-Oberfläche gebaut ist
Die MCP-Oberfläche ist so gebaut, dass auch Modelle mit schwächerer Planung sie zuverlässig nutzen können:
- Verb-first-imperative Namen:
create_contacts,update_deals,delete_records. Kein Batch-Präfix. Das Verb passt zur Absicht. - Zusammengeführte Peripherie: Custom Columns, Widgets und Webhooks liegen jeweils hinter einem Tool (
manage_custom_columns,manage_widgets,manage_webhooks) mitaction-Schalter, sodass das Modell eine Action wählt statt zwischen vielen fast identischen Tools. - Inline-Enum-Hinweise: jedes Enum-Feld listet gültige Werte inline in der Beschreibung, sodass das Modell keine externen Typen auflösen muss.
- Filter-Beispiele inline: jeder
filters-Parameter hat ein konkretes JSON-Beispiel in der Beschreibung. - Relationship-Sicherheit: Beziehungen ändern sich nur über
manage_record_links(add oder remove);nullauf einem Relationship-Array wird mit Remediation-Hint abgelehnt. - Unveränderlicher Spaltentyp:
manage_custom_columnshälttypeundentityTypebeim Update fest (aus der bestehenden Spalte übernommen); ein Typwechsel bedeutet löschen und neu anlegen. - Destructive-Flags: jedes destruktive Tool und jede destruktive Action hat
destructiveHint: trueund beginnt mitIRREVERSIBLE.
CLI-Nutzung
Wenn Sie einen lokalen Client statt GUI wollen, verbinden Tools wie mcporter denselben Endpoint. API-Key einmal in der Client-Config speichern und Tools aus der Shell aufrufen.
OpenAPI neben MCP
Beide liegen an derselben Basis-URL. MCP nutzt /api/v1/mcp, die OpenAPI-Spezifikation /api/v1/openapi. Die OpenAPI-Operationen entsprechen den REST-Endpunkten. MCP bildet unterstützte Operationen als typisierte Tools mit Anweisungen, Metadaten und derselben Produkt-Autorisierung ab. Die Anweisungen fügen keine zweite serverseitige Bestätigung hinzu.
Tool-Katalog
Customermates exponiert 48 MCP-Tools, alle standardmäßig aktiviert. Sie decken Records, Workspace, Messaging, Social Posts, Dokumentation und Deep Research, Custom Columns, Widgets, Webhooks, Admin und Support ab. Jedes destruktive Tool ist geflaggt und startet die Beschreibung mit IRREVERSIBLE. Beziehungen ändern sich nur über manage_record_links; die Update-Tools fassen sie nie an.
Zwei Flags pro Tool:
- Read: keine Mutation.
- Destructive: löscht Daten oder ist nicht rückgängig zu machen. Bei zusammengeführten Tools gilt das Flag für die löschenden Actions.
Das volle JSON-Schema jedes Tools liegt live an POST /api/v1/mcp mit method: "tools/list".
Records
Siebzehn Tools arbeiten gegen die fünf Record-Typen (contact, organization, deal, service, task). Records tragen pro Workspace definierte Custom Columns, deshalb ist get_record_schema der Anker: Es liefert die Custom-Column-IDs und Optionswerte, die Schreibzugriffe brauchen. Felder wie ein Deal- oder Task-Status sind konfigurierbare singleSelect Custom Columns, keine festen nativen Felder; get_record_schema liefert genau die Spalten, die der Workspace tatsächlich hat.
| Tool | Read | Destructive | Zweck |
|---|---|---|---|
get_record_schema | ✓ | Schema und Custom-Column-Metadaten, nie Record-Daten. Ein Entity-Typ, oder alle fünf, wenn entity fehlt. Vor jedem Create oder Update aufrufen. | |
list_records | ✓ | Suchen, filtern, sortieren, paginieren für einen Entity-Typ. Liefert immer das Total. Deals enthalten totalValue und totalQuantity, Services amount. | |
search_records | ✓ | Freitextsuche über einen oder mehrere Entity-Typen in einem Call. | |
get_records | ✓ | Volle Record-Daten per ID, bis 100, Typen mischbar; Contacts auch per E-Mail, Telefon oder provider:handle. Liefert immer die Felder; Markdown-Notes je Eintrag mit include=withNotes. | |
create_contacts | Bis 100 Contacts anlegen, Custom-Column-Werte und Relations-IDs inline. | ||
create_organizations | Bis 100 Organizations anlegen, Custom-Column-Werte und Contact-/User-/Deal-/Task-IDs inline. | ||
create_deals | Bis 100 Deals anlegen, Services als Inline-Array. | ||
create_services | Bis 100 Services anlegen, Custom-Column-Werte und User-/Deal-/Task-IDs inline. | ||
create_tasks | Bis 100 Tasks anlegen, Custom-Column-Werte und Relations-IDs inline. | ||
update_contacts | Partial-Update per Contact-Key (ID, E-Mail, Telefon oder provider:value); Org-/Deal-/User-/Task-Beziehungen bleiben unberührt, aber ein übergebenes identifiers-Array ERSETZT die Messaging-Kanäle des Contacts (nicht gelistete werden entkoppelt). | ||
update_organizations | Partial-Update per ID. Fasst Beziehungen nie an. | ||
update_deals | Partial-Update per ID, inklusive singleSelect-Custom-Column-Werten und services (Inline-Array aus {serviceId, quantity}, das die komplette Service-Menge des Deals ERSETZT); Org-/User-/Contact-/Task-Beziehungen bleiben unberührt (nutzen Sie manage_record_links). | ||
update_services | Partial-Update per ID. | ||
update_tasks | Partial-Update per ID, inklusive singleSelect-Custom-Column-Werten. Fasst Beziehungen nie an. | ||
update_record_notes | Markdown-Notes auf 1 bis 100 Records ersetzen oder anhängen, gewählt über mode. | ||
manage_record_links | IDs auf einer Beziehung hinzufügen oder entfernen (action add oder remove). Der einzige Weg, Beziehungen zu ändern. | ||
delete_records | ✓ | IRREVERSIBLES Hard-Delete von 1 bis 100 Records per ID (Contacts auch per E-Mail, Telefon oder provider:value). |
Alle Create- und Update-Tools nehmen Custom-Column-Werte über customFieldValues; rufen Sie zuerst get_record_schema für die Column-IDs auf.
Workspace
| Tool | Read | Destructive | Zweck |
|---|---|---|---|
get_workspace_context | ✓ | Ihr User, das Company-Profil, alle Rollen inklusive Rechte und Ihre verbundenen Messaging-Konten (Ihre eigenen plus die mit dem Workspace geteilten) in einem Call. Der natürliche erste Call einer Session. | |
list_users | ✓ | Teammitglieder mit ID, Name, E-Mail, roleId und Status. |
Messaging
Messaging-basierte Tools sind im Cloud-Modus ab dem Pro-Tarif verfügbar. get_activities kann ohne Messaging-Berechtigung weiterhin Änderungen aus dem Audit-Log liefern, wenn der aufrufende User die Audit-Log-Berechtigung hat. Nachrichten, Aktivitäten verbundener Accounts und Kalenderquellen erfordern zusätzlich die Berechtigung für den Posteingang und Messaging.
| Tool | Read | Destructive | Zweck |
|---|---|---|---|
get_messaging_threads | ✓ | Zwei Modi: ohne threadId listet es Inbox-Threads mit Filtern und Sortierung (Threads ohne Nachricht werden ausgeblendet, außer sie enthalten einen Draft; der draft-Filter zeigt genau die Threads mit Draft); mit threadId liefert es einen Thread plus eine Seite seiner Nachrichten (Standard 25, neueste zuerst, Drafts inklusive). | |
get_activities | ✓ | Aktivitäts-Timeline mit optionalem technischem Entitätsumfang und UND-verknüpften Filtern. Filter unterstützen Kategorie/Roh-Typ, Unterhaltung, Anbieter, verbundenen Account sowie verknüpfte Kontakte, Organisationen, Deals, Services und Aufgaben. Jedes Aktivitätsfilterfeld darf einmal vorkommen; Alternativen gehören in das Werte-Array einer einzigen Mitgliedschaftsregel. Beziehungsfelder akzeptieren in, notIn, hasSome und hasNone; Mitgliedschaft benötigt 1–50 UUIDs. Beziehungs-UUIDs müssen auf Datensätze verweisen, die Sie lesen dürfen; nicht auflösbare Ids werden abgelehnt. Das Ergebnis enthält availableSources, scopeTruncated, pageLimitReached, Gesamtzahl und Seite. Die Seitennummer ist auf 40 begrenzt. | |
get_calendars | ✓ | Drei Modi: list: "calendars" (Standard) listet die Kalender der zugänglichen verbundenen Konten; list: "events" listet Kalenderereignisse sortiert nach Startzeit, filterbar nach calendarId oder einem startsAt-Zeitraum; mit eventId liefert es die Details eines Ereignisses inklusive Organisator und Teilnehmern. Die Ids entsprechen der entityId der Kalender-Webhook-Events. | |
send_chat_message | Stellt sofort zu. Mit threadId antwortet es in einem bestehenden Chat; mit connectedAccountId plus attendeeIdentifiers startet es einen neuen (optionales chatName benennt eine Gruppe). Zum Senden eines gespeicherten Drafts sind draftMessageId und draftRevision erforderlich. Neue LinkedIn-Chats sind standardmäßig Classic; setzen Sie linkedinProduct auf sales_navigator oder recruiter für ein InMail (braucht inmailSubject), oder inmail:true, um auf Classic jemanden außerhalb Ihres Netzwerks per InMail anzuschreiben. | ||
send_email | Stellt sofort zu. Senden oder antworten von einem verbundenen E-Mail-Konto; für einen gespeicherten Draft sind draftMessageId und draftRevision erforderlich. Die aktivierte Signatur des Kontos wird automatisch angehängt, schreiben Sie daher keine Grußformel in den Text. | ||
save_message_draft | Nachricht zur Durchsicht vorbereiten: Der Draft erscheint in der Inbox, und Sie senden ihn selbst. Mit threadId entsteht eine Antwort, mit connectedAccountId plus recipients eine komplett neue Unterhaltung, die zunächst nur als Draft existiert. Gibt Message-ID und undurchsichtiges Revision-Token zurück; erneutes Speichern aktualisiert den einen Draft des Threads. Die Signatur wird beim Senden des Drafts angehängt, schreiben Sie daher keine Grußformel in den Text. | ||
discard_message_draft | ✓ | Die exakte gespeicherte Draft-Version per Message-ID und undurchsichtigem Revision-Token löschen. | |
update_messaging_thread | Thread-State setzen: unread, open, closed oder spam. | ||
move_email_thread | Eine E-Mail-Konversation beim Anbieter in einen anderen Postfachordner verschieben. | ||
connect_messaging_account | Erzeugt einen Link, den der User im Browser öffnet, um einen Kanal zu verbinden (WhatsApp, LinkedIn, E-Mail, Instagram, Telegram). Sie geben den Link zurück; der User schließt die Auth dort ab. Läuft nach 30 Minuten ab. |
Social Posts
| Tool | Read | Destructive | Zweck |
|---|---|---|---|
get_social_posts | ✓ | Posts auf LinkedIn oder Instagram, gelesen über ein verbundenes Konto. Für den Kontoinhaber authorIdentifier=me verwenden. Für eine andere Person get_social_profile.id, get_social_posts.items[].author.id (Listenmodus), get_social_posts.author.id (Einzel-Post-Modus), get_social_post_engagement.items[].author.id (Kommentare), get_social_post_engagement.items[].sender.id (Reaktionen) oder manage_social_relations.items[].user.id verwenden. get_messaging_threads.items[].participants[].identifier (Listenmodus) oder get_messaging_threads.thread.participants[].identifier (Detailmodus) zuerst mit get_social_profile auflösen; eine Thread-Teilnehmer-Kennung nicht direkt übergeben. get_social_posts.items[].id als postId übergeben, um einen einzelnen Post abzurufen. Bei einer Fortsetzung dasselbe Konto, denselben Autor und dasselbe Limit zusammen mit next_cursor verwenden. | |
get_social_post_engagement | ✓ | Engagement zu einem Post: kind=comments (Standard) listet Kommentare, kind=reactions wer reagiert hat; mit commentId die Reaktionen auf diesen Kommentar. | |
get_social_profile | ✓ | Ein Personen- oder Unternehmensprofil. Für Personen profileType=person mit me, get_messaging_threads.items[].participants[].identifier, get_messaging_threads.thread.participants[].identifier, get_social_posts.items[].author.id, get_social_posts.author.id, get_social_post_engagement.items[].author.id, get_social_post_engagement.items[].sender.id, manage_social_relations.items[].user.id, einem öffentlichen LinkedIn-Classic-Profil-Slug oder einem Instagram-Nutzernamen verwenden. Für LinkedIn-Unternehmen profileType=company mit linkedin_search_sales_companies.items[].id, linkedin_search_sales_leads.items[].current_positions[].company_id, linkedin_manage_sales_lists.items[].current_positions[].company_id oder get_social_profile.current_positions[].company_id verwenden. get_social_profile.id mit demselben profileType wiederverwenden. | |
manage_social_relations | Kontaktanfragen: Einladungen listen (standardmäßig erhaltene, oder Ihre eigenen gesendeten/ausgehenden über direction), mit get_social_profile.id einladen (sendet eine echte Anfrage), per invitationId annehmen oder abbrechen. | ||
linkedin_search_sales_leads | ✓ | Findet Personen über LinkedIn Sales Navigator: entweder aus einer eingefügten Such-URL oder als strukturierte Suche mit Filtern (Keywords, Standort, Branche, Unternehmen, Jobtitel, Seniorität und mehr). linkedin_search_sales_leads.items[].current_positions[].company_id mit get_social_profile und profileType=company auflösen. Braucht ein Sales-Navigator-Abo. | |
linkedin_search_sales_companies | ✓ | Findet Unternehmen über LinkedIn Sales Navigator: entweder aus einer eingefügten Unternehmens-Such-URL oder als strukturierte Suche mit Filtern (Keywords, Standort, Branche, Mitarbeiterzahl, Jahresumsatz und mehr). linkedin_search_sales_companies.items[].id mit profileType=company an get_social_profile übergeben. Braucht ein Sales-Navigator-Abo. | |
linkedin_get_sales_search_parameters | ✓ | Löst die IDs hinter den LinkedIn-Sales-Navigator-Sucheingaben nach Typ auf (Standorte, Branchen, Jobtitel, Funktionen, Unternehmen, Schulen, Gruppen und mehr) plus Ihre Lead-/Account-Listen und gespeicherten/letzten Suchen; Keyword ist optional, ein reiner Typ zählt also die ganze Familie auf. | |
linkedin_manage_sales_lists | LinkedIn-Sales-Navigator-Lead- und -Account-Listen: Listen aufzählen, die Mitglieder einer Liste lesen oder einen Lead über linkedin_search_sales_leads.items[].id beziehungsweise get_social_profile.id oder ein Unternehmen über linkedin_search_sales_companies.items[].id beziehungsweise einen oben dokumentierten items[].current_positions[].company_id-Pfad speichern. Neue Listen entstehen in Sales Navigator selbst. |
Typischer Social-Read-Ablauf
Wählen Sie aus get_workspace_context.connectedAccounts einen LinkedIn- oder Instagram-Eintrag mit status=ok und verwenden Sie dessen id als connectedAccountId. Wenn die Person aus einem Inbox-Thread stammt, lösen Sie zuerst get_messaging_threads.items[].participants[].identifier aus dem Listenmodus oder get_messaging_threads.thread.participants[].identifier aus dem Detailmodus auf:
{
"connectedAccountId": "00000000-0000-4000-8000-000000000001",
"identifier": "<get_messaging_threads.items[].participants[].identifier>",
"profileType": "person"
}Rufen Sie get_social_profile mit dieser Anfrage auf und übergeben Sie anschließend get_social_profile.id als get_social_posts.authorIdentifier für die erste Seite:
{
"connectedAccountId": "00000000-0000-4000-8000-000000000001",
"authorIdentifier": "<get_social_profile.id>",
"limit": 10
}Wenn next_cursor nicht null ist, wiederholen Sie dieselben Werte für connectedAccountId, authorIdentifier und limit, setzen Sie cursor auf diesen Wert und lassen Sie offset weg:
{
"connectedAccountId": "00000000-0000-4000-8000-000000000001",
"authorIdentifier": "<same get_social_profile.id>",
"cursor": "<next_cursor>",
"limit": 10
}Für ein Unternehmen rufen Sie get_social_profile mit profileType=company und einem identifier aus linkedin_search_sales_companies.items[].id, linkedin_search_sales_leads.items[].current_positions[].company_id, linkedin_manage_sales_lists.items[].current_positions[].company_id oder get_social_profile.current_positions[].company_id auf.
Dokumentation und Deep Research
| Tool | Read | Destructive | Zweck |
|---|---|---|---|
search_docs | ✓ | Volltextsuche über die Docs; standardmäßig nur die Produkt-Guides (source=docs); mit source=api oder all auch die REST-API-Referenz. Liefert Slug, Source, Titel, URL, Snippet. | |
get_docs_page | ✓ | Eine Doku-Seite als Markdown inklusive kanonischer URL. Listet bei einem Miss alle gültigen Slugs. | |
search | ✓ | Von ChatGPT-Deep-Research-Connectors verlangt; föderiert CRM-Records und Docs. Interaktive Agents nehmen besser search_records oder search_docs. | |
fetch | ✓ | Deep-Research-Gegenstück zu search: holt ein Ergebnis per ID. |
Custom Columns
| Tool | Read | Destructive | Zweck |
|---|---|---|---|
manage_custom_columns | ✓ | Ein Tool mit action-Schalter: list, upsert (anlegen oder aktualisieren), delete. Deckt alle zehn Spaltentypen ab; type und entityType sind beim Update unveränderlich. Delete ist IRREVERSIBLE und löscht alle gespeicherten Werte. |
Widgets
| Tool | Read | Destructive | Zweck |
|---|---|---|---|
manage_widgets | ✓ | Ein Tool mit action-Schalter: list, get, create, update, delete. Ohne kind bleibt create abwärtskompatibel ein chart. Ein Aktivitätsverlauf akzeptiert beim Erstellen name, optionale timelineFilters und optional showFilters; jedes Aktivitätsfilterfeld darf nur einmal vorkommen. Update leitet den unveränderlichen gespeicherten Typ ab, erhält ausgelassene Felder und leert Filter mit timelineFilters: []. Create weist neue, unzugängliche Beziehungs-UUIDs zurück. Update darf eine nicht verfügbare Beziehungs-UUID nur beibehalten oder entfernen, wenn genau diese UUID bereits im Widget gespeichert ist; weitere unzugängliche UUIDs werden abgelehnt. list/get/create/update liefern jeweils kind; get liefert zusätzlich Diagrammdaten für Charts und direkt wiederverwendbare timelineFilters für Aktivitätsverläufe. Chart- und Aktivitätsfelder dürfen nicht gemischt werden. |
Routinen
| Tool | Read | Destructive | Zweck |
|---|---|---|---|
manage_routines | ✓ | Ein Tool mit einem action-Schalter: list, runs, create, update, pause, run_now, delete. Eine Routine sind gespeicherte Anweisungen, die der Assistent nach Zeitplan oder bei einem CRM-Ereignis ausführt. Ohne enabled erzeugt create eine LIVE-Routine; für einen Entwurf enabled: false übergeben. Ein Wechsel von triggerKind muss den Zeitplan oder die Ereignisse der neuen Art mitbringen. pause deaktiviert die Routine und setzt wartende Läufe auf übersprungen, was ein erneutes Aktivieren nicht rückgängig macht. run_now gilt nur für geplante Routinen. Läufe werden über cursor paginiert und enthalten Status, Zusammenfassung und Auslöser. |
Webhooks
| Tool | Read | Destructive | Zweck |
|---|---|---|---|
manage_webhooks | ✓ | Ein Tool mit action-Schalter: list, get, create, update, delete, dazu das Delivery-Log (Action list_deliveries, auf die aktuelle url eines Webhooks beschränkt, wenn Sie dessen id übergeben) und die erneute Zustellung (Action resend_delivery). |
Admin und Team
| Tool | Read | Destructive | Zweck |
|---|---|---|---|
update_workspace_settings | target profile aktualisiert Ihren Namen, Ihr Land und Ihren Avatar; target company aktualisiert die Workspace-Währung (nur Admins). | ||
manage_team | Mitglieder per E-Mail einladen (Action invite, bis 20, verschickt echte Einladungs-E-Mails) oder Rolle und Status eines Mitglieds ändern (Action update_member). |
Support
| Tool | Read | Destructive | Zweck |
|---|---|---|---|
request_support | Öffnet ein Support-Ticket beim Customermates-Team (Betreff plus Beschreibung). Das Team meldet sich per E-Mail und im In-App-Chat. Gibt die Ticketnummer zurück. |
Eingrenzen mit ?toolsets=
Alle 48 Tools sind standardmäßig an. Um nur einen Teil der Oberfläche zu exponieren, hängen Sie ?toolsets= mit kommagetrennten Gruppen-Keys an die Endpoint-URL:
https://customermates.com/api/v1/mcp?toolsets=records,messagingKeys: records, workspace, messaging, social, docs, custom-columns, widgets, routines, webhooks, admin, support. Kein Parameter heißt alles; unbekannte Keys werden ignoriert. search und fetch sind immer an, damit Deep-Research-Connectors auch auf einer eingegrenzten Oberfläche funktionieren.
Wenn ein Aufruf abgelehnt wird
Eine Ablehnung ist Datum, kein Absturz. Das Ergebnis trägt isError: true, eine menschenlesbare Nachricht in content und einen maschinenlesbaren Umschlag in _meta.failure mit kind und den betroffenen issues, die jeweils den Feld-path benennen:
{
"isError": true,
"content": [{ "type": "text", "text": "Webhook ID not found or not accessible." }],
"_meta": {
"failure": {
"kind": "not_found",
"issues": [{ "code": "custom", "path": [], "message": "Webhook ID not found or not accessible.", "customCode": "webhookNotFound" }]
}
}
}kind ist eines von validation, authentication, authorization, not_found, conflict, rate_limit oder unavailable. Darauf verzweigen statt Nachrichtentexte zu matchen:
- validation: die Argumente waren falsch.
issues[].pathlesen, das Feld korrigieren, erneut aufrufen.get_record_schemaklärt die meisten dieser Fälle. - authorization: die Rolle des Aufrufers erlaubt es nicht. Wiederholen hilft nie; benennen, was abgelehnt wurde und welche Berechtigung es braucht. Rollen sind workspace-definiert, also
get_workspace_context.roleslesen statt einen festen Satz anzunehmen. - not_found: die Id existiert nicht oder gehört zu einem anderen Workspace. Jeder Aufruf ist mandantengebunden, eine fremde Id liest sich daher als fehlend, nicht als verboten.
- conflict: etwas belegt die Ressource bereits. Vor dem Wiederholen den aktuellen Stand lesen.
- rate_limit und unavailable: vorübergehend oder kapazitätsbedingt. Zurückhalten, und
unavailableals Provider-Problem darstellen, nicht als Fehler des Users. - authentication: der Key fehlt, ist abgelaufen oder widerrufen. Der User muss einen neuen ausstellen.
Entitlements lehnen auf demselben Weg ab. Messaging-gestützte Tools brauchen die Pro-Stufe, Sales-Navigator-Tools das entsprechende LinkedIn-Abo, und das Verbinden eines Accounts endet am Kanal-Limit des Plans. Berechtigung und Entitlement sind unabhängig: ein Aufrufer kann Inbox-Berechtigung haben und trotzdem am Plan scheitern, und umgekehrt.
Tool-Metadaten und serverseitige Grenzen
- Bestätigungshinweis für den Client. Die Server-Anweisungen fordern das Modell auf, vor
delete_recordsund jedem Versand-Tool nachzufragen. Der MCP-Endpunkt führt einen autorisierten Tool-Aufruf aus, sobald der Client ihn sendet. Prüfen Sie daher das Bestätigungsverhalten des Clients. - Beziehungen nur über
manage_record_links. Die Update-Tools fassen Beziehungen nie an, undnullauf einem Relationship-Array wird serverseitig mit Remediation-Hint abgelehnt. - Erst Draft, dann Send.
send_emailundsend_chat_messagestellen sofort zu. Wer eine Nachricht vorbereitet haben will, bekommt sie übersave_message_draft, und Sie senden sie aus der Inbox. Ein Draft braucht keine bestehende Unterhaltung: MitconnectedAccountIdundrecipientsentsteht der Thread lokal, erscheint in der Inbox und erreicht den Anbieter erst beim Senden. - Destructive-Flags überall. Jedes destruktive Tool und jede destruktive Action hat
destructiveHint: trueund den PräfixIRREVERSIBLEin der Beschreibung. - Jedes Enum-Feld listet gültige Werte inline in der Beschreibung, und jedes
filters-Feld enthält ein konkretes JSON-Beispiel.
Häufige Fragen
Wie authentifiziere ich mich am MCP-Endpoint?
Den 64-stelligen API-Key im Header x-api-key senden, oder per OAuth verbinden, wo der Client das unterstützt. Keys entstehen unter Profil → API Keys → Neuer Key. Jeder Key trägt die eigenen Rechte, ein Client kann also nie mehr als man selbst.
Welche AI-Clients können sich verbinden?
Für Claude im Web, mobil und als Desktop-App, ChatGPT, Claude Code, Codex und Cursor sind oben Verbindungswege dokumentiert. Ein anderer Client kann sich verbinden, wenn er MCP über Streamable HTTP und die benötigte Authentifizierung unterstützt. Prüfen Sie vor der Nutzung die konkrete Kompatibilität und den Umgang mit Anweisungen.
Kann ich die Zahl der Tools reduzieren, die ein Client sieht?
Ja. ?toolsets= mit einer kommagetrennten Liste der Gruppen oben an die Endpoint-URL anhängen, dann werden nur diese Tools angeboten. Die beiden Connector-Tools search und fetch bleiben immer aktiv.
Woran erkenne ich gefährliche Tools?
Jedes destruktive Tool ist im Katalog oben markiert und beginnt seine Beschreibung mit IRREVERSIBLE. Clients, die MCP-Metadaten auswerten, erhalten zusätzlich destructiveHint und können vor dem Aufruf nachfragen. Diese Metadaten helfen dem Client, ersetzen aber keine zweite serverseitige Freigabe.
Liefern Tools maschinenlesbare Ergebnisse?
Ja. Jedes Tool deklariert ein Output-Schema, live sichtbar über tools/list, und liefert dazu passendes structuredContent neben der kompakten Textform, sodass ein Client Ergebnisse verketten kann, ohne Text zu parsen.
Sollte ich MCP oder die REST-API verwenden?
Beides existiert nebeneinander: MCP ist für AI-Clients, die Tools selbst entdecken und aufrufen, die per OpenAPI dokumentierte REST-API für eigenen Code und Integrationen. Beide teilen dieselben Berechtigungen und Daten.
Weiter
- Custom Connector: End-to-End-Setup auf einer Seite.
- Filter-Syntax: jeder Operator mit Beispielen.
- Webhooks: die andere Hälfte des agentischen Loops.