• Virtual Marketer CRM Logo
    Virtual Marketer CRMDokumentation
  • Einführung
Erste Schritte
  • Quickstart
  • Kernkonzepte
KI verbinden
  • Custom Connector
  • CLI & Editoren
  • Ratenlimits
Integrationen
  • MCP
  • Webhooks
  • Leads von der Website
  • OpenAPI 3.1.0
  • N8N
  • WhatsApp-API
App-Leitfaden
  • Dashboard
  • Posteingang
  • Datensätze
  • Profil
  • Unternehmen
  • Lead-Versand
  • API-Keys
  • Filter-Syntax
Lizenzen & Sicherheit
  • Architektur & Sicherheit
  • Zurück
  1. Einführung
  2. MCP

Model Context Protocol (MCP)

Virtual Marketer CRM exponiert einen nativen MCP-Endpoint unter /api/v1/mcp, damit Claude, ChatGPT, Cursor und andere Agent-Clients das CRM direkt lesen und schreiben können.

Virtual Marketer CRM exponiert einen MCP-Endpoint unter https://crm.virtual-marketer.de/api/v1/mcp. Ein verbundener Client entdeckt automatisch alle 62 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-key oder 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://crm.virtual-marketer.de/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 Request Accept: application/json, text/event-stream senden. Ohne diesen Header liefert der Endpoint 406 Not Acceptable. Alle unterstützten MCP-Clients setzen ihn automatisch; nur rohe HTTP-Aufrufe (curl, Skripte) müssen ihn 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

ClientMethodeGuide
Claude Web & MobileCustom Connector (OAuth)Mit einem Custom Connector verbinden
Claude DesktopConnector (OAuth) oder Config-KeyClaude Desktop verbinden
ChatGPTConnector (OAuth) oder Key-HeaderChatGPT verbinden
Claude CodeAPI-KeyClaude Code verbinden
CodexAPI-KeyCodex verbinden
CursorAPI-KeyCursor verbinden
Gemini CLIAPI-KeyGemini verbinden
Beliebiger MCP-ClientKey-HeaderEndpoint und Header oben nutzen

Der Server brieft das Modell automatisch, sobald sich ein Client verbindet. Clients, die MCP-Prompts unterstützen, können zusätzlich den eingebauten get-started-Prompt für einen personalisierten Start ausführen.

Server-Instructions, Prompts und Toolsets

Sie müssen dem Modell nicht beibringen, wie es das CRM nutzt. Der Server sendet beim Verbinden Instructions, sodass das Modell den Workflow automatisch befolgt: erst das Schema lesen, IDs vor dem Schreiben suchen, Beziehungen nur über manage_record_links ändern und vor Löschen oder Senden rückfragen. In Clients, die MCP-Prompts unterstützen (Claude Code, Cursor), gibt es zusätzlich einen eingebauten Get-Started-Prompt; er interviewt Sie kurz und fasst Ihren Workspace zusammen, um den Start zu personalisieren.

Die volle 62-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=.

Der Virtual Marketer Agent

Der Server stellt sich jedem Client als Virtual Marketer Agent vor (serverInfo.name im MCP-Handshake), und seine Instructions bitten den Client, ihn unter diesem Namen zu nennen. Er ist die Agenten- und Datenschicht der Virtual-Marketer-Plattform: er hält die Daten des Workspace, setzt durch, wer was sehen und ändern darf, und behält das Gelernte im Workspace.

Worauf das Datenschutzversprechen beruht, und nicht mehr:

  • Jeder Aufruf läuft als ein Nutzer oder eine Dienstidentität und sieht nur diesen Workspace. Ein Dienstschlüssel hat genau die Rechte seiner Rolle.
  • Das CRM hält keinen Schlüssel eines KI-Anbieters. Über das CRM selbst verlässt also kein Datensatz den Server für Training oder Inferenz. Was ein verbundener Client mit gelesenen Daten tut, verantwortet dieser Client.
  • Fehlertexte enthalten nie Hostnamen, Ports oder Datenbankmeldungen.
  • Jeder Schreibvorgang über die Anwendung steht mit Autor und Zeit im Audit-Log.

Ausdrückliche Regeln und implizites Lernen

