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
Configure MCP Server
Ensure HatiData MCP server is running and connected to Claude Desktop.
# Start HatiData (if not running)
hati init
# Verify MCP server is available
curl -s http://localhost:5440/health | python3 -m json.tool{
"status": "healthy",
"tools": 24,
"triggers_enabled": true
}Note: The MCP server exposes trigger management tools: register_trigger, list_triggers, delete_trigger, test_trigger.
Register a Trigger via MCP
Use the register_trigger MCP tool to create a webhook trigger.
# 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"Trigger registered successfully:
Name: security-alert
Concept: data breaches, security vulnerabilities, unauthorized access
Threshold: 0.7
Action: webhook → https://your-app.com/hooks/securityNote: The trigger concept is embedded into a vector and stored in the vector index. All future agent content is matched against it.
Set Up Webhook Receiver
Create a simple webhook receiver that validates HMAC signatures and logs events.
# 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()Webhook receiver listening on :9090Test the Trigger
Use the test_trigger MCP tool to verify matching without firing the webhook.
# 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"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 sentNote: test_trigger runs the full evaluation pipeline without actually firing the action. Use it to tune thresholds.
Monitor Live Trigger Events
Query the trigger event log to see all firings and their details.
# 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"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 OKNote: The event log records every trigger firing, including the webhook HTTP status code for monitoring delivery.