diff --git a/hermes-k8s.yaml b/hermes-k8s.yaml new file mode 100644 index 0000000..10eb7d0 --- /dev/null +++ b/hermes-k8s.yaml @@ -0,0 +1,188 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: hermes-mcp + namespace: fetcherpay +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + app: hermes-mcp + template: + metadata: + labels: + app: hermes-mcp + spec: + hostNetwork: true + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + containers: + - name: hermes-mcp + image: localhost:32000/hermes-mcp@sha256:e169dccdb2a4e670036391658c5718a2244b3e16b7ffb1f71946a9aae10ba151 + imagePullPolicy: Always + securityContext: + allowPrivilegeEscalation: false + ports: + - containerPort: 3456 + env: + - name: PORT + value: "3456" + - name: SERVER_URL + value: "https://hermes.squaremcp.com" + - name: MCP_API_KEY + value: "114521f3f9e6858480d6269446a446ef" + - name: YAHOO_EMAIL + value: "gheron01@yahoo.com" + - name: YAHOO_APP_PASSWORD + value: "lzlleytmslxocxae" + - name: FETCHERPAY_EMAIL + value: "garfield.heron@fetcherpay.com" + - name: FETCHERPAY_PASSWORD + value: "onelove" + - name: FETCHERPAY_IMAP_HOST + value: "23.120.207.35" + - name: FETCHERPAY_IMAP_PORT + value: "30993" + - name: FETCHERPAY_SMTP_HOST + value: "23.120.207.35" + - name: FETCHERPAY_SMTP_PORT + value: "30587" + - name: GARFIELD_EMAIL + value: "garfield@fetcherpay.com" + - name: GARFIELD_PASSWORD + value: "onelove" + - name: SALES_EMAIL + value: "sales@fetcherpay.com" + - name: SALES_PASSWORD + value: "onelove" + - name: LEADS_EMAIL + value: "leads@fetcherpay.com" + - name: LEADS_PASSWORD + value: "onelove" + - name: FOUNDER_EMAIL + value: "founder@fetcherpay.com" + - name: FOUNDER_PASSWORD + value: "onelove" + - name: OBSIDIAN_VAULT_PATH + value: "/vaults" + - name: SYNCTHING_URL + value: "http://10.1.58.192:8384" + - name: SYNCTHING_API_KEY + value: "PRWss5jFKX7VaHRr5LcJnbJHyFWuWuMH" + - name: SYNCTHING_FOLDER_ID + value: "obsidian-vault" + - name: GMAIL_EMAIL + value: "garfield.heron@gmail.com" + - name: GMAIL_APP_PASSWORD + value: "ldmk duee movy hruy" + - name: SQCP_GARFIELD_EMAIL + value: "garfield@squaremcp.com" + - name: SQCP_GARFIELD_PASSWORD + value: "onelove" + - name: SQCP_INFO_EMAIL + value: "info@squaremcp.com" + - name: SQCP_INFO_PASSWORD + value: "onelove" + - name: SQCP_SALES_EMAIL + value: "sales@squaremcp.com" + - name: SQCP_SALES_PASSWORD + value: "onelove" + - name: SQCP_SUPPORT_EMAIL + value: "support@squaremcp.com" + - name: SQCP_SUPPORT_PASSWORD + value: "onelove" + - name: SQCP_FOUNDER_EMAIL + value: "founder@squaremcp.com" + - name: SQCP_FOUNDER_PASSWORD + value: "onelove" + - name: SQCP_CONTACT_EMAIL + value: "contact@squaremcp.com" + - name: SQCP_CONTACT_PASSWORD + value: "onelove" + - name: SQCP_ADMIN_EMAIL + value: "admin@squaremcp.com" + - name: SQCP_ADMIN_PASSWORD + value: "onelove" + - name: MYSQL_HOST + value: "127.0.0.1" + - name: MYSQL_PORT + value: "3306" + - name: MYSQL_USER + value: "root" + - name: MYSQL_PASSWORD + value: "fetcherpay" + - name: REDIS_URL + value: "redis://127.0.0.1:6379" + - name: CREDENTIAL_ENCRYPTION_KEY + value: "4ef9c48e9f4e5dfa843d4bfcc3a8f69c5ad5738326c8b0e878076853ae4b8416" + - name: OAUTH_CLIENT_ID + value: "fecb863c9aa334aba93c9017f4b9bee8" + - name: OAUTH_CLIENT_SECRET + value: "761c17a9a49670489ccf93ccffd344dbfc642ae994ac2ee991dbb42de3f6c3af" + - name: SLACK_PILOT_WEBHOOK_URL + value: "https://hooks.slack.com/services/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" + volumeMounts: + - name: vaults + mountPath: /vaults + readinessProbe: + httpGet: + path: /health + port: 3456 + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + httpGet: + path: /health + port: 3456 + initialDelaySeconds: 10 + periodSeconds: 30 + volumes: + - name: vaults + hostPath: + path: /home/garfield/obsidian/vaults + type: Directory +--- +apiVersion: v1 +kind: Service +metadata: + name: hermes-mcp + namespace: fetcherpay +spec: + selector: + app: hermes-mcp + ports: + - protocol: TCP + port: 3456 + targetPort: 3456 +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: hermes-ingress + namespace: fetcherpay + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-buffering: "off" +spec: + ingressClassName: nginx + rules: + - host: hermes.squaremcp.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: hermes-mcp + port: + number: 3456 + tls: + - hosts: + - hermes.squaremcp.com + secretName: hermes-squaremcp-tls diff --git a/src/imap.ts b/src/imap.ts index e565b8f..7e3d0ee 100644 --- a/src/imap.ts +++ b/src/imap.ts @@ -1,7 +1,7 @@ import { ImapFlow } from 'imapflow'; import type { EmailCredentials } from './multitenancy/credential-store.js'; -export type Account = 'yahoo' | 'fetcherpay' | 'garfield' | 'sales' | 'leads' | 'founder' | 'gmail'; +export type Account = 'yahoo' | 'fetcherpay' | 'garfield' | 'sales' | 'leads' | 'founder' | 'gmail' | 'sqcp_garfield' | 'sqcp_info' | 'sqcp_sales' | 'sqcp_support' | 'sqcp_founder' | 'sqcp_contact' | 'sqcp_admin'; export type EmailCtx = Account | EmailCredentials; const FETCHERPAY_IMAP_HOST = process.env['FETCHERPAY_IMAP_HOST'] ?? 'mail.fetcherpay.com'; @@ -29,6 +29,20 @@ function getEnvConfig(account: Account = 'yahoo') { return fetcherpayImapConfig(process.env['LEADS_EMAIL']!, process.env['LEADS_PASSWORD']!); case 'founder': return fetcherpayImapConfig(process.env['FOUNDER_EMAIL']!, process.env['FOUNDER_PASSWORD']!); + case 'sqcp_garfield': + return fetcherpayImapConfig(process.env['SQCP_GARFIELD_EMAIL']!, process.env['SQCP_GARFIELD_PASSWORD']!); + case 'sqcp_info': + return fetcherpayImapConfig(process.env['SQCP_INFO_EMAIL']!, process.env['SQCP_INFO_PASSWORD']!); + case 'sqcp_sales': + return fetcherpayImapConfig(process.env['SQCP_SALES_EMAIL']!, process.env['SQCP_SALES_PASSWORD']!); + case 'sqcp_support': + return fetcherpayImapConfig(process.env['SQCP_SUPPORT_EMAIL']!, process.env['SQCP_SUPPORT_PASSWORD']!); + case 'sqcp_founder': + return fetcherpayImapConfig(process.env['SQCP_FOUNDER_EMAIL']!, process.env['SQCP_FOUNDER_PASSWORD']!); + case 'sqcp_contact': + return fetcherpayImapConfig(process.env['SQCP_CONTACT_EMAIL']!, process.env['SQCP_CONTACT_PASSWORD']!); + case 'sqcp_admin': + return fetcherpayImapConfig(process.env['SQCP_ADMIN_EMAIL']!, process.env['SQCP_ADMIN_PASSWORD']!); case 'gmail': return { host: 'imap.gmail.com', @@ -290,6 +304,13 @@ export async function getProfile(ctx: EmailCtx = 'yahoo'): Promise<{ email: stri leads: process.env['LEADS_EMAIL'] ?? '', founder: process.env['FOUNDER_EMAIL'] ?? '', gmail: process.env['GMAIL_EMAIL'] ?? '', + sqcp_garfield: process.env['SQCP_GARFIELD_EMAIL'] ?? '', + sqcp_info: process.env['SQCP_INFO_EMAIL'] ?? '', + sqcp_sales: process.env['SQCP_SALES_EMAIL'] ?? '', + sqcp_support: process.env['SQCP_SUPPORT_EMAIL'] ?? '', + sqcp_founder: process.env['SQCP_FOUNDER_EMAIL'] ?? '', + sqcp_contact: process.env['SQCP_CONTACT_EMAIL'] ?? '', + sqcp_admin: process.env['SQCP_ADMIN_EMAIL'] ?? '', }; const email = emailMap[ctx] ?? ''; return { email, name: email.split('@')[0], account: ctx }; diff --git a/src/manifest.ts b/src/manifest.ts index 617bb07..29d7207 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -796,9 +796,9 @@ export function getOpenApiSpecSocial(serverUrl: string) { const ACCOUNT_PARAM_SCHEMA = { account: { type: 'string', - enum: ['yahoo', 'fetcherpay', 'garfield', 'sales', 'leads', 'founder', 'gmail'], + 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".', + '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" (Gmail account), or squaremcp accounts: "sqcp_garfield", "sqcp_info", "sqcp_sales", "sqcp_support", "sqcp_founder", "sqcp_contact", "sqcp_admin". Defaults to "yahoo".', }, }; diff --git a/src/smtp.ts b/src/smtp.ts index 1e15567..df20c1f 100644 --- a/src/smtp.ts +++ b/src/smtp.ts @@ -27,6 +27,20 @@ function getEnvSmtpTransport(account: Account = 'yahoo') { return fetcherpaySmtpTransport(process.env['LEADS_EMAIL']!, process.env['LEADS_PASSWORD']!); case 'founder': return fetcherpaySmtpTransport(process.env['FOUNDER_EMAIL']!, process.env['FOUNDER_PASSWORD']!); + case 'sqcp_garfield': + return fetcherpaySmtpTransport(process.env['SQCP_GARFIELD_EMAIL']!, process.env['SQCP_GARFIELD_PASSWORD']!); + case 'sqcp_info': + return fetcherpaySmtpTransport(process.env['SQCP_INFO_EMAIL']!, process.env['SQCP_INFO_PASSWORD']!); + case 'sqcp_sales': + return fetcherpaySmtpTransport(process.env['SQCP_SALES_EMAIL']!, process.env['SQCP_SALES_PASSWORD']!); + case 'sqcp_support': + return fetcherpaySmtpTransport(process.env['SQCP_SUPPORT_EMAIL']!, process.env['SQCP_SUPPORT_PASSWORD']!); + case 'sqcp_founder': + return fetcherpaySmtpTransport(process.env['SQCP_FOUNDER_EMAIL']!, process.env['SQCP_FOUNDER_PASSWORD']!); + case 'sqcp_contact': + return fetcherpaySmtpTransport(process.env['SQCP_CONTACT_EMAIL']!, process.env['SQCP_CONTACT_PASSWORD']!); + case 'sqcp_admin': + return fetcherpaySmtpTransport(process.env['SQCP_ADMIN_EMAIL']!, process.env['SQCP_ADMIN_PASSWORD']!); case 'gmail': return nodemailer.createTransport({ host: 'smtp.gmail.com', @@ -67,6 +81,13 @@ function resolveSenderEmail(ctx: EmailCtx): string { leads: process.env['LEADS_EMAIL'] ?? '', founder: process.env['FOUNDER_EMAIL'] ?? '', gmail: process.env['GMAIL_EMAIL'] ?? '', + sqcp_garfield: process.env['SQCP_GARFIELD_EMAIL'] ?? '', + sqcp_info: process.env['SQCP_INFO_EMAIL'] ?? '', + sqcp_sales: process.env['SQCP_SALES_EMAIL'] ?? '', + sqcp_support: process.env['SQCP_SUPPORT_EMAIL'] ?? '', + sqcp_founder: process.env['SQCP_FOUNDER_EMAIL'] ?? '', + sqcp_contact: process.env['SQCP_CONTACT_EMAIL'] ?? '', + sqcp_admin: process.env['SQCP_ADMIN_EMAIL'] ?? '', }; return emailMap[ctx] ?? ''; } diff --git a/src/tools.ts b/src/tools.ts index 300be63..5f008e2 100644 --- a/src/tools.ts +++ b/src/tools.ts @@ -19,7 +19,7 @@ import { getMe as getSlackMe, getChannels as getSlackChannels, sendMessage as se const ACCOUNT_PARAM = { account: { type: 'string', - enum: ['yahoo', 'fetcherpay', 'garfield', 'sales', 'leads', 'founder', 'gmail'], + 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".', }, };