Ein Feld lässt sich auf zwei Wegen steuern, und beide greifen ineinander:

  • Ausdrücklich: eine Custom Column kann eine description tragen. Sie steht im Spalteneditor und für jeden Agenten in get_record_schema. Dort steht die Regel, zum Beispiel wie lang ein Betreff sein darf. Eine ausdrückliche Regel geht immer vor.
  • Implizit: eine Custom Column mit learnFromEdits macht jede Bearbeitung durch einen Menschen zu einem Lernsignal. get_learning_signals listet diese Bearbeitungen mit dem Wert davor und danach und mit der Angabe, wer den Wert davor geschrieben hat (previousBy: agent, person oder unknown). Ein Mensch, der einen Entwurf des Agenten korrigiert, ist das stärkste Signal. Bearbeitete Notizabschnitte, etwa eine Instagram-DM, kommen je Abschnitt.

Der Lernlauf liest diese Signale, passt Ton und Wortwahl späterer Entwürfe an und achtet auf Drift. Aus einem gelernten Muster macht er nie selbst eine Änderung an Zielgruppe oder Angebot: so etwas wird einem Menschen vorgeschlagen.

Kritische Prüfung von Zielgruppe und Stil

Eine Custom Column mit reviewOnChange ist folgenreich, typischerweise die Zielgruppe oder ein Stilfeld. Ein update_*-Aufruf, der sie ändert, wird abgelehnt und schreibt nichts, solange er keine reviewNote trägt: was sich ändert, warum es zum Briefing des Workspace und zu den Lernsignalen passt, und wer es wollte. Die Notiz wird mit dem Audit-Eintrag gespeichert und erscheint in get_audit_changes und get_learning_signals. Dieselbe Prüfung gilt per Anweisung für einen Briefing-Datensatz: ein Agent liest ihn vor einer Änderung und meldet Widersprüche, statt sie zu schreiben.

Alle drei Einstellungen setzen Sie je Spalte im Spalteneditor oder mit manage_custom_columns (description, learnFromEdits, reviewOnChange).

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) mit action-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); null auf einem Relationship-Array wird mit Remediation-Hint abgelehnt.
  • Unveränderlicher Spaltentyp: manage_custom_columns hält type und entityType beim 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: true und beginnt mit IRREVERSIBLE.

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 Base-URL. MCP auf /api/v1/mcp; die OpenAPI-Spec auf /api/v1/openapi. Die OpenAPI-Operationen mappen 1:1 auf REST-Endpoints; MCP-Tools wrappen diese und ergänzen Safety-Guardrails, die die Raw-API nicht hat.

Tool-Katalog

Virtual Marketer CRM exponiert 62 MCP-Tools, alle standardmäßig aktiviert. Sie decken Records, Workspace, Messaging, Dokumentation und Deep Research, Custom Columns, Widgets, Webhooks, Projekte, Kampagnen, Insights, Teams, Abrechnung, Zeiterfassung, Anreicherung, WhatsApp, Admin, Support und Audit 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.

