Steps 0–10 of the v2 plan, 194 tests passing. Core infrastructure - Shared Redis client (src/redis.ts); all four Redis consumers migrated - Vitest test harness with vitest.config.ts and npm test/test:watch scripts Billing & invoicing (Steps 1–2) - Monthly invoice generation with idempotency (MySQL uq_customer_period unique key) - Cron job with Redis distributed lock (Lua compare-delete, 1-hr TTL) - Invoice emailer via nodemailer (FETCHERPAY SMTP) - Billing middleware: checkLimit gate in handleToolCall; platform attribution fix Email multi-tenancy (Step 3) - EmailCtx = Account | EmailCredentials; imap.ts + smtp.ts accept both - resolveEmailCtx helper in tools.ts; all email tools use customer credentials Analytics + platform health (Steps 4–5) - Chart.js bar charts for platform breakdown and daily activity - Token expiry check in getCredential with dynamic import refresh - platform-health.ts: per-platform health probe with 10-min Redis cache - GET /api/health/platforms; "Token expired" amber badge in dashboard Tool schema filtering (Step 6) - stripAccountParam deep-clones tool schemas; multi-tenant sessions never see the internal account enum OAuth hardening (Step 7) - Atomic auth code consumption: UPDATE SET used=TRUE, check affectedRows - customer_id threaded through oauth_auth_codes → oauth_tokens - getTokenCustomer(); requireAuth resolves req.customer from Bearer token - Consent page requires authenticated session; redirect_uri validated against registered URIs; http://localhost:* loopback wildcard DCR browser flow (Step 8) - ensureOAuthAppRegistered() upserts pre-registered SquareMCP OAuth app on startup with redirect URIs for mcp-callback, localhost:*, claude-desktop, opencode - GET /oauth/connect-mcp → server-side redirect (client_id off frontend) - GET /oauth/mcp-callback → exchanges code, renders config snippet page with copy buttons for Claude Desktop and Codex CLI Webhooks (Step 9) - webhook_url + webhook_secret columns on customers - deliverWebhook(): HMAC-SHA256 signing, 3× exponential retry (1s/4s/16s), Redis DLQ with 7-day TTL on total failure - isValidWebhookUrl(): SSRF protection (blocks RFC-1918, localhost, .local) - POST /api/webhooks/config (secret returned once), GET, DELETE - GET /api/admin/webhooks/dlq/:customerId - WhatsApp POST route uses express.raw() for raw body preservation - Dashboard Webhooks tab with secret-once display and copy button Developer docs (Step 10) - docs/ static HTML site (GitHub Pages, no build pipeline) - index.html: landing page with client + platform overview - getting-started.html: tabbed MCP config for Claude Desktop, Codex CLI, opencode - platforms.html: LinkedIn, TikTok, WhatsApp, Instagram, Twitter, Telegram guides - agent-tutorial.html: complete Node.js agent (Anthropic SDK + MCP SDK), LinkedIn posting loop, extensions for multi-platform + inbound webhook reaction Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Hermes MCP
Hermes MCP is a hosted MCP gateway for messaging, knowledge, and social connectors.
The production endpoint is:
https://hermes.squaremcp.com/mcp
Hermes currently supports MCP access patterns for:
- Obsidian vault notes
- WhatsApp Business
- Telegram
- additional social connectors that are in various states of credentialing and rollout
What Hermes is for
Hermes is the integration and connector layer behind broader product work such as SquareMCP.
Use Hermes when you want:
- an MCP endpoint that exposes real tools over Streamable HTTP
- API-key or OAuth-protected access
- connector access from agent clients such as Codex CLI, Claude Code, opencode, or ChatGPT
Core transports
| Transport | URL |
|---|---|
| Streamable HTTP (preferred) | https://hermes.squaremcp.com/mcp |
| Legacy SSE | https://hermes.squaremcp.com/sse |
Authentication
Hermes accepts:
x-api-keyheader?key=query parameterAuthorization: Bearer ...for OAuth-based clients
For local/manual config examples in this repo, always substitute your own value for:
YOUR_MCP_API_KEY
Do not commit live API keys into repo config files.
Client setup guides
Use the setup guide that matches your client:
- Codex CLI setup
- CLI agent setup (Claude Code, generic MCP CLIs, Claude Desktop)
- opencode setup
- ChatGPT Custom GPT setup
- Social publishing setup (TikTok / Facebook)
Codex quick setup
Add this block to ~/.codex/config.toml:
[mcp_servers.hermes]
url = "https://hermes.squaremcp.com/mcp"
See CODEX_SETUP.md for the full notes and caveats.
opencode quick setup
Project-level opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"hermes": {
"type": "remote",
"url": "https://hermes.squaremcp.com/mcp",
"headers": {
"x-api-key": "YOUR_MCP_API_KEY"
}
}
}
}
Full instructions: OPENCODE.md
Local development
npm install
cp .env.example .env
npm run dev
curl http://localhost:3456/health
The local server runs on port 3456 by default.
Deployment
Production deployment notes are in:
- DEPLOY.md
hermes-k8s.yaml
SquareMCP product-site docs live under:
product/siteproduct/README.mdvideos/remotion-demofor SquareMCP video production assets and render workflows
Notes
The historical docs in this repo started from an email-only Claude-focused setup. Current deployment and setup guidance should follow:
- the
hermes.squaremcp.comdomain - Streamable HTTP
/mcpas the default transport - the dedicated client setup docs linked above