- product/site/squaremcp-broker-demo.mp4 — 45s mortgage broker demo video
served at squaremcp.com/squaremcp-broker-demo.mp4, sent to Ferrari Lending
- .gitignore: add .runner (Gitea Actions runner token, should not be committed)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces direct Poste.io SMTP (mail.squaremcp.com:30587, port 25 blocked)
with Azure Communication Services relay (smtp.azurecomm.net:587).
All sqcp_* accounts share a single ACS credential; FROM addresses unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- CRITICAL: forgot-password no longer returns token in response; sends email via info@squaremcp.com instead
- Rate limit: login 10/15min, forgot-password 5/hr, chat 30/hr (Redis, per IP)
- express.json() capped at 100kb
- WhatsApp webhook HMAC verification (activates when WHATSAPP_APP_SECRET is set)
- JWT_SECRET now explicitly set in K8s (was falling back to CREDENTIAL_ENCRYPTION_KEY)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Customers who haven't connected WhatsApp in the dashboard now
automatically use the SquareMCP default number (+19547385805 via Twilio)
instead of throwing 'WhatsApp not connected'. Routing flag usingDefault
replaces the !customer check so OAuth sessions get the same Twilio path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ChatGPT regenerates its GPT ID (and callback URL) every time the GPT
is saved, making exact redirect_uri matching impossible. Added support
for the registered URI pattern https://chat.openai.com/aip/*/oauth/callback
which matches any valid ChatGPT GPT callback via regex.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Drops obsidian (5 ops) and whatsapp/templates list (1 op) to stay
under ChatGPT's 30-operation cap. Served at /openapi-chatgpt.json.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The SquareMCP number (+19547385805) is registered under Twilio's BSP,
so direct Meta API sends were blocked with #200 permission errors.
Default account now routes through Twilio's REST API; customer-owned
accounts still use Meta's Cloud API directly.
- twilioSend(): POST to api.twilio.com with Basic auth
- resolveTemplateText(): fetches template body from Meta, substitutes
{{1}}/{{}} parameters, so templates render correctly via Twilio
- Bumped WHATSAPP_API_VERSION to v21.0
- Added TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_WHATSAPP_NUMBER,
WHATSAPP_DEFAULT_BUSINESS_ACCOUNT_ID to K8s deployment
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
WHATSAPP_DEFAULT_PHONE_NUMBER_ID, WHATSAPP_DEFAULT_ACCESS_TOKEN,
and WA_VERIFY_TOKEN (hermes-wa-2026) added to K8s deployment.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
POST /webhook/twilio/voice returns TwiML that says the number doesn't
accept voice calls and hangs up — needed for Twilio number config.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- notifications/slack.ts: added sendChatEscalationAlert (fires when visitor
asks about pricing, demo, help, or a human) and sendSupportEmailAlert
- email-poller.ts: polls support@squaremcp.com every 5 min via IMAP,
deduplicates with Redis (support📧alerted_uids), fires Slack alert
for each new unseen message
- index.ts: detectEscalation() scans last user message for trigger phrases;
chat endpoint fires alert fire-and-forget after responding; startEmailPoller()
called on server boot
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- chat.ts: system prompt now includes step-by-step ChatGPT Custom GPT
setup (openapi.json import + OAuth), Claude/Cursor/Windsurf config,
and mortgage broker guidance — bot no longer incorrectly says ChatGPT
is unsupported
- smtp.ts: all sqcp_* accounts now route to mail.squaremcp.com (SQCP_SMTP_HOST)
instead of the fetcherpay server
- tools.ts: ACCOUNT_PARAM description now lists all 14 mailboxes including
the 7 squaremcp.com accounts so Claude picks the right one without guessing
- package.json: postinstall hook runs imapflow patch script after npm install
- hermes-k8s.yaml: updated image digest to current production build
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move client.connect() inside try/catch in withClient
- Add logImapError() writing full stack to /vaults/imap-errors.log for diagnosis
- Extend patch-imapflow.cjs to guard this.remainder.trim() in parser-instance.js
- Root cause of reported crash was undefined args.q (callers passing 'query' not 'q')
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New accounts: sqcp_garfield, sqcp_info, sqcp_sales, sqcp_support,
sqcp_founder, sqcp_contact, sqcp_admin
- All use same poste.io mail server as fetcherpay.com (IMAP 30993, SMTP 30587)
- Password: onelove for all accounts
- Updated: imap.ts, smtp.ts, tools.ts, manifest.ts, hermes-k8s.yaml
Chat widget now runs a live tool-use loop via Claude Haiku. Exposes
slack, discord, and telegram demo tools — bot can actually send messages
and read channels to prove the platform works in real time. Widget shows
a purple pill with tool names when the agent calls a live platform.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add Slack as customer-facing messaging platform (client, 4 MCP tools, dashboard card)
- Add /api/chat endpoint powered by Claude Haiku with SquareMCP system prompt
- Add embeddable chat-widget.js injected into all 3 sites (docs, app, www)
- Add ANTHROPIC_API_KEY, serve product/ as static files
- Update Platform type to include slack
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
16s landscape (1920x1080): shows SquareMCP chat prompt triggering an
animated cURL call to the Business Management API creating a message
template (HEADER/BODY/FOOTER components with variables), then the right
panel renders a WhatsApp phone UI previewing the template bubble with
variable placeholders highlighted and a PENDING status badge.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
15s landscape (1920x1080) split-screen: left shows SquareMCP chat
prompt + animated cURL command + 200 response with wamid; right shows
a rendered WhatsApp phone UI with the message bubble appearing and blue
double-checkmarks. Also adds transparent-background logo PNG for Meta
Tech Provider icon upload.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add src/notifications/slack.ts — Slack webhook integration with rich blocks
- Add src/notifications/index.ts — dispatcher with test-submission filtering
- Wire notifyNewPilotRequest() into POST /api/pilot-request (fire-and-forget)
- Filter out test submissions (@example.com, E2E, Smoke Test, QA Test, Browser Test)
- Skip alert gracefully when SLACK_PILOT_WEBHOOK_URL is not set
- Update .gitignore to exclude .playwright-mcp/ artifacts
Runs on every push to main and every PR:
1. npm ci — install deps
2. npm run build — TypeScript type check
3. npm test — vitest run (216 tests, all mocked, no DB/Redis needed)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Guards the browser OAuth popup flow used by claude.ai and ChatGPT:
- GET /login: return_to URL validation, XSS escaping, error display
- POST /login: first-party cookie properties (httpOnly/secure/lax/domain),
open redirect blocking, credential rejection paths
- GET /oauth/authorize: must redirect to /login (never app.squaremcp.com),
return_to encoding, valid session bypasses redirect
Also exports `app` from index.ts and guards main() with NODE_ENV !== 'test'
so the Express app can be imported by supertest without triggering DB init.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add GET/POST /login to hermes for first-party cookie during OAuth popup
(fixes browser CHIPS cookie partitioning that broke claude.ai connection)
- Add role column to all findCustomer* SQL queries in src/auth.ts
- Add claude.ai tab to docs/getting-started.html with OAuth flow steps
- Add ARCHITECTURE.md with system diagrams, data flow, and key invariants
- Rewrite README.md and DEPLOY.md to reflect actual MicroK8s deployment
- Deploy updated docs site (squaremcp-docs sha256 updated)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add YC_APPLICATION_ANSWERS.md with full Summer 2026 application draft
(all fields answered, updated with mortgage broker user interview quote)
- Wire OffthreadVideo into YCAppVideo.tsx for founder recording playback
- Ignore .mov files and .gstack/ in .gitignore
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add YCAppVideo Remotion composition (1920x1080, 60s)
- 3s intro card with founder name + company
- 55s video placeholder with branded frame + lower thirds
- 2s outro card with logo + tagline
- Update Root.tsx with new composition
- Add YC_APPLICATION_TALKING_POINTS.md with bullet points
and recording tips per YC instructions
- Add /public static route to serve files from /vaults/public
- Fix LinkedIn API version: 202501 → 202603 (active version)
- OpenAPI schema already included POST /api/linkedin/video
- Successfully posted Remotion video to LinkedIn
Implements full 4-step LinkedIn Videos API flow: download from public URL,
initialize upload, 4MB chunk PUT with ETag collection, finalize, poll until
AVAILABLE, then publish via POST /rest/posts reading post ID from x-restli-id.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
TikTok: getUserProfile, getUserVideos, createVideo (PULL_FROM_URL),
getVideoStatus via Content Posting API v2. Full multi-tenant credential
isolation and audit logging on write operations.
Snapchat: getMe (Login Kit), getAdAccounts (Marketing API). createSnap
throws with a clear explanation that Creative Kit is mobile-only — no
server-side posting API exists.
Platform type, validPlatforms list, and /api/connections endpoint all
updated to include tiktok and snapchat. Architecture diagram updated.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>