ToolReadDestructiveZweck
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. Eine Datumsspalte der Organisation, die sich selbst füllt, trägt autoFilledFrom mit der ID der auslösenden Spalte.
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_contactsBis 100 Contacts anlegen, Custom-Column-Werte und Relations-IDs inline.
create_organizationsBis 100 Organizations anlegen, Custom-Column-Werte und Contact-/User-/Deal-/Task-IDs inline.
create_dealsBis 100 Deals anlegen, Services als Inline-Array.
create_servicesBis 100 Services anlegen, Custom-Column-Werte und User-/Deal-/Task-IDs inline.
create_tasksBis 100 Tasks anlegen, Custom-Column-Werte und Relations-IDs inline. Akzeptiert projectId, parentTaskId und sortOrder, um den Task einem Projekt oder einem übergeordneten Task zuzuordnen, sowie dueDate (ISO-8601-Datum oder -Zeitpunkt) als Fälligkeitsdatum.
update_contactsPartial-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_organizationsPartial-Update per ID. Fasst Beziehungen nie an. Eine Änderung an einer Spalte mit reviewOnChange braucht eine reviewNote, sonst wird nichts geschrieben; das gilt für alle update_*-Tools.
update_dealsPartial-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_servicesPartial-Update per ID.
update_tasksPartial-Update per ID, inklusive singleSelect-Custom-Column-Werten, projectId, parentTaskId, sortOrder und dueDate (null entfernt das Fälligkeitsdatum). Fasst Beziehungen nie an.
update_record_notesMarkdown-Notes auf 1 bis 100 Records ersetzen oder anhängen, gewählt über mode.
add_record_attachmentDatei an einer Organization ablegen: Audio spielt inline, Bilder, PDF; höchstens 10 MB als base64. Audio braucht eine Caption, die wörtlich neben dem Player steht.
list_record_attachments✓Dateien einer Organization mit Caption und Größe auflisten, neueste zuerst.
get_lead_dispatches✓Zeigt den automatischen Lead-Versand: jede Regel (läuft oder pausiert, Grund, Versandfenster, Absender, Anzahl je Status) und die einzelnen Versände mit Empfänger, Betreff, Status, Sendezeit und Fehler- oder Bounce-Grund. Vor Recherche oder Anschreiben prüfen, ob eine Organisation schon angeschrieben wurde, gebounced ist oder noch wartet. Siehe Lead-Versand.
get_lead_follow_ups✓Zeigt die Antworten von Leads, die auf Prüfung warten: die Antwort und die zweite Mail (mit Media-Kit-Link), die rausgehen würde. Vor der Entscheidung mit decide_lead_follow_up die Antwort lesen.
decide_lead_follow_up✓Gibt eine zurückgehaltene Folgemail frei oder überspringt sie, mit Pflichtbegründung. Nur senden, wenn die Antwort Interesse zeigt; bei Absage, Autoantwort oder Unklarheit überspringen. Der Text lässt sich nicht ändern, das CRM prüft beim Versand alles erneut.
get_learning_signals✓Die implizite Hälfte des Lernens: Bearbeitungen durch Menschen an Organisationsspalten mit learnFromEdits und an Notizabschnitten, neueste zuerst, jeweils mit Wert davor und danach, Bearbeiter und previousBy (agent, person oder unknown). Bearbeitungen durch Dienstidentitäten fehlen bewusst. Weitere Seiten über before. Braucht Leserecht auf Organisationen.
manage_record_linksIDs 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

ToolReadDestructiveZweck
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

Die Messaging-Tools sind registriert und hier dokumentiert. Der Posteingang dahinter wird gerade als native E-Mail- und WhatsApp-Engine neu gebaut.

ToolReadDestructiveZweck
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); mit threadId liefert es einen Thread plus eine Seite seiner Nachrichten (Standard 25, neueste zuerst, Drafts inklusive).
get_message_attachment✓Lädt einen Anhang einer Posteingangs-Nachricht: Bilder und Audio kommen als ansehbarer Inhalt zurück, andere Typen als Beschreibung und, mit includeRawBase64, als Rohbytes. Holt die Daten beim ersten Aufruf vom Anbieter und speichert sie.
get_activities✓Aktivitäts-Timeline (Nachrichten und Audit-Log-Änderungen) für den Workspace oder einen Record.
send_chat_messageStellt sofort zu. Mit threadId antwortet es in einem bestehenden Chat; mit connectedAccountId plus attendeeIdentifiers startet es einen neuen (optionales chatName benennt eine Gruppe).
send_emailStellt sofort zu. Senden oder antworten von einem verbundenen E-Mail-Konto; kann einen gespeicherten Draft über draftMessageId senden.
save_message_draftAntwort zur Durchsicht vorbereiten: Der Draft erscheint in der Inbox-Compose-Box, und Sie senden ihn selbst. Drafts hängen am Thread, einer pro Thread, erneutes Speichern aktualisiert ihn.
discard_message_draft✓Draft per Draft-Message-ID löschen.
update_messaging_threadThread-State setzen: unread, open, closed oder spam.
connect_messaging_accountErzeugt einen Link, den der User im Browser öffnet, um einen Kanal zu verbinden (WhatsApp oder E-Mail). Sie geben den Link zurück; der User schließt die Auth dort ab. Läuft nach 30 Minuten ab.
pause_lead_sendingPausiert den automatischen Lead-Versand, ohne ruleId alle Regeln des Workspace. Eingereihte E-Mails bleiben eingereiht, eine gerade übergebene läuft zu Ende. Ein Fortsetzen gibt es über MCP bewusst nicht: Das kann nur ein angemeldeter Mensch im CRM.

