← All Cookbooks
MCPIntermediate20 min

MCP + HatiData: Trigger to Webhook Pipeline

Build an MCP-based trigger pipeline that fires HMAC-signed webhooks when agents discuss specific topics. Monitor agent conversations in real-time.

What You'll Build

An MCP-based trigger pipeline that fires HMAC-signed webhooks when agents discuss specific topics.

Prerequisites

$hati init

$Claude Desktop or MCP client

$Webhook endpoint

Architecture

┌──────────────┐  MCP   ┌──────────────┐    ┌──────────────┐
│   Claude     │──────▶│  HatiData    │───▶│ Vector Index │
│  Desktop     │       │  Triggers    │    │  matching    │
└──────────────┘       └──────┬───────┘    └──────────────┘
                              │ fires
                       ┌──────▼───────┐
                       │   Webhook    │
                       │ HMAC-SHA256  │
                       └──────────────┘

Key Concepts

  • Semantic triggers: vector ANN pre-filters content against trigger concepts, followed by exact cosine verification
  • HMAC-SHA256 signing: webhook payloads are signed so receivers can verify they came from HatiData
  • Test mode: test_trigger runs the full evaluation without firing, letting you tune thresholds safely
  • Event log: all trigger firings are logged with similarity scores, matched content, and webhook delivery status

Step-by-Step Implementation

1

Configure MCP Server

Ensure HatiData MCP server is running and connected to Claude Desktop.

Bash
# Start HatiData (if not running)
hati init

# Verify MCP server is available
curl -s http://localhost:5440/health | python3 -m json.tool
Expected Output
{
    "status": "healthy",
    "tools": 24,
    "triggers_enabled": true
}

Note: The MCP server exposes trigger management tools: register_trigger, list_triggers, delete_trigger, test_trigger.

2

Register a Trigger via MCP

Use the register_trigger MCP tool to create a webhook trigger.

text
# In Claude Desktop, say:
"Register a trigger called 'security-alert' that fires when anyone
 discusses data breaches, security vulnerabilities, or unauthorized access.
 Set the threshold to 0.7 and send webhooks to https://your-app.com/hooks/security"

# Claude calls register_trigger MCP tool:
# Tool: register_trigger
# Arguments:
#   name: "security-alert"
#   concept: "data breaches, security vulnerabilities, unauthorized access"
#   threshold: 0.7
#   action: "webhook"
#   webhook_url: "https://your-app.com/hooks/security"
Expected Output
Trigger registered successfully:
  Name: security-alert
  Concept: data breaches, security vulnerabilities, unauthorized access
  Threshold: 0.7
  Action: webhook → https://your-app.com/hooks/security

Note: The trigger concept is embedded into a vector and stored in the vector index. All future agent content is matched against it.

3

Set Up Webhook Receiver

Create a simple webhook receiver that validates HMAC signatures and logs events.

Python
# webhook_server.py
from http.server import HTTPServer, BaseHTTPRequestHandler
import hmac
import hashlib
import json

SECRET = "your-webhook-secret"

class WebhookHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        length = int(self.headers.get("Content-Length", 0))
        body = self.rfile.read(length)

        # Verify HMAC signature
        sig = self.headers.get("X-HatiData-Signature", "")
        expected = hmac.new(SECRET.encode(), body, hashlib.sha256).hexdigest()

        if hmac.compare_digest(sig, expected):
            data = json.loads(body)
            print(f"TRIGGER: {data['trigger_name']}")
            print(f"  Agent: {data['agent_id']}")
            print(f"  Score: {data['similarity_score']:.2f}")
            print(f"  Content: {data['matched_content'][:100]}")
            self.send_response(200)
        else:
            print("INVALID SIGNATURE — rejected")
            self.send_response(401)

        self.end_headers()

print("Webhook receiver listening on :9090")
HTTPServer(("", 9090), WebhookHandler).serve_forever()
Expected Output
Webhook receiver listening on :9090
4

Test the Trigger

Use the test_trigger MCP tool to verify matching without firing the webhook.

text
# In Claude Desktop, say:
"Test the security-alert trigger with this text:
 'We discovered an unauthorized access attempt on the production database last night'"

# Claude calls test_trigger MCP tool:
# Tool: test_trigger
# Arguments:
#   name: "security-alert"
#   content: "We discovered an unauthorized access attempt on the production database last night"
Expected Output
Trigger test result:
  Matched: true
  Similarity: 0.84
  Would fire: yes (above 0.7 threshold)
  Action: webhook to https://your-app.com/hooks/security
  Note: test mode — webhook not actually sent

Note: test_trigger runs the full evaluation pipeline without actually firing the action. Use it to tune thresholds.

5

Monitor Live Trigger Events

Query the trigger event log to see all firings and their details.

text
# In Claude Desktop, say:
"Show me all security-alert trigger firings from today"

# Claude calls query MCP tool:
# Tool: query
# Arguments:
#   sql: "SELECT trigger_name, agent_id, similarity_score,
#         matched_content, fired_at, webhook_status
#         FROM _hatidata_triggers.events
#         WHERE trigger_name = 'security-alert'
#           AND fired_at > CURRENT_DATE
#         ORDER BY fired_at DESC
#         LIMIT 10"
Expected Output
trigger_name     | agent_id    | similarity | fired_at            | webhook_status
-----------------|-------------|------------|---------------------|---------------
security-alert   | analyst-bot | 0.84       | 2026-02-28 15:30:00 | 200 OK
security-alert   | report-gen  | 0.79       | 2026-02-28 14:15:00 | 200 OK

Note: The event log records every trigger firing, including the webhook HTTP status code for monitoring delivery.

Ready to build?

Install HatiData locally and start building with MCP in minutes.

Join Waitlist