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
| Channel | Use Case | Client | Cursor |
|---|---|---|---|
| SSE | Real-time UI updates | PWA Frontend | Single global TimeTick |
| Web Push | Background browser delivery | Service worker on the same origin | Reuses normalized module events |
| Webhooks | Backend integrations | External systems | Per-app cursor |
| MCP | AI agent actions | Claude 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:
- First connection: No
sinceparameter - Store the max
tickfrom received events in localStorage - 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.json 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/eventsoutput reaching AuthProxyEventPoller - 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)
| Type | Description | Data |
|---|---|---|
TxInWallet | New transaction | TxEventOut |
TxStateChanged | Transaction state updated | TxEventOut |
BalanceChanged | Balance updated | Balance info |
Chat Events (Chat)
| Type | Description | Data |
|---|---|---|
NewChatMessage | New message | ChatEventOut |
MessageRead | Message read status | Message IDs |
ChatCreated | New chat created | Chat 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
| Tool | Description | Module |
|---|---|---|
wallet_balance | Get wallet balance | TrexWallet |
wallet_transactions | List transactions | TrexWallet |
wallet_send | Send funds | TrexWallet |
chat_messages | Get chat messages | Chat |
chat_send | Send message | Chat |
user_info | Get user profile | CRM |
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:
- Session - For user-context operations
- 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
| Parameter | Description |
|---|---|
since | Cursor (timetick_update) — fetch events after this. |
subjects | Comma-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. |
users | Legacy alias for user: subjects (still accepted). |
apps | Legacy alias for app: subjects (still accepted). |
limit | Max 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/eventsendpoint - Return
EventBatchwith properTickUpdatecursor - Include typed
Data(e.g.,TxEventOut,ChatEventOut) - Support
usersfilter for SSE delivery - Support
appsfilter 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
tickin localStorage - Reconnect with
sinceparameter on disconnect - Handle different event types by
moduleandtype
For Integration Partners
- Register app with webhook URL
- Implement webhook endpoint
- Verify webhook signatures
- Handle idempotency (events may be delivered multiple times)
See Also
- Platform Overview - Architecture overview
- AuthProxy Documentation - Detailed SSE docs
- TrexWallet Documentation - Wallet events