Dokumentation und Deep Research

ToolReadDestructiveZweck
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

ToolReadDestructiveZweck
manage_custom_columns✓Ein Tool mit action-Schalter: list, upsert (anlegen oder aktualisieren), delete, set_auto_date, remove_auto_date. Deckt alle zehn Spaltentypen ab; type und entityType sind beim Update unveränderlich. Delete ist IRREVERSIBLE und löscht alle gespeicherten Werte. set_auto_date lässt eine Datumsspalte der Organisation (id) sich selbst mit dem heutigen Datum füllen, sobald eine andere Organisationsspalte (sourceColumnId) zum ersten Mal einen Wert bekommt; remove_auto_date schaltet das ab. Upsert setzt außerdem description (die ausdrückliche Regel, die Agenten lesen), learnFromEdits (Bearbeitungen durch Menschen werden Lernsignale) und reviewOnChange (Änderungen über MCP brauchen eine reviewNote).

Widgets

ToolReadDestructiveZweck
manage_widgets✓Ein Tool mit action-Schalter: list, get, create, update, delete. Die get-Action liefert die berechneten Datenpunkte zur Konfiguration dazu, aggregierte Summen kommen also direkt aus einem Widget.

Webhooks

ToolReadDestructiveZweck
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).

Projekte

ToolReadDestruktivZweck
manage_projects✓Ein Tool mit action-Schalter: list, get, create, update, archive, delete. Mitglieder sind Workspace-User-IDs, und ein Update ERSETZT die komplette Mitgliederliste. startDate/endDate (JJJJ-MM-TT, Ende nicht vor Start) legen den Zeitrahmen fest, progress (0 bis 100) den Fortschritt; bei einem Update bleiben weggelassene Werte erhalten, null löscht ein Datum. Bevorzugen Sie Action archive gegenüber delete: beim Löschen bleiben die Aufgaben erhalten, verlieren aber ihre Projektzuordnung.

Kampagnen

ToolReadDestruktivZweck
get_campaigns✓Listet die E-Mail- und WhatsApp-Kampagnen mit Status, Absender, Versandfenster, Taktung und Zählern je Empfängerstatus. Mit id kommt eine Kampagne samt einer Seite ihrer Empfänger (Adresse, Rechtsgrundlage, Status, Grund); senders: true listet die Postfächer, aus denen eine E-Mail-Kampagne senden darf.
manage_campaigns✓Ein Tool mit action-Schalter: create, update, add_recipients, remove_recipients, pause, cancel, delete. Es bereitet Kampagnen vor und hält sie an, kann aber nie eine starten oder fortsetzen: das kann nur ein Mensch in der CRM-Oberfläche. Bei E-Mail ist consentBasis Pflicht und eine rechtliche Aussage, die vom Nutzer kommen muss; express_consent braucht consentEvidence, existing_customer wird für Kontakte ohne Deal oder Rechnung abgelehnt. Gesperrte und abgemeldete Adressen werden übersprungen. Eine WhatsApp-Kampagne lässt sich nur abbrechen, nicht pausieren.

Insights und Follow-ups

ToolReadDestruktivZweck
get_sales_insights✓Das Standard-Dashboard: Nettoumsatz pro Monat über 12 Monate (bezahlt und offen), die letzten 12 Monate gegen die 12 davor, wiederkehrender Umsatz pro Monat, aktive, ehemalige und neue Kunden, offene und überfällige Rechnungen, offene Angebote, der Lead-Funnel, die Verteilung jeder Lead- oder Statusspalte und die offenen Follow-ups je Art. Beträge in ganzen Cent.
get_follow_ups✓Listet die erkannten Follow-ups, wichtigste zuerst: offene Rechnungen (1, 7 und 14 Tage nach Fälligkeit), offene Angebote, Aufträge ohne Rechnung, stehende Deals, Leads ohne Antwort, ehemalige Kunden und Upsell-Chancen aus dem, was ähnliche Kunden gekauft haben. Jeder Eintrag trägt den Grund, den empfohlenen Kanal samt Empfänger, du oder Sie aus dem Mailverlauf und einen fertigen Entwurf. settings: true liefert die Einstellungen des Workspace.
update_follow_upaction set_status markiert ein Follow-up als erledigt oder verworfen und entfernt seine Aufgabe; action scan startet die Erkennung sofort. Beides sendet nichts: eine Nachricht geht nur von der Insights-Seite oder über ein Sende-Tool raus, mit dem Go des Nutzers.

