Skip to main content

Real-time Events & MCP Integration

ItBuild provides a unified event system for browser and backend notifications through SSE (Server-Sent Events), Web Push, and Webhooks, plus MCP (Model Context Protocol) integration for AI agents.

Architecture Overview

graph LR
subgraph "Modules"
W[TrexWallet]
C[Chat]
end

subgraph "AuthProxy"
E[events API]
H[EventHub]
S[SSE Endpoint]
WH[Webhooks]
M[MCP Server]
end

subgraph "Clients"
PWA[PWA Frontend]
AI[AI Agent]
EXT[External System]
end

W --> E
C --> E
E --> H
H --> S
H --> WH
H --> M

S --> PWA
M --> AI
WH --> EXT

Event Delivery Channels

ChannelUse CaseClientCursor
SSEReal-time UI updatesPWA FrontendSingle global TimeTick
Web PushBackground browser deliveryService worker on the same originReuses normalized module events
WebhooksBackend integrationsExternal systemsPer-app cursor
MCPAI agent actionsClaude Code, etc.N/A

Operationally, AuthProxy normalizes module events once and can then fan them out to multiple transports:

  • active tabs usually consume the event over SSE
  • background browsers can receive the same business event over Web Push if the browser subscription exists and the browser can still wake its service worker
  • backend systems can receive the same event through webhooks

SSE (Server-Sent Events)

Connecting

// PWA Frontend
const eventSource = new EventSource('/auth/v1/subscribe?since=' + lastTick);

eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
// data = { module: "wallet", tick: 123, type: "TxInWallet", data: {...} }

// Store max tick for reconnection
localStorage.setItem('lastTick', Math.max(lastTick, data.tick));

// Handle event
handleEvent(data);
};

Reconnection with Cursor

The since parameter enables reconnection without losing events:

  1. First connection: No since parameter
  2. Store the max tick from received events in localStorage
  3. On reconnect: Pass since={stored_tick} to receive missed events

Web Push

Web Push complements SSE instead of replacing it.

  • Subscription API: /auth/v1/notifications/public_key, /auth/v1/notifications/subscribe, /auth/v1/notifications/unsubscribe, /auth/v1/notifications/test
  • Worker ownership: one canonical root sw.js on the AuthProxy origin
  • Recommended model: SSE for active tabs, Web Push for background delivery
  • Detailed setup: see Browser Push Notifications

Important caveats:

  • a successful push test validates sender transport, not the full module event pipeline
  • real business push still depends on module GET /private/v1/events output reaching AuthProxy EventPoller
  • a fully terminated browser process may still prevent delivery on some OS/browser combinations

Event Format (BroadcastEvent)

{
"module": "wallet",
"tick": 17234567890012,
"type": "TxInWallet",
"data": {
"id": "17234567890010",
"currency": "USDT",
"tx_type": 1,
"state": 2,
"amount": 100.50,
"fee": 0.10,
"datetime": "2026-02-04T12:30:00Z"
}
}

Event Types

Wallet Events (TrexWallet)

TypeDescriptionData
TxInWalletNew transactionTxEventOut
TxStateChangedTransaction state updatedTxEventOut
BalanceChangedBalance updatedBalance info

Chat Events (Chat)

TypeDescriptionData
NewChatMessageNew messageChatEventOut
MessageReadMessage read statusMessage IDs
ChatCreatedNew chat createdChat info

Typed Event Data

TxEventOut (Wallet Transactions)

Wallet events include transaction id, cursor tick, currency, transaction type, state, amount, fee, optional partner metadata, and event time. All platform ids are serialized as strings.

ChatEventOut (Chat Messages)

Chat events include message id, cursor tick, sender, chat id, content, optional file metadata, flags, and event time. All platform ids are serialized as strings.

Webhooks

Webhooks deliver events to external systems based on app subscriptions.

Configuration

Register the webhook URL in the application settings. The platform stores the callback URL with the app record and dispatches enabled event types to it.

Webhook Payload

{
"events": [
{
"module": "wallet",
"tick": 17234567890012,
"type": "TxInWallet",
"app_id": 123456,
"data": { /* TxEventOut */ }
}
]
}

Signature Verification

Webhooks include X-Signature header with HMAC-SHA256 signature.

import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)

MCP Integration (Model Context Protocol)

MCP enables AI agents (like Claude Code) to interact with ItBuild platform.

Architecture

Claude Code ──MCP Protocol──▶ AuthProxy MCP Server ──REST API──▶ Modules

Available Tools

ToolDescriptionModule
wallet_balanceGet wallet balanceTrexWallet
wallet_transactionsList transactionsTrexWallet
wallet_sendSend fundsTrexWallet
chat_messagesGet chat messagesChat
chat_sendSend messageChat
user_infoGet user profileCRM

Tool Examples

wallet_balance

{
"name": "wallet_balance",
"arguments": {
"currency": "USDT"
}
}

Response:

{
"currency": "USDT",
"balance": 1234.56,
"hold": 100.00,
"available": 1134.56
}

chat_send

{
"name": "chat_send",
"arguments": {
"chat_id": "123456789",
"content": "Hello from AI agent!"
}
}

Authentication

MCP tools authenticate using:

  1. Session - For user-context operations
  2. API Key - For service-context operations

Events API (Internal)

Modules expose /private/v1/events endpoint for AuthProxy to fetch events. The contract is capability-based (introduced 2026-03 with the generic SSE mode): the caller passes the set of subjects it cares about and the module returns events scoped to that intersection.

Request

GET /private/v1/events?since=17234567890000&subjects=user:123,user:456,app:789&limit=100
ParameterDescription
sinceCursor (timetick_update) — fetch events after this.
subjectsComma-separated list of capability subjects. Each subject is kind:id, e.g. user:123 (CRM user), app:42 (verified app), code:K8HS73G8CJB7P (anonymous chat invite). The module only returns events whose addressee intersects the requested set.
usersLegacy alias for user: subjects (still accepted).
appsLegacy alias for app: subjects (still accepted).
limitMax events to return.

The unified subjects parameter lets a single SSE pipeline serve authenticated browsers, anonymous code-based chats, and webhook subscribers without a per-flavour endpoint. AuthProxy resolves the active subjects from the session (crm_id, owned apps, anonymous capability tokens) and forwards them to each module.

Response (EventBatch)

{
"Events": [
{
"CrmId": 123,
"AppId": 0,
"Timetick": 17234567890012,
"TickUpdate": 17234567890013,
"EventType": "TxInWallet",
"Data": { /* typed event data */ }
}
],
"LastTick": 17234567890013
}

Implementation Checklist

For Module Developers

  • Implement /private/v1/events endpoint
  • Return EventBatch with proper TickUpdate cursor
  • Include typed Data (e.g., TxEventOut, ChatEventOut)
  • Support users filter for SSE delivery
  • Support apps filter for Webhook delivery

For Frontend Developers

  • Connect to SSE endpoint /auth/v1/subscribe
  • If background browser notifications are required, also register the root service worker and subscribe through /auth/v1/notifications/*
  • Store max tick in localStorage
  • Reconnect with since parameter on disconnect
  • Handle different event types by module and type

For Integration Partners

  • Register app with webhook URL
  • Implement webhook endpoint
  • Verify webhook signatures
  • Handle idempotency (events may be delivered multiple times)

See Also