Skip to content

Commit a65a755

Browse files
authored
feat: Refactor IMAP ID command handling for better compatibility with strict servers (#86)
1 parent fb73af6 commit a65a755

File tree

1 file changed

+31
-12
lines changed

1 file changed

+31
-12
lines changed

mcp_email_server/emails/classic.py

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,34 @@
2626
from mcp_email_server.log import logger
2727

2828

29+
async def _send_imap_id(imap: aioimaplib.IMAP4 | aioimaplib.IMAP4_SSL) -> None:
30+
"""Send IMAP ID command with fallback for strict servers like 163.com.
31+
32+
aioimaplib's id() method sends ID command with spaces between parentheses
33+
and content (e.g., 'ID ( "name" "value" )'), which some strict IMAP servers
34+
like 163.com reject with 'BAD Parse command error'.
35+
36+
This function first tries the standard id() method, and if it fails,
37+
falls back to sending a raw command with correct format.
38+
39+
See: https://github.com/ai-zerolab/mcp-email-server/issues/85
40+
"""
41+
try:
42+
response = await imap.id(name="mcp-email-server", version="1.0.0")
43+
if response.result != "OK":
44+
# Fallback for strict servers (e.g., 163.com)
45+
# Send raw command with correct parenthesis format
46+
await imap.protocol.execute(
47+
aioimaplib.Command(
48+
"ID",
49+
imap.protocol.new_tag(),
50+
'("name" "mcp-email-server" "version" "1.0.0")',
51+
)
52+
)
53+
except Exception as e:
54+
logger.warning(f"IMAP ID command failed: {e!s}")
55+
56+
2957
class EmailClient:
3058
def __init__(self, email_server: EmailServer, sender: str | None = None):
3159
self.email_server = email_server
@@ -202,10 +230,7 @@ async def get_emails_metadata_stream( # noqa: C901
202230

203231
# Login and select inbox
204232
await imap.login(self.email_server.user_name, self.email_server.password)
205-
try:
206-
await imap.id(name="mcp-email-server", version="1.0.0")
207-
except Exception as e:
208-
logger.warning(f"IMAP ID command failed: {e!s}")
233+
await _send_imap_id(imap)
209234
await imap.select(mailbox)
210235

211236
search_criteria = self._build_search_criteria(
@@ -366,10 +391,7 @@ async def get_email_body_by_id(self, email_id: str, mailbox: str = "INBOX") -> d
366391

367392
# Login and select inbox
368393
await imap.login(self.email_server.user_name, self.email_server.password)
369-
try:
370-
await imap.id(name="mcp-email-server", version="1.0.0")
371-
except Exception as e:
372-
logger.warning(f"IMAP ID command failed: {e!s}")
394+
await _send_imap_id(imap)
373395
await imap.select(mailbox)
374396

375397
# Fetch the specific email by UID
@@ -411,10 +433,7 @@ async def download_attachment(
411433
await imap.wait_hello_from_server()
412434

413435
await imap.login(self.email_server.user_name, self.email_server.password)
414-
try:
415-
await imap.id(name="mcp-email-server", version="1.0.0")
416-
except Exception as e:
417-
logger.warning(f"IMAP ID command failed: {e!s}")
436+
await _send_imap_id(imap)
418437
await imap.select("INBOX")
419438

420439
data = await self._fetch_email_with_formats(imap, email_id)

0 commit comments

Comments
 (0)