Skip to main content
Glama
jorgemovitext

Voice Brain MCP Server

Voice Brain MCP — Prototyp Sprachsteuerung (NL Pearl v2) + Brain (MCP) + Kanäle

Prototyp eines Sprach-Gateways auf Basis von NL Pearl v2 mit einem "Brain" für einheitlichen Kontext pro Kontakt (kanalunabhängig), ebenfalls als MCP-Server verfügbar, sowie einer Angular 22-Konsole zur Bedienung des Ablaufs.

Läuft End-to-End im Mock-Modus ohne Anmeldedaten. Die echten Adapter für NL Pearl v2 sind bereit zur Anbindung.

Funktionen

  • Sprache: NL Pearl v2 als Engine hinter unserem eigenen Gateway (weder deren Konsole noch deren Textkanäle werden verwendet). Der ausgehende Anruf wird mit addLead ausgelöst; vor dem Sprechen fordert der Knoten PreCallAPI den Kontext von POST /precall an; nach Beendigung bringt der Webhook POST /webhooks/nlpearl die Benachrichtigung und das Gateway ruft Transkription/Zusammenfassung/Sentiment/Daten ab.

  • Brain: Einheitlicher Kontext pro Kontakt (Identität, kanalübergreifende Timeline, Signale wie Zahlungsversprechen). Verfügbar über REST für die Konsole und als MCP-Server (stdio) mit Tools brain_*.

  • Eigene Kanäle: WhatsApp/SMS (Stubs mit Platz für WABA/SMS-Anbieter) lesen und schreiben denselben Kontext → die Nachverfolgung setzt denselben Thread fort.

Related MCP server: Customer Support MCP Server

Flussdiagramm (Demo)

 consola /demo ──POST /api/demo/run──▶ DemoService
   1. siembra contacto (promesa activa + WhatsApp previo)
   2. addLead (VoiceEnginePort → mock | NL Pearl v2)
        │
        ▼  (ciclo de llamada)
   3. POST /precall  ◀── nodo PreCallAPI      → variables (nombre, promesa, saldo, último resumen)
   4. ... conversación ...
   5. POST /webhooks/nlpearl (HMAC guard)     → getCall → Brain.recordCallContext
        │                                        · interacción voice + señal promesa
        ▼
   6. FollowupService → brain_suggest_followup → WhatsApp propio (stub)
        │                                        · interacción whatsapp outbound
        ▼
   7. consola: timeline del contacto con voz + WhatsApp en el mismo hilo

Struktur

voice-brain-mcp/
├─ apps/
│  ├─ api/        # NestJS 11 + Fastify: Brain, NL Pearl, canales, MCP, demo
│  └─ console/    # Angular 22 (signals + zoneless). Vistas:
│                 #   /home           inicio con avatar de voz
│                 #   /contacts       directorio de contactos
│                 #   /contacts/:id   chat + contexto en vivo (2 columnas)
│                 #   /conversations  módulo de conversaciones: lista de hilos
│                 #                   + chat + contexto en vivo (3 columnas)
│                 #   /demo           flujos end-to-end paso a paso
├─ scripts/run-demo.mjs
├─ data/brain.json   # respaldo de persistencia (se crea al correr)
└─ .env              # copiar de .env.example

Ausführung

Voraussetzungen: Node 20+ (getestet mit Node 24).

cp .env.example .env     # MOCK=true por defecto
npm install

npm run dev              # api (3000) + consola (4200) juntos
# o por separado:
npm run dev:api
npm run dev:console
  • Konsole: http://localhost:4200 → Tab Demo des Ablaufs → „End-to-End-Ablauf ausführen“. Am Ende gibt es einen Link zum Kontext des Kontakts (Sprache + WhatsApp in derselben Timeline).

  • Demo per CLI (bei laufender API): npm run demo

  • Tests: npm test · Build: npm run build

Bereitgestellt

