From af796d8583a841ab6e522e670cd6cc8b06a7363a Mon Sep 17 00:00:00 2001 From: Kacper Kwapisz Date: Wed, 29 Apr 2026 09:25:59 +0200 Subject: [PATCH 1/2] Send IMAP ID after login for providers that require it (netease) Some providers (notably netease 163.com / 126.com / yeah.net) reject clients that don't issue an RFC 2971 ID command after login. Send a minimal client identification when the server advertises the ID capability. Failures are logged at debug and never break login. Fixes #10 --- src/server.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/server.py b/src/server.py index 1422a01..b63a764 100644 --- a/src/server.py +++ b/src/server.py @@ -265,6 +265,15 @@ def resolve_account(accounts: list[dict], account_id: str) -> dict: # --------------------------------------------------------------------------- +# RFC 2971 IMAP ID — required by some providers (e.g. netease 163.com / 126.com / yeah.net) +# which reject clients that don't identify themselves after login. +_IMAP_CLIENT_ID = { + "name": "poke-mail", + "version": "1.0.0", + "vendor": "Poke Interactions", +} + + def get_imap_client(account: dict) -> IMAPClient: port = account["imap_port"] use_ssl = port == 993 @@ -272,6 +281,13 @@ def get_imap_client(account: dict) -> IMAPClient: if not use_ssl: client.starttls() client.login(account["imap_username"], account["imap_password"]) + # Send IMAP ID if the server supports it. Non-fatal: not all servers do, + # and we never want this to break an otherwise-working login. + try: + if client.has_capability("ID"): + client.id_(_IMAP_CLIENT_ID) + except Exception as e: + logger.debug("IMAP ID command failed for %s: %s", account.get("id"), e) return client From 83a3c482ec2ad33939aa284da5ce497f5c6e978a Mon Sep 17 00:00:00 2001 From: Kacper Kwapisz Date: Wed, 29 Apr 2026 09:27:59 +0200 Subject: [PATCH 2/2] Skip MCP_API_KEY generation in tunnel mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit start.sh previously generated and persisted an MCP_API_KEY to .env unconditionally on first run. In tunnel mode (POKE_TUNNEL=1, the default) the local server runs unauthenticated and the Poke tunnel handles auth — generating a key there is at best useless and at worst overwrites the user's pre-set key, causing 421 errors at the tunnel. Move .env loading and POKE_TUNNEL resolution above the generation block, and skip generation entirely when POKE_TUNNEL=1. Re-source .env after a successful generation so the rest of the script sees the new value. Fixes #9 --- start.sh | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/start.sh b/start.sh index 66ec470..cf89bf6 100644 --- a/start.sh +++ b/start.sh @@ -207,10 +207,23 @@ PYEOF fi fi -# 4. MCP_API_KEY — generate once and persist to .env -if [ ! -f .env ] \ +# ── Load .env early so POKE_TUNNEL is visible to the MCP_API_KEY logic below ── +if [ -f .env ]; then + set -a + source .env + set +a +fi + +# Tunnel-mode detection must happen BEFORE the MCP_API_KEY block: in tunnel +# mode (POKE_TUNNEL=1, the default) the local server runs unauthenticated and +# the tunnel handles auth, so we must NOT generate a key — doing so previously +# overwrote user-supplied keys and broke working setups (issue #9). +POKE_TUNNEL="${POKE_TUNNEL:-1}" + +# 4. MCP_API_KEY — generate once and persist to .env (skipped in tunnel mode) +if [ "${POKE_TUNNEL}" != "1" ] && { [ ! -f .env ] \ || grep -Eq '^[[:space:]]*MCP_API_KEY=your-secret-key-here' .env 2>/dev/null \ - || ! grep -Eq '^[[:space:]]*MCP_API_KEY=.+' .env 2>/dev/null; then + || ! grep -Eq '^[[:space:]]*MCP_API_KEY=.+' .env 2>/dev/null; }; then RANDOM_KEY=$(python3 -c " import secrets, string alphabet = string.ascii_letters + string.digits @@ -233,18 +246,13 @@ PYEOF fi echo " ✓ MCP_API_KEY generated and saved to .env" echo "" -fi - -# ── Load .env ───────────────────────────────────────────────────────────────── -if [ -f .env ]; then + # Re-source so the freshly generated key is visible to the rest of the script set -a source .env set +a fi -# ── Tunnel-mode detection ───────────────────────────────────────────────────── -POKE_TUNNEL="${POKE_TUNNEL:-1}" - +# ── Tunnel-mode enforcement ─────────────────────────────────────────────────── if [ "${POKE_TUNNEL}" != "1" ]; then : "${MCP_API_KEY:?MCP_API_KEY is not set — add it to .env or export it}" else