Teams

ToolReadDestruktivZweck
manage_teams✓Ein Tool mit action-Schalter: list, get, create, update, delete, add_member, remove_member, list_rules, set_rule, delete_rule, resolve. Der key eines Teams ist das feste Kleinbuchstaben-Kürzel, über das ein Ticket-Router das Team anspricht. Eine Routing-Regel ohne organizationId ist der Workspace-Standard; eine mit organizationId überschreibt ihn für genau diesen Kunden. Strategie all benachrichtigt alle Zuständigen, roundRobin wählt eine Person über rotationSeed, leastOpen nimmt die Person mit den wenigsten zugewiesenen Aufgaben, none lässt das Ticket bewusst unzugewiesen. Greift keine Regel, antworten die Team-Leads, danach das ganze Team. Action resolve beantwortet „wer bekäme dieses Ticket“, ohne etwas zu schreiben.

Abrechnung

ToolReadDestruktivZweck
manage_billing✓Ein Tool mit action-Schalter für die Kette Angebot → Auftrag → Rechnung → Gutschrift: list, get, create, update, status, convert, payment, send, einvoice, profile, delete. Alle Beträge sind ganzzahlige CENT (1250 sind 12,50 €), und Summen werden immer aus den Positionen gerechnet, nie übergeben. Beim Verlassen des Entwurfs vergibt das System die endgültige Nummer, die sich danach nie mehr ändert; nummerierte Dokumente lassen sich nur stornieren, nicht löschen. Action send hängt PDF und, sofern die Rechnung vollständig ist, die E‑Rechnung an; mit scheduledSendAt wird stattdessen terminiert, mit testCopy: true und ausdrücklichem to geht eine Testkopie raus, die keine Nummer vergibt, nichts als versendet markiert und den Kunden nicht erreicht.
manage_recurring_invoices✓Ein Tool mit action-Schalter: list, create, update, delete. Eine Serie wiederholt eine bestehende Rechnung als Vorlage; die Vorlage selbst wird nie versendet. Mit autoSend geht jede Ausgabe sofort raus, sonst landet sie als Entwurf zur Kontrolle. status: paused hält eine Serie an, ohne sie zu löschen.
get_finance_report✓Zwei Berichte: datev liefert einen DATEV-EXTF-Buchungsstapel für den Zeitraum samt Liste der übersprungenen Belege mit Begründung, revenue-plan eine Monatsvorschau aus Zahlungseingängen, offenen Rechnungen, bestätigten Aufträgen, geplanten Serienrechnungen und offenen Angeboten, gewichtet mit offerProbabilityPercent.

Zeiterfassung

ToolReadDestruktivZweck
manage_time_tracking✓Ein Tool mit action-Schalter: list, create, update, delete, start, stop, running, preview_billable, bill, release. Dauern sind ganze MINUTEN, Sätze ganzzahlige CENT pro Stunde: 9000 sind 90,00 € pro Stunde. Ein Eintrag braucht eine taskId oder eine organizationId; auf eine Aufgabe gebuchte Zeit zählt auch für die Kunden, mit denen die Aufgabe verknüpft ist. Ohne Satz greift der Satz der Leistung, danach der Workspace-Standardstundensatz. Action preview_billable zeigt die Rechnungspositionen, die die offene Zeit eines Kunden ergeben würde, ohne etwas zu schreiben; action bill hängt sie an ein ENTWURF-Dokument und markiert die Einträge in derselben Transaktion als abgerechnet, sodass dieselbe Stunde nie auf zwei Rechnungen landen kann. Ein Dokument, das den Entwurf verlassen hat, wird abgelehnt. Action release nimmt die Zeit wieder vom Entwurf und entfernt die dafür angelegten Positionen.

Anreicherung