https://voice-brain-mcp.vercel.app — läuft im Mock-Modus, ohne Anmeldedaten.

Auf Vercel bereitstellen (von GitHub)

Das Repository enthält bereits vercel.json und die serverlose Funktion in api/index.js.

git init && git add -A && git commit -m "Prototipo voz + Brain MCP"
git remote add origin git@github.com:<usuario>/<repo>.git
git push -u origin main

In Vercel: Add New → Project → Import dieses Repository und Deploy. vercel.json definiert den Build, veröffentlicht die Angular-Konsole als statische Dateien und leitet /api/*, /precall und /webhooks/* an die Nest-Funktion weiter.

Ein einziges Projekt, mit Root Directory im Stammverzeichnis des Repos. Der Build toleriert, dass Vercel innerhalb eines Workspaces startet, aber die serverlose Funktion befindet sich in api/index.js (Stammverzeichnis) und Vercel erkennt sie nur, wenn das Root Directory dieses Stammverzeichnis ist. Bei getrennten Projekten pro Workspace wird die Konsole zwar bereitgestellt, aber /api/* antwortet mit 404.

Warum der Build ein Skript ist und nicht npm run --workspace (zwei Fallstricke von Vercel mit npm-Monorepos, beide bereits in scripts/vercel-build.sh behoben):

  • Ein Skript namens vercel-build im Stamm-package.json funktioniert nicht: Vercel behandelt es speziell und npm propagiert es an jeden Workspace, der es nicht definiert → Missing script: "vercel-build".

  • npm run build --workspace apps/api schlägt mit No workspaces found fehl, wenn Vercel den Build aus einem Unterverzeichnis ausführt. Das Skript findet das Stammverzeichnis des Monorepos selbstständig und ruft nest/ng mit npx auf, sodass es von jedem Ort aus funktioniert.

Sollte das Deployment erneut fehlschlagen, überprüfen Sie die ersten Zeilen des Logs: Das Skript gibt cwd initial und Stamm des Monorepos aus, die genau anzeigen, von wo Vercel gestartet ist.

Umgebungsvariablen (Project → Settings → Environment Variables): keine ist erforderlich — ohne Angaben läuft das Deployment im Mock-Modus. Für die echte NL-Pearl-Anbindung setzen Sie MOCK=false, NLPEARL_ACCOUNT_ID, NLPEARL_API_KEY, NLPEARL_PEARL_ID und NLPEARL_WEBHOOK_SECRET, und richten Sie den Webhook des Pearls auf https://<ihr-deploy>.vercel.app/webhooks/nlpearl sowie den PreCallAPI-Knoten auf https://<ihr-deploy>.vercel.app/precall.

Was sich serverlos ändert (und warum)

Vercel friert den Prozess nach der Antwort ein und nur /tmp ist beschreibbar, daher passt sich der Code automatisch an (erkennt VERCEL):

  • Persistenz: Das JSON-Backup geht nach /tmp. Jede Instanz hat ihre eigene Kopie, die beim Recycling verloren geht — ausreichend für Demos, nicht für die Produktion (ersetzen Sie BrainRepository durch SQLite/Postgres dafür).

  • Kaltstart-Befüllung: Wenn das Brain leer startet, wird das Demo-Verzeichnis mit festen IDs befüllt, damit die Links /contacts/:id zwischen Instanzen gültig bleiben.

  • Demo-Ablauf: Wird innerhalb der Anfrage abgeschlossen (keine Hintergrund-Timer) und die Schritte werden in der Antwort übermittelt, da Polling auf eine andere Instanz fallen könnte.

  • Mock: Verwendet die In-Prozess-Dienste anstatt sich selbst per HTTP aufzurufen (der Deployment-Schutz würde diesen Selbstaufruf blockieren). Lokal wird weiterhin echtes HTTP gegen /precall und /webhooks/nlpearl verwendet.

  • MCP: Der stdio-Server ist auf Vercel nicht anwendbar; er läuft lokal mit npm run mcp.

Brain als MCP-Server

npm run mcp                                    # servidor stdio
npx @modelcontextprotocol/inspector npm run mcp  # probarlo con el inspector

Tools: brain_resolve_identity, brain_get_context, brain_upsert_contact, brain_append_interaction, brain_set_signal, brain_get_signals, brain_record_call_context, brain_suggest_followup.

Teilt die Persistenz (JSON-Datei) mit dem HTTP-Gateway.

Echte NL-Pearl-Anbindung

  1. In .env: MOCK=false, NLPEARL_ACCOUNT_ID, NLPEARL_API_KEY und NLPEARL_PEARL_ID (Pearl für ausgehende Sprachkommunikation). Auth in der Dokumentation bestätigt: Authorization: Bearer {AccountId}:{SecretKey}.

  2. In NL Pearl: Konfigurieren Sie den Pearl-Ablauf mit dem Knoten PreCallAPI, der auf https://ihr-host/precall zeigt, und aktivieren Sie den Anruf-Webhook, der auf https://ihr-host/webhooks/nlpearl zeigt.

    Wo sich der Webhook befindet (nicht Workspace-weit, sondern pro Pearl): Dashboard (verlassen Sie Settings mit Go Back) → öffnen Sie Ihren Pearl → Flusseditor PearlVibe → Tab Outbound Settings (oder Inbound Settings) → Gruppe Campaign Settings → scrollen Sie ganz nach unten, Abschnitt Webhooks → aktivieren Sie den Schalter (die URL-Felder erscheinen erst nach Aktivierung) → Call Webhook URL. Der Lead Webhook wird nicht verwendet. Hinweis: In den Workspace-Einstellungen ist Agent(s) die Kapazität für gleichzeitige Anrufe, nicht die Pearls; und Text Channels wird nicht verwendet (WhatsApp/SMS sind unsere eigenen).

  3. NLPEARL_WEBHOOK_SECRET: NL Pearl signiert Webhooks nicht mit HMAC — beim Konfigurieren des Webhooks können Sie ein Credential (einen von Ihnen erstellten Token) anhängen, der mit jeder Zustellung übermittelt wird. Setzen Sie denselben Wert in NLPEARL_WEBHOOK_SECRET und der Wächter wird ihn überprüfen; leer = keine Anforderung.

  4. Die gegen die v2-Dokumentation bestätigten Pfade befinden sich in apps/api/src/nlpearl/nlpearl.client.ts; die nicht verifizierten wurden mit // TODO: confirmar con NL Pearl markiert (ebenso wie die genaue Form des Webhooks und des PreCallAPI in webhook.controller.ts / precall.controller.ts).

Entscheidungen / Notizen

  • Ports als Injection-Tokens (VoiceEnginePort, ChannelPort, BrainRepository): Das Mock/echte Binding lebt in jedem Adaptermodul gemäß MOCK; das Brain importiert nie konkrete Clients.

  • Der Mock übt die echten HTTP-Endpunkte des Gateways aus (Self-HTTP an /precall und /webhooks/nlpearl, mit HMAC-Signatur falls Secret vorhanden), keine internen Abkürzungen.

  • Persistenz: Speicher + JSON-Backup hinter BrainRepository (austauschbar gegen SQLite/Postgres über Provider).

  • Die Textkanäle von NL Pearl werden nicht verwendet: WhatsApp/SMS sind eigene Adapter (Stubs mit Logging).

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides AI agents with operational customer context, including typed revenue objects, persistent state, scoped tools, and human-in-the-loop handoffs through MCP, REST, and CLI.
    7 npm
    12
    Apache 2.0
  • F
    license
    Not graded
    quality
    B
    maintenance
    Provides MCP tools that let an agent retrieve customer account, product usage, interaction, and support summaries, and create follow-up tasks after user approval.
    -