Skip to content

Commit 77226f6

Browse files
authored
feat: Support order inbox email and set desc default (#26)
* feat: Support order inbox email and set desc default * test * Add more on desc
1 parent b106cd1 commit 77226f6

File tree

5 files changed

+27
-7
lines changed

5 files changed

+27
-7
lines changed

mcp_email_server/app.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from datetime import datetime
2-
from typing import Annotated
2+
from typing import Annotated, Literal
33

44
from mcp.server.fastmcp import FastMCP
55
from pydantic import Field
@@ -38,19 +38,31 @@ async def add_email_account(email: EmailSettings) -> None:
3838
@mcp.tool(description="Paginate emails, page start at 1, before and since as UTC datetime.")
3939
async def page_email(
4040
account_name: Annotated[str, Field(description="The name of the email account.")],
41-
page: Annotated[int, Field(default=1, description="The page number to retrieve (starting from 1).")] = 1,
41+
page: Annotated[
42+
int,
43+
Field(default=1, description="The page number to retrieve (starting from 1)."),
44+
] = 1,
4245
page_size: Annotated[int, Field(default=10, description="The number of emails to retrieve per page.")] = 10,
4346
before: Annotated[
44-
datetime | None, Field(default=None, description="Retrieve emails before this datetime (UTC).")
47+
datetime | None,
48+
Field(default=None, description="Retrieve emails before this datetime (UTC)."),
4549
] = None,
4650
since: Annotated[
47-
datetime | None, Field(default=None, description="Retrieve emails since this datetime (UTC).")
51+
datetime | None,
52+
Field(default=None, description="Retrieve emails since this datetime (UTC)."),
4853
] = None,
4954
subject: Annotated[str | None, Field(default=None, description="Filter emails by subject.")] = None,
5055
body: Annotated[str | None, Field(default=None, description="Filter emails by body.")] = None,
5156
text: Annotated[str | None, Field(default=None, description="Filter emails by text.")] = None,
5257
from_address: Annotated[str | None, Field(default=None, description="Filter emails by sender address.")] = None,
53-
to_address: Annotated[str | None, Field(default=None, description="Filter emails by recipient address.")] = None,
58+
to_address: Annotated[
59+
str | None,
60+
Field(default=None, description="Filter emails by recipient address."),
61+
] = None,
62+
order: Annotated[
63+
Literal["asc", "desc"],
64+
Field(default=None, description="Order emails by field. `asc` or `desc`."),
65+
] = "desc",
5466
) -> EmailPageResponse:
5567
handler = dispatch_handler(account_name)
5668

@@ -64,6 +76,7 @@ async def page_email(
6476
text=text,
6577
from_address=from_address,
6678
to_address=to_address,
79+
order=order,
6780
)
6881

6982

mcp_email_server/emails/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ async def get_emails(
1919
text: str | None = None,
2020
from_address: str | None = None,
2121
to_address: str | None = None,
22+
order: str = "desc",
2223
) -> "EmailPageResponse":
2324
"""
2425
Get emails

mcp_email_server/emails/classic.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ async def get_emails_stream( # noqa: C901
9494
text: str | None = None,
9595
from_address: str | None = None,
9696
to_address: str | None = None,
97+
order: str = "desc",
9798
) -> AsyncGenerator[dict[str, Any], None]:
9899
imap = self.imap_class(self.email_server.host, self.email_server.port)
99100
try:
@@ -119,6 +120,9 @@ async def get_emails_stream( # noqa: C901
119120
start = (page - 1) * page_size
120121
end = start + page_size
121122

123+
if order == "desc":
124+
message_ids.reverse()
125+
122126
# Fetch each message
123127
for _, message_id in enumerate(message_ids[start:end]):
124128
try:
@@ -279,10 +283,11 @@ async def get_emails(
279283
text: str | None = None,
280284
from_address: str | None = None,
281285
to_address: str | None = None,
286+
order: str = "desc",
282287
) -> EmailPageResponse:
283288
emails = []
284289
async for email_data in self.incoming_client.get_emails_stream(
285-
page, page_size, before, since, subject, body, text, from_address, to_address
290+
page, page_size, before, since, subject, body, text, from_address, to_address, order
286291
):
287292
emails.append(EmailData.from_email(email_data))
288293
total = await self.incoming_client.get_email_count(before, since, subject, body, text, from_address, to_address)

tests/test_classic_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ async def test_get_emails(self, classic_handler):
106106

107107
# Verify the client methods were called correctly
108108
classic_handler.incoming_client.get_emails_stream.assert_called_once_with(
109-
1, 10, now, None, "Test", None, None, "sender@example.com", None
109+
1, 10, now, None, "Test", None, None, "sender@example.com", None, "desc"
110110
)
111111
mock_count.assert_called_once_with(now, None, "Test", None, None, "sender@example.com", None)
112112

tests/test_mcp_tools.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ async def test_page_email(self):
159159
text=None,
160160
from_address="sender@example.com",
161161
to_address=None,
162+
order="desc",
162163
)
163164

164165
@pytest.mark.asyncio

0 commit comments

Comments
 (0)