ToolReadDestruktivZweck
infer_contact_email✓Leitet eine wahrscheinliche E-Mail-Adresse aus dem Muster ab, das Kolleginnen und Kollegen derselben Domain bereits verwenden. Liefert einen Vorschlag mit Konfidenz strong oder weak. Weak heißt: nur eine stützende Adresse, oder ein Umlaut, dessen Schreibweise (mueller vs. muller) die Domain nie belegt hat. Einen weak-Vorschlag als Vermutung kennzeichnen und niemals an eine abgeleitete Adresse senden, ohne das zu sagen. Ohne domain und nur mit contactId wird die Domain genommen, die die meisten Kolleginnen und Kollegen der Organisation des Kontakts verwenden.

WhatsApp

ToolReadDestruktivZweck
manage_whatsapp_session✓Die eigene WhatsApp-Nummer des aufrufenden Nutzers auf der selbst gehosteten WAHA-Instanz verbinden oder trennen. Jeder Nutzer erhält eine eigene Sitzung, nie geteilt mit Kolleginnen und Kollegen. Action connect liefert einen QR-Code, den ein Mensch mit dem Telefon der Nummer scannen muss; action status liest den Kopplungsstand neu und liefert einen frischen Code; action logout trennt die Nummer. Connect und logout erfordern Administratorrechte.
send_whatsapp_messageEine Textnachricht, optional mit base64-kodierten Dateianhängen (je nach MIME-Typ als Foto, Sprachnachricht oder Dokument, insgesamt 25 MB), von der gekoppelten Nummer senden. Nur für Konversationen, die der Kontakt begonnen hat oder in die er eingewilligt hat. WAHA ist ein inoffizieller Transport, und Kaltakquise riskiert die Sperrung der Nummer und ist nach UWG §7 unzulässig. Eine über die offizielle Cloud API verbundene Nummer antwortet nur innerhalb von 24 Stunden nach der letzten Nachricht des Kontakts und nicht in Gruppen; Marketing-Vorlagen gehen nur über eine Kampagne.
list_whatsapp_groups✓Listet die WhatsApp-Gruppen, in denen die eigene gekoppelte Nummer Mitglied ist, mit id, Name und Teilnehmerzahl. Die id einer Gruppe als to bei send_whatsapp_message oder als attendeeIdentifiers-Eintrag bei send_chat_message verwenden, um in diese Gruppe zu senden.

Admin und Team

ToolReadDestructiveZweck
update_workspace_settingstarget profile aktualisiert Ihren Namen, Ihr Land und Ihren Avatar; target company aktualisiert die Workspace-Währung (nur Admins).
manage_teamMitglieder per E-Mail einladen (Action invite, bis 20, verschickt echte Einladungs-E-Mails) oder Rolle und Status eines Mitglieds ändern (Action update_member).

Support

ToolReadDestructiveZweck
request_supportÖffnet ein Support-Ticket beim Virtual Marketer CRM-Team (Betreff plus Beschreibung). Das Team meldet sich per E-Mail und im In-App-Chat. Gibt die Ticketnummer zurück.

Audit-Log

ToolReadDestructiveZweck
get_audit_changes✓Liest das Audit-Log als Änderungen je Feld, neueste zuerst: Ereignis, Record, Autor, Zeitpunkt und je Änderung Feld, Custom-Column-Id sowie den vollständigen alten und neuen Wert. Filter nach Nutzer, Record, Ereignisnamen, Custom Columns und Zeitraum, weitere Seiten über before. Notizen kommen als Markdown. Schreibvorgänge direkt in der Datenbank stehen nicht im Log. Braucht Leserecht auf das Audit-Log.
revert_audit_entries✓Bis zu 50 Audit-Log-Einträge zurücknehmen. Eine Anlage wird zurückgenommen, indem der Record gelöscht wird, solange es ihn noch gibt; ein Update wird Feld für Feld zurückgenommen, und nur dort, wo der Record noch genau den Wert trägt, den dieser Eintrag geschrieben hat. Ein seither geändertes Feld bleibt unangetastet und wird mit beiden Werten gemeldet. Löschungen und Zeiterfassung werden abgelehnt. Gilt für Organization-, Contact-, Deal-, Service- und Task-Records, deren native Felder und Custom-Column-Werte, nie für deren Beziehungen. Braucht dieselbe Berechtigung wie der ursprüngliche Schreibzugriff, dazu Leserecht auf das Audit-Log. Mit dryRun wird nur berichtet, nicht geschrieben.

