- Add src/multitenancy/ with AES-256-GCM credential store, WhatsApp webhook router (phone_number_id -> customerId), and per-customer audit log (90-day Redis TTL) - Add src/billing/ with plan definitions and meterMiddleware that resolves API key -> Customer object with getCredential() closure - Refactor all src/clients/* to accept optional customer param, falling back to env vars for backward compat with single-user mode - Thread customer through handleToolCall(name, args, customer?) - Add customers table to MySQL schema initDatabase() - Add /webhook/whatsapp (immediate 200 + async routing) and /api/connect/* onboarding endpoints to index.ts - Add Redis 7 to docker-compose.yml; add REDIS_URL and CREDENTIAL_ENCRYPTION_KEY to hermes-k8s.yaml - Add product/incubation/ with architecture write-up and PlantUML diagrams (system architecture + 5 user flows) - Extend OpenAPI spec in manifest.ts with all platform endpoints Verification: 3 isolation tests (credential, webhook routing, audit log) passed against live Redis. Deployed to hermes.squaremcp.com. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
160 lines
4.3 KiB
Plaintext
160 lines
4.3 KiB
Plaintext
@startuml hermes-mcp-architecture
|
|
|
|
skinparam backgroundColor #1a1a2e
|
|
skinparam defaultFontColor #e0e0e0
|
|
skinparam defaultFontSize 13
|
|
skinparam arrowColor #888888
|
|
skinparam roundCorner 8
|
|
skinparam shadowing false
|
|
|
|
skinparam component {
|
|
BackgroundColor #16213e
|
|
BorderColor #0f3460
|
|
FontColor #e0e0e0
|
|
ArrowColor #888888
|
|
}
|
|
skinparam package {
|
|
BackgroundColor #0d1b2a
|
|
BorderColor #2a4a6a
|
|
FontColor #aaaaaa
|
|
FontStyle bold
|
|
}
|
|
skinparam database {
|
|
BackgroundColor #0f2040
|
|
BorderColor #533483
|
|
FontColor #e0e0e0
|
|
}
|
|
skinparam cloud {
|
|
BackgroundColor #1a0d2e
|
|
BorderColor #e94560
|
|
FontColor #e0e0e0
|
|
}
|
|
skinparam note {
|
|
BackgroundColor #0d1b2a
|
|
BorderColor #2a4a6a
|
|
FontColor #aaaaaa
|
|
}
|
|
|
|
title hermes-mcp -- System Architecture (2026-05-08)
|
|
|
|
' ── AI Clients ────────────────────────────────────────────────────
|
|
package "AI Clients" {
|
|
[Claude.ai\nMCP connector] as claude
|
|
[ChatGPT\ncustom GPT] as chatgpt
|
|
[opencode / Codex] as opencode
|
|
}
|
|
|
|
' ── hermes-mcp server ─────────────────────────────────────────────
|
|
package "hermes-mcp | Node.js / TypeScript | hermes.squaremcp.com" {
|
|
|
|
package "Transports" {
|
|
[Streamable HTTP\n/mcp] as mcp_t
|
|
[SSE legacy\n/sse] as sse_t
|
|
[REST API\n/api/*] as rest_t
|
|
[Webhook\n/webhook/whatsapp] as wh_t
|
|
}
|
|
|
|
package "Auth" {
|
|
[requireAuth\nMCP_API_KEY + OAuth Bearer] as req_auth
|
|
[meterMiddleware\nAPI key -> Customer] as meter
|
|
[OAuth 2.0\n/oauth/*] as oauth
|
|
}
|
|
|
|
package "Core" {
|
|
[handleToolCall\nname, args, customer?] as dispatch
|
|
}
|
|
|
|
package "Platform Clients src/clients/*" {
|
|
[whatsapp.ts] as c_wa
|
|
[linkedin.ts] as c_li
|
|
[telegram.ts] as c_tg
|
|
[discord.ts] as c_dc
|
|
[instagram.ts] as c_ig
|
|
[twitter.ts] as c_tw
|
|
[obsidian.ts] as c_ob
|
|
}
|
|
|
|
package "Multi-tenancy src/multitenancy/*" {
|
|
[credential-store\nAES-256-GCM] as cred_store
|
|
[webhook-router\nphone_id -> customerId] as wh_router
|
|
[audit-log\n90-day per-customer trail] as audit_log
|
|
}
|
|
|
|
package "Billing src/billing/*" {
|
|
[middleware.ts\nCustomer + meterMiddleware] as billing
|
|
[plans.ts\nfree/starter/growth/enterprise] as plans
|
|
}
|
|
}
|
|
|
|
' ── Storage ───────────────────────────────────────────────────────
|
|
database "Redis 7" as redis
|
|
note right of redis
|
|
creds:{cid}:{platform} (AES-256-GCM encrypted)
|
|
wa_phone_id:{phoneId} (-> customerId)
|
|
customer:apikey:{key} (60s TTL cache)
|
|
logs:{cid}:{date}:{seq} (90-day audit trail)
|
|
end note
|
|
|
|
database "MySQL 8\nhermes_oauth" as mysql
|
|
note right of mysql
|
|
customers (id, api_key, plan, active, email)
|
|
oauth_clients / oauth_auth_codes / oauth_tokens
|
|
end note
|
|
|
|
' ── Platform APIs ─────────────────────────────────────────────────
|
|
cloud "External Platform APIs" {
|
|
[Meta Graph API\nWhatsApp + Instagram] as meta_api
|
|
[LinkedIn API v2] as li_api
|
|
[Telegram Bot API] as tg_api
|
|
[Discord API v10] as dc_api
|
|
[Twitter API v2] as tw_api
|
|
[Obsidian Vault\nfilesystem] as ob_vault
|
|
}
|
|
|
|
' ── Connections ───────────────────────────────────────────────────
|
|
claude --> mcp_t : MCP / Bearer
|
|
chatgpt --> mcp_t : MCP / Bearer
|
|
opencode --> rest_t : REST / x-api-key
|
|
|
|
mcp_t --> req_auth
|
|
sse_t --> req_auth
|
|
rest_t --> req_auth
|
|
rest_t --> meter : /api/connect/*
|
|
wh_t --> wh_router
|
|
|
|
req_auth --> dispatch
|
|
meter --> billing : resolve Customer
|
|
billing --> mysql : SELECT customers
|
|
billing --> redis : customer cache
|
|
|
|
dispatch --> c_wa
|
|
dispatch --> c_li
|
|
dispatch --> c_tg
|
|
dispatch --> c_dc
|
|
dispatch --> c_ig
|
|
dispatch --> c_tw
|
|
dispatch --> c_ob
|
|
|
|
c_wa --> cred_store : getCredential
|
|
c_li --> cred_store : getCredential
|
|
c_tg --> cred_store : getCredential
|
|
c_dc --> cred_store : getCredential
|
|
c_ig --> cred_store : getCredential
|
|
c_tw --> cred_store : getCredential
|
|
|
|
cred_store --> redis
|
|
wh_router --> redis
|
|
audit_log --> redis
|
|
|
|
c_wa --> meta_api
|
|
c_ig --> meta_api
|
|
c_li --> li_api
|
|
c_tg --> tg_api
|
|
c_dc --> dc_api
|
|
c_tw --> tw_api
|
|
c_ob --> ob_vault
|
|
|
|
oauth --> mysql
|
|
|
|
@enduml
|