@sempervirens-labs/apple-mail-mcp 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +3 -1
- package/README.md +4 -0
- package/package.json +1 -1
- package/src/applescript/mail.ts +59 -6
- package/src/index.ts +1 -0
- package/src/tools.ts +5 -0
package/README.md
CHANGED
|
@@ -160,6 +160,7 @@ Get recent emails from a mailbox.
|
|
|
160
160
|
| `mailbox` | string | No | "INBOX" | Mailbox name |
|
|
161
161
|
| `limit` | number | No | 10 | Max emails to retrieve |
|
|
162
162
|
| `includeContent` | boolean | No | false | Include email body |
|
|
163
|
+
| `unreadOnly` | boolean | No | false | Only return unread emails |
|
|
163
164
|
|
|
164
165
|
**Example response:**
|
|
165
166
|
```json
|
|
@@ -169,6 +170,9 @@ Get recent emails from a mailbox.
|
|
|
169
170
|
"id": 12345,
|
|
170
171
|
"subject": "Meeting tomorrow",
|
|
171
172
|
"sender": "John Doe <john@example.com>",
|
|
173
|
+
"to": ["you@example.com", "team@example.com"],
|
|
174
|
+
"cc": ["manager@example.com"],
|
|
175
|
+
"bcc": [],
|
|
172
176
|
"dateSent": "Monday, 10. January 2025 at 09:30:00",
|
|
173
177
|
"isRead": false
|
|
174
178
|
}
|
package/package.json
CHANGED
package/src/applescript/mail.ts
CHANGED
|
@@ -100,6 +100,9 @@ export interface Email {
|
|
|
100
100
|
id: number;
|
|
101
101
|
subject: string;
|
|
102
102
|
sender: string;
|
|
103
|
+
to: string[];
|
|
104
|
+
cc: string[];
|
|
105
|
+
bcc: string[];
|
|
103
106
|
dateSent: string;
|
|
104
107
|
isRead: boolean;
|
|
105
108
|
content?: string;
|
|
@@ -113,8 +116,9 @@ export function getEmails(options: {
|
|
|
113
116
|
mailbox?: string;
|
|
114
117
|
limit?: number;
|
|
115
118
|
includeContent?: boolean;
|
|
119
|
+
unreadOnly?: boolean;
|
|
116
120
|
}): Email[] {
|
|
117
|
-
const { account, mailbox = "INBOX", limit = 10, includeContent = false } = options;
|
|
121
|
+
const { account, mailbox = "INBOX", limit = 10, includeContent = false, unreadOnly = false } = options;
|
|
118
122
|
|
|
119
123
|
const contentPart = includeContent
|
|
120
124
|
? `set msgContent to content of msg`
|
|
@@ -124,12 +128,17 @@ export function getEmails(options: {
|
|
|
124
128
|
? `mailbox "${mailbox}" of account "${account}"`
|
|
125
129
|
: `mailbox "${mailbox}"`;
|
|
126
130
|
|
|
131
|
+
// If unreadOnly, filter messages by read status
|
|
132
|
+
const messageFilter = unreadOnly
|
|
133
|
+
? `(messages of theMailbox whose read status is false)`
|
|
134
|
+
: `messages of theMailbox`;
|
|
135
|
+
|
|
127
136
|
const script = `
|
|
128
137
|
tell application "Mail"
|
|
129
138
|
set results to ""
|
|
130
139
|
try
|
|
131
140
|
set theMailbox to ${accountPart}
|
|
132
|
-
set msgList to
|
|
141
|
+
set msgList to ${messageFilter}
|
|
133
142
|
set msgCount to count of msgList
|
|
134
143
|
if msgCount > ${limit} then set msgCount to ${limit}
|
|
135
144
|
|
|
@@ -142,7 +151,26 @@ tell application "Mail"
|
|
|
142
151
|
set msgRead to read status of msg
|
|
143
152
|
${contentPart}
|
|
144
153
|
|
|
145
|
-
|
|
154
|
+
-- Get recipients
|
|
155
|
+
set toList to ""
|
|
156
|
+
repeat with r in to recipients of msg
|
|
157
|
+
set toList to toList & address of r & ","
|
|
158
|
+
end repeat
|
|
159
|
+
if toList is not "" then set toList to text 1 thru -2 of toList
|
|
160
|
+
|
|
161
|
+
set ccList to ""
|
|
162
|
+
repeat with r in cc recipients of msg
|
|
163
|
+
set ccList to ccList & address of r & ","
|
|
164
|
+
end repeat
|
|
165
|
+
if ccList is not "" then set ccList to text 1 thru -2 of ccList
|
|
166
|
+
|
|
167
|
+
set bccList to ""
|
|
168
|
+
repeat with r in bcc recipients of msg
|
|
169
|
+
set bccList to bccList & address of r & ","
|
|
170
|
+
end repeat
|
|
171
|
+
if bccList is not "" then set bccList to text 1 thru -2 of bccList
|
|
172
|
+
|
|
173
|
+
set results to results & msgId & "<<>>" & msgSubject & "<<>>" & msgSender & "<<>>" & toList & "<<>>" & ccList & "<<>>" & bccList & "<<>>" & (msgDate as string) & "<<>>" & msgRead & "<<>>" & msgContent & "|||"
|
|
146
174
|
end repeat
|
|
147
175
|
on error errMsg
|
|
148
176
|
return "ERROR:" & errMsg
|
|
@@ -161,11 +189,14 @@ end tell
|
|
|
161
189
|
const parts = result.split("|||").filter(Boolean);
|
|
162
190
|
|
|
163
191
|
for (const part of parts) {
|
|
164
|
-
const [id, subject, sender, dateSent, isRead, content] = part.split("<<>>");
|
|
192
|
+
const [id, subject, sender, to, cc, bcc, dateSent, isRead, content] = part.split("<<>>");
|
|
165
193
|
emails.push({
|
|
166
194
|
id: parseInt(id) || 0,
|
|
167
195
|
subject: subject || "(No Subject)",
|
|
168
196
|
sender: sender || "(Unknown)",
|
|
197
|
+
to: to ? to.split(",").map(s => s.trim()).filter(Boolean) : [],
|
|
198
|
+
cc: cc ? cc.split(",").map(s => s.trim()).filter(Boolean) : [],
|
|
199
|
+
bcc: bcc ? bcc.split(",").map(s => s.trim()).filter(Boolean) : [],
|
|
169
200
|
dateSent: dateSent || "",
|
|
170
201
|
isRead: isRead === "true",
|
|
171
202
|
content: content || undefined,
|
|
@@ -219,7 +250,26 @@ tell application "Mail"
|
|
|
219
250
|
set msgDate to date sent of msg
|
|
220
251
|
set msgRead to read status of msg
|
|
221
252
|
|
|
222
|
-
|
|
253
|
+
-- Get recipients
|
|
254
|
+
set toList to ""
|
|
255
|
+
repeat with r in to recipients of msg
|
|
256
|
+
set toList to toList & address of r & ","
|
|
257
|
+
end repeat
|
|
258
|
+
if toList is not "" then set toList to text 1 thru -2 of toList
|
|
259
|
+
|
|
260
|
+
set ccList to ""
|
|
261
|
+
repeat with r in cc recipients of msg
|
|
262
|
+
set ccList to ccList & address of r & ","
|
|
263
|
+
end repeat
|
|
264
|
+
if ccList is not "" then set ccList to text 1 thru -2 of ccList
|
|
265
|
+
|
|
266
|
+
set bccList to ""
|
|
267
|
+
repeat with r in bcc recipients of msg
|
|
268
|
+
set bccList to bccList & address of r & ","
|
|
269
|
+
end repeat
|
|
270
|
+
if bccList is not "" then set bccList to text 1 thru -2 of bccList
|
|
271
|
+
|
|
272
|
+
set results to results & msgId & "<<>>" & msgSubject & "<<>>" & msgSender & "<<>>" & toList & "<<>>" & ccList & "<<>>" & bccList & "<<>>" & (msgDate as string) & "<<>>" & msgRead & "|||"
|
|
223
273
|
set foundCount to foundCount + 1
|
|
224
274
|
end repeat
|
|
225
275
|
end repeat
|
|
@@ -240,11 +290,14 @@ end tell
|
|
|
240
290
|
const parts = result.split("|||").filter(Boolean);
|
|
241
291
|
|
|
242
292
|
for (const part of parts) {
|
|
243
|
-
const [id, subject, sender, dateSent, isRead] = part.split("<<>>");
|
|
293
|
+
const [id, subject, sender, to, cc, bcc, dateSent, isRead] = part.split("<<>>");
|
|
244
294
|
emails.push({
|
|
245
295
|
id: parseInt(id) || 0,
|
|
246
296
|
subject: subject || "(No Subject)",
|
|
247
297
|
sender: sender || "(Unknown)",
|
|
298
|
+
to: to ? to.split(",").map(s => s.trim()).filter(Boolean) : [],
|
|
299
|
+
cc: cc ? cc.split(",").map(s => s.trim()).filter(Boolean) : [],
|
|
300
|
+
bcc: bcc ? bcc.split(",").map(s => s.trim()).filter(Boolean) : [],
|
|
248
301
|
dateSent: dateSent || "",
|
|
249
302
|
isRead: isRead === "true",
|
|
250
303
|
});
|
package/src/index.ts
CHANGED
|
@@ -78,6 +78,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
78
78
|
mailbox: (args?.mailbox as string) || "INBOX",
|
|
79
79
|
limit: (args?.limit as number) || 10,
|
|
80
80
|
includeContent: (args?.includeContent as boolean) || false,
|
|
81
|
+
unreadOnly: (args?.unreadOnly as boolean) || false,
|
|
81
82
|
});
|
|
82
83
|
return {
|
|
83
84
|
content: [
|
package/src/tools.ts
CHANGED
|
@@ -50,6 +50,11 @@ export const MAIL_GET_EMAILS: Tool = {
|
|
|
50
50
|
description: "Whether to include the email body content (default: false)",
|
|
51
51
|
default: false,
|
|
52
52
|
},
|
|
53
|
+
unreadOnly: {
|
|
54
|
+
type: "boolean",
|
|
55
|
+
description: "Only return unread emails (default: false)",
|
|
56
|
+
default: false,
|
|
57
|
+
},
|
|
53
58
|
},
|
|
54
59
|
required: [],
|
|
55
60
|
},
|