Die Rücknahme wird selbst ins Audit-Log geschrieben und dem Aufrufer zugeordnet. Diese Einträge sind ihrerseits nicht zurücknehmbar, und genau das verhindert eine Endlosschleife.

Eingrenzen mit ?toolsets=

Alle 62 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://crm.virtual-marketer.de/api/v1/mcp?toolsets=records,messaging

Keys: records, workspace, messaging, docs, custom-columns, widgets, webhooks, projects, campaigns, insights, teams, billing, time-tracking, enrichment, whatsapp, admin, support, audit. 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.

Bei einem selbst erstellten Key ist ?toolsets= eine Bequemlichkeit, keine Berechtigung: der Parameter kommt aus der Request-URL, wer den Key hat, lässt ihn einfach weg und erreicht die volle Oberfläche. Behandeln Sie jeden API-Key als Vollzugriff auf alles, was Ihre Rolle darf.

Der Key, mit dem sich der Virtual-Marketer-Agent verbindet

Wer sich mit einem Virtual-Marketer-Konto im CRM anmeldet, bekommt automatisch einen API-Key namens Virtual Marketer Agent, der Agent ist damit verbunden, ohne dass jemand einen Key abtippt. Er steht unter Profil → API & Konnektoren neben Ihren eigenen Keys und lässt sich dort widerrufen; die nächste Anmeldung legt einen neuen an.

Dieser Key ist der eine Fall, in dem die Toolset-Liste erzwungen und nicht nur vorgeschlagen wird. Er ist an records, workspace, docs, enrichment und projects gebunden, delete_records ist ausgenommen. Fragt eine Anfrage mit diesem Key nach messaging, whatsapp, admin oder billing, oder lässt sie ?toolsets= ganz weg, sieht sie trotzdem nur die gebundenen Gruppen. Die Bindung hängt am Key, nicht an der URL.

Die gebundene Oberfläche ist gröber als das Risiko, das sie einhegt: Toolset-Gruppen sind die Einheit der Eingrenzung, und records bringt Anlegen, Ändern und Lesen gemeinsam mit. Alles, was der Key tut, geschieht als Sie, unter Ihrer eigenen Rolle, er erreicht also keinen Datensatz, den Ihr Konto nicht erreicht.

Eingebaute Sicherheitsregeln

  • Bestätigen vor destruktiven Aktionen. Die Server-Instructions weisen das Modell an, sich vor delete_records und vor jedem Send-Tool beim User rückzuversichern.
  • Beziehungen nur über manage_record_links. Die Update-Tools fassen Beziehungen nie an, und null auf einem Relationship-Array wird serverseitig mit Remediation-Hint abgelehnt.
  • Erst Draft, dann Send. send_email und send_chat_message stellen sofort zu. Wer eine Nachricht vorbereitet haben will, bekommt sie über save_message_draft, und Sie senden sie aus der Inbox. Drafts hängen am Thread; eine komplett neue ausgehende Nachricht lässt sich nicht als Draft anlegen.
  • Destructive-Flags überall. Jedes destruktive Tool und jede destruktive Action hat destructiveHint: true und den Präfix IRREVERSIBLE in der Beschreibung.
  • Jedes Enum-Feld listet gültige Werte inline in der Beschreibung, und jedes filters-Feld enthält ein konkretes JSON-Beispiel.

Weiter

  • Custom Connector: End-to-End-Setup auf einer Seite.
  • Filter-Syntax: jeder Operator mit Beispielen.
  • Webhooks: die andere Hälfte des agentischen Loops.
Wann MCP passt
Der Endpoint
Client verbinden
Server-Instructions, Prompts und Toolsets
Der Virtual Marketer Agent
Ausdrückliche Regeln und implizites Lernen
Kritische Prüfung von Zielgruppe und Stil
Wie die Tool-Oberfläche gebaut ist
CLI-Nutzung
OpenAPI neben MCP
Tool-Katalog
Records
Workspace
Messaging
Dokumentation und Deep Research
Custom Columns
Widgets
Webhooks
Projekte
Kampagnen
Insights und Follow-ups
Teams
Abrechnung
Zeiterfassung
Anreicherung
WhatsApp
Admin und Team
Support
Audit-Log
Eingrenzen mit ?toolsets=
Der Key, mit dem sich der Virtual-Marketer-Agent verbindet
Eingebaute Sicherheitsregeln
Weiter