feat: ChatGPT Custom GPT support in chat bot + sqcp SMTP routing fix

- 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>
This commit is contained in:
Garfield
2026-05-15 18:53:42 -04:00
parent 1f8d97b6bd
commit 18b838c268
5 changed files with 63 additions and 11 deletions

View File

@@ -22,7 +22,7 @@ spec:
fsGroup: 1000 fsGroup: 1000
containers: containers:
- name: hermes-mcp - name: hermes-mcp
image: localhost:32000/hermes-mcp@sha256:17f1f7ce059f0f87d9c34c39e2ea0fb1f25cf72f9279341c5912e6c35690f43a image: localhost:32000/hermes-mcp@sha256:54488f625b5a065f3cfb30d9d0afe269dac65aadd8206652d27da034daf1dee4
imagePullPolicy: Always imagePullPolicy: Always
securityContext: securityContext:
allowPrivilegeEscalation: false allowPrivilegeEscalation: false

View File

@@ -15,7 +15,8 @@
"test:product-site:cleanup": "node product/site/cleanup-test-submissions.mjs", "test:product-site:cleanup": "node product/site/cleanup-test-submissions.mjs",
"deploy:product-site:verify": "bash product/site/deploy-and-verify.sh", "deploy:product-site:verify": "bash product/site/deploy-and-verify.sh",
"test": "vitest run", "test": "vitest run",
"test:watch": "vitest" "test:watch": "vitest",
"postinstall": "node scripts/patch-imapflow.cjs"
}, },
"dependencies": { "dependencies": {
"@anthropic-ai/sdk": "^0.96.0", "@anthropic-ai/sdk": "^0.96.0",

View File

@@ -10,16 +10,54 @@ You have real tools connected to live platforms. When a visitor asks "can it sen
What SquareMCP does: What SquareMCP does:
- Connects AI coding assistants to social platforms: LinkedIn, TikTok, WhatsApp, Instagram, Twitter/X, Facebook, Telegram, Discord, Slack, and Email - Connects AI coding assistants to social platforms: LinkedIn, TikTok, WhatsApp, Instagram, Twitter/X, Facebook, Telegram, Discord, Slack, and Email
- Works with any MCP-compatible client: Claude Desktop, Claude Code, Cursor, Windsurf, opencode, Codex CLI - Works with any MCP-compatible client: Claude Desktop, Claude Code, Cursor, Windsurf, opencode, Codex CLI
- Also works with ChatGPT via Custom GPT (uses the REST API + OAuth, not MCP protocol directly)
- Provides a multi-tenant SaaS platform where each customer securely stores their own platform credentials - Provides a multi-tenant SaaS platform where each customer securely stores their own platform credentials
- Plans: Free (100 calls/month), Pro, Business - Plans: Free (100 calls/month), Pro, Business
How to connect — by AI client:
CHATGPT (chatgpt.com):
SquareMCP works with ChatGPT via a Custom GPT with Actions. Steps:
1. Go to chatgpt.com → Explore GPTs → Create → Actions → Import from URL
2. Import the OpenAPI schema: https://hermes.squaremcp.com/openapi.json
3. Set Authentication to OAuth:
- Authorization URL: https://hermes.squaremcp.com/oauth/authorize
- Token URL: https://hermes.squaremcp.com/oauth/token
- Register your OAuth client first at: https://hermes.squaremcp.com/oauth/register
4. Connect your social accounts in the SquareMCP dashboard at https://app.squaremcp.com
5. Ask your Custom GPT: "Send a WhatsApp to my top 3 clients" — it just works.
Full guide: email support@squaremcp.com for the ChatGPT setup walkthrough.
CLAUDE (claude.ai or Claude Desktop):
1. In claude.ai → Settings → Integrations → Add MCP server
2. Server URL: https://hermes.squaremcp.com/mcp
3. Authenticate via OAuth
4. Connect social accounts at https://app.squaremcp.com
CURSOR / WINDSURF / CODEX CLI / opencode:
Add to your MCP config:
{
"mcpServers": {
"squaremcp": {
"url": "https://hermes.squaremcp.com/mcp",
"apiKey": "your-api-key-from-dashboard"
}
}
}
For mortgage brokers specifically:
- ChatGPT Custom GPT is often the easiest starting point — no install required, works in the browser
- WhatsApp rate blast: one command sends updates to hundreds of clients
- Multi-channel: handle WhatsApp, email, LinkedIn, and Facebook from a single AI conversation
- Compliance: we can scope the setup to stay within RESPA/TILA guidelines
When using tools: When using tools:
- For demo sends (Slack, Telegram, Discord), send a short, friendly message that explains this is a live SquareMCP demo - For demo sends (Slack, Telegram, Discord), send a short, friendly message that explains this is a live SquareMCP demo
- After a tool succeeds, explain what just happened and how easy it was - After a tool succeeds, explain what just happened and how easy it was
- If a tool fails (missing credentials), explain what credential the customer would set up instead - If a tool fails (missing credentials), explain what credential the customer would set up instead
- Never expose tokens or internal IDs in your reply - Never expose tokens or internal IDs in your reply
Keep replies concise. If you don't know something, say so and suggest emailing support@squaremcp.com.`; Keep replies concise and practical. If you don't know something, say so and suggest emailing support@squaremcp.com.`;
// Tools the public demo agent is allowed to use (no customer auth needed — uses env var creds) // Tools the public demo agent is allowed to use (no customer auth needed — uses env var creds)
const DEMO_TOOL_NAMES = new Set([ const DEMO_TOOL_NAMES = new Set([

View File

@@ -5,6 +5,9 @@ import type { EmailCredentials } from './multitenancy/credential-store.js';
const FETCHERPAY_SMTP_HOST = process.env['FETCHERPAY_SMTP_HOST'] ?? 'mail.fetcherpay.com'; const FETCHERPAY_SMTP_HOST = process.env['FETCHERPAY_SMTP_HOST'] ?? 'mail.fetcherpay.com';
const FETCHERPAY_SMTP_PORT = parseInt(process.env['FETCHERPAY_SMTP_PORT'] ?? '30587'); const FETCHERPAY_SMTP_PORT = parseInt(process.env['FETCHERPAY_SMTP_PORT'] ?? '30587');
const SQCP_SMTP_HOST = process.env['SQCP_SMTP_HOST'] ?? 'mail.squaremcp.com';
const SQCP_SMTP_PORT = parseInt(process.env['SQCP_SMTP_PORT'] ?? '30587');
function fetcherpaySmtpTransport(user: string, pass: string) { function fetcherpaySmtpTransport(user: string, pass: string) {
return nodemailer.createTransport({ return nodemailer.createTransport({
host: FETCHERPAY_SMTP_HOST, host: FETCHERPAY_SMTP_HOST,
@@ -15,6 +18,16 @@ function fetcherpaySmtpTransport(user: string, pass: string) {
}); });
} }
function sqcpSmtpTransport(user: string, pass: string) {
return nodemailer.createTransport({
host: SQCP_SMTP_HOST,
port: SQCP_SMTP_PORT,
secure: false,
auth: { user, pass },
tls: { rejectUnauthorized: false },
});
}
function getEnvSmtpTransport(account: Account = 'yahoo') { function getEnvSmtpTransport(account: Account = 'yahoo') {
switch (account) { switch (account) {
case 'fetcherpay': case 'fetcherpay':
@@ -28,19 +41,19 @@ function getEnvSmtpTransport(account: Account = 'yahoo') {
case 'founder': case 'founder':
return fetcherpaySmtpTransport(process.env['FOUNDER_EMAIL']!, process.env['FOUNDER_PASSWORD']!); return fetcherpaySmtpTransport(process.env['FOUNDER_EMAIL']!, process.env['FOUNDER_PASSWORD']!);
case 'sqcp_garfield': case 'sqcp_garfield':
return fetcherpaySmtpTransport(process.env['SQCP_GARFIELD_EMAIL']!, process.env['SQCP_GARFIELD_PASSWORD']!); return sqcpSmtpTransport(process.env['SQCP_GARFIELD_EMAIL']!, process.env['SQCP_GARFIELD_PASSWORD']!);
case 'sqcp_info': case 'sqcp_info':
return fetcherpaySmtpTransport(process.env['SQCP_INFO_EMAIL']!, process.env['SQCP_INFO_PASSWORD']!); return sqcpSmtpTransport(process.env['SQCP_INFO_EMAIL']!, process.env['SQCP_INFO_PASSWORD']!);
case 'sqcp_sales': case 'sqcp_sales':
return fetcherpaySmtpTransport(process.env['SQCP_SALES_EMAIL']!, process.env['SQCP_SALES_PASSWORD']!); return sqcpSmtpTransport(process.env['SQCP_SALES_EMAIL']!, process.env['SQCP_SALES_PASSWORD']!);
case 'sqcp_support': case 'sqcp_support':
return fetcherpaySmtpTransport(process.env['SQCP_SUPPORT_EMAIL']!, process.env['SQCP_SUPPORT_PASSWORD']!); return sqcpSmtpTransport(process.env['SQCP_SUPPORT_EMAIL']!, process.env['SQCP_SUPPORT_PASSWORD']!);
case 'sqcp_founder': case 'sqcp_founder':
return fetcherpaySmtpTransport(process.env['SQCP_FOUNDER_EMAIL']!, process.env['SQCP_FOUNDER_PASSWORD']!); return sqcpSmtpTransport(process.env['SQCP_FOUNDER_EMAIL']!, process.env['SQCP_FOUNDER_PASSWORD']!);
case 'sqcp_contact': case 'sqcp_contact':
return fetcherpaySmtpTransport(process.env['SQCP_CONTACT_EMAIL']!, process.env['SQCP_CONTACT_PASSWORD']!); return sqcpSmtpTransport(process.env['SQCP_CONTACT_EMAIL']!, process.env['SQCP_CONTACT_PASSWORD']!);
case 'sqcp_admin': case 'sqcp_admin':
return fetcherpaySmtpTransport(process.env['SQCP_ADMIN_EMAIL']!, process.env['SQCP_ADMIN_PASSWORD']!); return sqcpSmtpTransport(process.env['SQCP_ADMIN_EMAIL']!, process.env['SQCP_ADMIN_PASSWORD']!);
case 'gmail': case 'gmail':
return nodemailer.createTransport({ return nodemailer.createTransport({
host: 'smtp.gmail.com', host: 'smtp.gmail.com',

View File

@@ -20,7 +20,7 @@ const ACCOUNT_PARAM = {
account: { account: {
type: 'string', type: 'string',
enum: ['yahoo', 'fetcherpay', 'garfield', 'sales', 'leads', 'founder', 'gmail', 'sqcp_garfield', 'sqcp_info', 'sqcp_sales', 'sqcp_support', 'sqcp_founder', 'sqcp_contact', 'sqcp_admin'], enum: ['yahoo', 'fetcherpay', 'garfield', 'sales', 'leads', 'founder', 'gmail', 'sqcp_garfield', 'sqcp_info', 'sqcp_sales', 'sqcp_support', 'sqcp_founder', 'sqcp_contact', 'sqcp_admin'],
description: 'Which mailbox to use: "yahoo" (gheron01@yahoo.com), "fetcherpay" (garfield.heron@fetcherpay.com), "garfield" (garfield@fetcherpay.com), "sales" (sales@fetcherpay.com), "leads" (leads@fetcherpay.com), "founder" (founder@fetcherpay.com), or "gmail" (Gmail account). Defaults to "yahoo".', description: 'Which mailbox to use: "yahoo" (gheron01@yahoo.com), "fetcherpay" (garfield.heron@fetcherpay.com), "garfield" (garfield@fetcherpay.com), "sales" (sales@fetcherpay.com), "leads" (leads@fetcherpay.com), "founder" (founder@fetcherpay.com), "gmail" (garfield.heron@gmail.com), "sqcp_garfield" (garfield@squaremcp.com), "sqcp_info" (info@squaremcp.com), "sqcp_sales" (sales@squaremcp.com), "sqcp_support" (support@squaremcp.com), "sqcp_founder" (founder@squaremcp.com), "sqcp_contact" (contact@squaremcp.com), "sqcp_admin" (admin@squaremcp.com). Defaults to "yahoo".',
}, },
}; };