From 9ecb02785c4e670dbacd461c380b45f9822dfb4c Mon Sep 17 00:00:00 2001 From: garfieldheron Date: Thu, 5 Mar 2026 13:37:51 -0500 Subject: [PATCH] Remove specific account references from public documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace FETCHERPAY with generic CUSTOM account examples - Update README.md, .env.example, and DEPLOY.md with generic configurations - Remove hardcoded IPs, email addresses, and domain names - Update package.json description to be more generic πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .env.example | 17 +++++---- DEPLOY.md | 97 ++++++++++++++++++++++++++-------------------------- README.md | 30 ++++++++-------- package.json | 2 +- 4 files changed, 72 insertions(+), 74 deletions(-) diff --git a/.env.example b/.env.example index d96a9a1..a3613e9 100644 --- a/.env.example +++ b/.env.example @@ -3,15 +3,14 @@ YAHOO_EMAIL=you@yahoo.com YAHOO_APP_PASSWORD=xxxx xxxx xxxx xxxx -# ── FetcherPay self-hosted mail (Dovecot / Poste.io) ───────────────────────── -# IMAP/SMTP are exposed as Kubernetes NodePorts on the server. -# Use the direct server IP (not hostname) to avoid K8s internal DNS flakiness. -FETCHERPAY_EMAIL=you@fetcherpay.com -FETCHERPAY_PASSWORD=yourpassword -FETCHERPAY_IMAP_HOST=23.120.207.35 # direct IP avoids EAI_AGAIN; or: mail.fetcherpay.com -FETCHERPAY_IMAP_PORT=30993 # K8s NodePort β€” IMAPS (TLS, self-signed cert) -FETCHERPAY_SMTP_HOST=23.120.207.35 -FETCHERPAY_SMTP_PORT=30587 # K8s NodePort β€” SMTP + STARTTLS +# ── Optional: Custom IMAP/SMTP Server ──────────────────────────────────────── +# Uncomment and configure these if you want to use a second email account +# CUSTOM_EMAIL=you@yourdomain.com +# CUSTOM_PASSWORD=yourpassword +# CUSTOM_IMAP_HOST=mail.yourdomain.com +# CUSTOM_IMAP_PORT=993 +# CUSTOM_SMTP_HOST=mail.yourdomain.com +# CUSTOM_SMTP_PORT=587 # ── Server ─────────────────────────────────────────────────────────────────── PORT=3456 diff --git a/DEPLOY.md b/DEPLOY.md index 36c1475..de0d6da 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -1,7 +1,7 @@ # Hermes MCP β€” Setup & Deployment Hermes is a multi-account email MCP server for Claude AI. -It supports **Yahoo Mail** (IMAP App Password) and any **self-hosted mail server** (Dovecot / Poste.io). +It supports **Yahoo Mail** (IMAP App Password) and any **custom IMAP/SMTP server**. --- @@ -25,51 +25,51 @@ curl http://localhost:3456/health --- -## Production deployment (MicroK8s β€” current setup) +## Production deployment (Kubernetes example) -The server runs as a Kubernetes Deployment on `23.120.207.35` (MicroK8s single-node cluster). -SSL is handled by `cert-manager` with a Let's Encrypt cert for `hermes.fetcherpay.com`. +Example deployment using MicroK8s single-node cluster. +SSL is handled by `cert-manager` with a Let's Encrypt certificate. ### Prerequisites on the server - MicroK8s with addons: `dns`, `ingress`, `registry`, `cert-manager` - Local registry at `localhost:32000` - A `ClusterIssuer` named `letsencrypt-prod` already configured -### One-time: create K8s namespace secret +### One-time: create K8s namespace and secret ```bash -microk8s kubectl create namespace fetcherpay # if it doesn't exist +microk8s kubectl create namespace hermes-mcp # if it doesn't exist -microk8s kubectl create secret generic hermes-mcp-env -n fetcherpay \ - --from-literal=YAHOO_EMAIL=gheron01@yahoo.com \ - --from-literal=YAHOO_APP_PASSWORD=lzlleytmslxocxae \ - --from-literal=FETCHERPAY_EMAIL=garfield.heron@fetcherpay.com \ - --from-literal=FETCHERPAY_PASSWORD=onelove \ - --from-literal=FETCHERPAY_IMAP_HOST=23.120.207.35 \ - --from-literal=FETCHERPAY_IMAP_PORT=30993 \ - --from-literal=FETCHERPAY_SMTP_HOST=23.120.207.35 \ - --from-literal=FETCHERPAY_SMTP_PORT=30587 \ +microk8s kubectl create secret generic hermes-mcp-env -n hermes-mcp \ + --from-literal=YAHOO_EMAIL=your@yahoo.com \ + --from-literal=YAHOO_APP_PASSWORD=your-app-password \ + --from-literal=CUSTOM_EMAIL=your@domain.com \ + --from-literal=CUSTOM_PASSWORD=your-password \ + --from-literal=CUSTOM_IMAP_HOST=mail.yourdomain.com \ + --from-literal=CUSTOM_IMAP_PORT=993 \ + --from-literal=CUSTOM_SMTP_HOST=mail.yourdomain.com \ + --from-literal=CUSTOM_SMTP_PORT=587 \ --from-literal=PORT=3456 ``` ### Build & push image ```bash -# From your local machine β€” SCP src to server first, then SSH in: -scp -P 2222 -r src/ package*.json tsconfig.json Dockerfile garfield@23.120.207.35:~/hermes-mcp/ - -ssh -p 2222 garfield@23.120.207.35 -cd ~/hermes-mcp +# Option 1: Build locally and push to your registry docker build -t localhost:32000/hermes-mcp:latest . docker push localhost:32000/hermes-mcp:latest + +# Option 2: Copy to server and build there +scp -r src/ package*.json tsconfig.json Dockerfile user@your-server:~/hermes-mcp/ +ssh user@your-server "cd ~/hermes-mcp && docker build -t localhost:32000/hermes-mcp:latest . && docker push localhost:32000/hermes-mcp:latest" ``` -### Apply K8s manifests (hermes-k8s.yaml on the server) +### Apply K8s manifests ```yaml -# ~/hermes-mcp/hermes-k8s.yaml (already applied β€” shown for reference) +# hermes-k8s.yaml apiVersion: apps/v1 kind: Deployment metadata: name: hermes-mcp - namespace: fetcherpay + namespace: hermes-mcp spec: replicas: 1 selector: @@ -99,7 +99,7 @@ apiVersion: v1 kind: Service metadata: name: hermes-mcp - namespace: fetcherpay + namespace: hermes-mcp spec: selector: app: hermes-mcp @@ -111,7 +111,7 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: hermes-ingress - namespace: fetcherpay + namespace: hermes-mcp annotations: cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/proxy-buffering: "off" @@ -120,7 +120,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: hermes.fetcherpay.com + - host: hermes.yourdomain.com http: paths: - path: / @@ -132,23 +132,24 @@ spec: number: 3456 tls: - hosts: - - hermes.fetcherpay.com - secretName: hermes-fetcherpay-tls + - hermes.yourdomain.com + secretName: hermes-tls +``` + +Apply the manifests: +```bash +microk8s kubectl apply -f hermes-k8s.yaml ``` ### Redeploy after code changes ```bash -# On your local machine: -scp -P 2222 src/imap.ts src/smtp.ts src/tools.ts src/index.ts \ - garfield@23.120.207.35:~/hermes-mcp/src/ +# Rebuild and push the image +docker build -t localhost:32000/hermes-mcp:latest . +docker push localhost:32000/hermes-mcp:latest -ssh -p 2222 garfield@23.120.207.35 " - cd ~/hermes-mcp && - docker build -t localhost:32000/hermes-mcp:latest . && - docker push localhost:32000/hermes-mcp:latest && - microk8s kubectl rollout restart deployment/hermes-mcp -n fetcherpay && - microk8s kubectl rollout status deployment/hermes-mcp -n fetcherpay -" +# Restart the deployment +microk8s kubectl rollout restart deployment/hermes-mcp -n hermes-mcp +microk8s kubectl rollout status deployment/hermes-mcp -n hermes-mcp ``` --- @@ -157,17 +158,17 @@ ssh -p 2222 garfield@23.120.207.35 " ```bash # Logs -microk8s kubectl logs -n fetcherpay -l app=hermes-mcp --tail=100 -f +microk8s kubectl logs -n hermes-mcp -l app=hermes-mcp --tail=100 -f # Pod status -microk8s kubectl get pods -n fetcherpay -l app=hermes-mcp +microk8s kubectl get pods -n hermes-mcp -l app=hermes-mcp # Update a single env var without rebuild (takes effect on next rollout) -microk8s kubectl set env deployment/hermes-mcp -n fetcherpay KEY=value -microk8s kubectl rollout restart deployment/hermes-mcp -n fetcherpay +microk8s kubectl set env deployment/hermes-mcp -n hermes-mcp KEY=value +microk8s kubectl rollout restart deployment/hermes-mcp -n hermes-mcp # Health check -curl https://hermes.fetcherpay.com/health +curl https://hermes.yourdomain.com/health ``` --- @@ -175,7 +176,7 @@ curl https://hermes.fetcherpay.com/health ## Add to Claude.ai 1. Go to **Claude.ai β†’ Settings β†’ Connectors β†’ Add custom connector** -2. Enter URL: `https://hermes.fetcherpay.com/mcp` +2. Enter URL: `https://hermes.yourdomain.com/mcp` (or your server's URL) 3. Click Connect ### Available tools @@ -189,7 +190,7 @@ curl https://hermes.fetcherpay.com/health | `create_draft` | Save a draft to the Drafts folder | `to`, `subject`, `body`, `account` | | `send_email` | Send an email | `to`, `subject`, `body`, `account` | -`account` is always optional β€” defaults to `"yahoo"`. Set to `"fetcherpay"` for the FetcherPay mailbox. +`account` is always optional and defaults to `"yahoo"`. Configure your second account in the code if needed. --- @@ -197,7 +198,7 @@ curl https://hermes.fetcherpay.com/health | Issue | Cause | Fix | |-------|-------|-----| -| `yahoo_read_message` 5-min timeout | `source: true` downloads full raw RFC822 | Use `bodyParts: ['TEXT']` | +| `read_message` timeout | `source: true` downloads full raw RFC822 | Use `bodyParts: ['TEXT']` instead | | `messageFlagsAdd` deadlock | Called inside `for await` loop while FETCH active | Moved to after the loop | -| Stale session after pod restart | `!sessionId` guard blocked re-initialize | Accept initialize regardless of session ID | -| FetcherPay `EAI_AGAIN` DNS | K8s internal DNS cold-start for hostname | Use direct IP `23.120.207.35` | +| Stale session after pod restart | Session ID guard blocked re-initialize | Accept initialize regardless of session ID | +| `EAI_AGAIN` DNS errors | K8s internal DNS resolution issues | Use direct IP instead of hostname | diff --git a/README.md b/README.md index 88445a4..d582e39 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,17 @@ # Hermes MCP A multi-account email MCP server for [Claude AI](https://claude.ai). -Supports **Yahoo Mail** (IMAP App Password) and any **self-hosted mail server** (Dovecot / Poste.io). +Supports **Yahoo Mail** (IMAP App Password) and any **self-hosted mail server** (IMAP/SMTP). --- ## Features - Read, search, and send email from Claude via MCP -- Multi-account: connect Yahoo and a custom IMAP/SMTP server simultaneously +- Multi-account support: Yahoo Mail and custom IMAP/SMTP servers - Streamable HTTP transport (MCP 1.x) + legacy SSE endpoint - Automatic session recovery after server restarts -- Deployable to Kubernetes (MicroK8s example included) +- Docker and Kubernetes deployment ready --- @@ -26,7 +26,7 @@ Supports **Yahoo Mail** (IMAP App Password) and any **self-hosted mail server** | `create_draft` | Save a draft to the Drafts folder | `to`, `subject`, `body`, `account` | | `send_email` | Send an email | `to`, `subject`, `body`, `account` | -`account` defaults to `"yahoo"`. Set to `"fetcherpay"` (or whatever you name your second account) for the custom mailbox. +`account` parameter allows you to specify which configured mailbox to use (defaults to `"yahoo"`). --- @@ -60,19 +60,17 @@ Copy `.env.example` to `.env` and fill in your values: YAHOO_EMAIL=you@yahoo.com YAHOO_APP_PASSWORD=xxxx xxxx xxxx xxxx -# Self-hosted mail (Dovecot / Poste.io / any IMAP server) -FETCHERPAY_EMAIL=you@yourdomain.com -FETCHERPAY_PASSWORD=yourpassword -FETCHERPAY_IMAP_HOST=your-mail-server-ip -FETCHERPAY_IMAP_PORT=993 -FETCHERPAY_SMTP_HOST=your-mail-server-ip -FETCHERPAY_SMTP_PORT=587 +# Optional: Self-hosted mail server (any IMAP/SMTP server) +# CUSTOM_EMAIL=you@yourdomain.com +# CUSTOM_PASSWORD=yourpassword +# CUSTOM_IMAP_HOST=mail.yourdomain.com +# CUSTOM_IMAP_PORT=993 +# CUSTOM_SMTP_HOST=mail.yourdomain.com +# CUSTOM_SMTP_PORT=587 PORT=3456 ``` -> **Tip:** Use the server's direct IP for `FETCHERPAY_IMAP_HOST` / `FETCHERPAY_SMTP_HOST` to avoid DNS resolution issues in Kubernetes. - --- ## Connecting to Claude.ai @@ -107,9 +105,9 @@ Claude.ai ──POST /mcp──► StreamableHTTPServerTransport imapflow (IMAP) nodemailer (SMTP) β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β” - β”‚ Yahoo Mail β”‚ β”‚ Self-hosted β”‚ - β”‚ imap.mail β”‚ β”‚ Dovecot / β”‚ - β”‚ .yahoo.com β”‚ β”‚ Poste.io β”‚ + β”‚ Yahoo Mail β”‚ β”‚ Custom IMAP/ β”‚ + β”‚ β”‚ β”‚ SMTP Server β”‚ + β”‚ β”‚ β”‚ (optional) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` diff --git a/package.json b/package.json index f8e110f..0c8da04 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "hermes-mcp", "version": "1.0.0", - "description": "Yahoo Mail MCP server for Claude AI", + "description": "Multi-account email MCP server for Claude AI", "type": "module", "main": "dist/index.js", "scripts": {