@marlinjai/email-mcp 1.10.1 → 1.11.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/README.md +6 -0
- package/dist/index.js +185 -34
- package/dist/index.js.map +4 -4
- package/dist/setup/wizard.js +60 -3
- package/dist/setup/wizard.js.map +2 -2
- package/package.json +1 -1
package/dist/setup/wizard.js
CHANGED
|
@@ -922,6 +922,17 @@ function normalizeBody(body) {
|
|
|
922
922
|
function toAddress(contact) {
|
|
923
923
|
return contact.name ? { name: contact.name, address: contact.email } : contact.email;
|
|
924
924
|
}
|
|
925
|
+
var PROVIDER_LABELS = /* @__PURE__ */ new Set(["gmail", "outlook", "icloud", "imap"]);
|
|
926
|
+
function fromAddress(email, displayName, accountName) {
|
|
927
|
+
const own = displayName?.trim();
|
|
928
|
+
if (own) return { name: own, address: email };
|
|
929
|
+
const fallback = accountName?.trim();
|
|
930
|
+
const label = (name) => PROVIDER_LABELS.has(name) || name === email.toLowerCase() || name === email.toLowerCase().split("@")[0];
|
|
931
|
+
if (fallback && !label(fallback.toLowerCase())) {
|
|
932
|
+
return { name: fallback, address: email };
|
|
933
|
+
}
|
|
934
|
+
return email;
|
|
935
|
+
}
|
|
925
936
|
function toAddressList(contacts) {
|
|
926
937
|
return contacts?.length ? contacts.map(toAddress) : void 0;
|
|
927
938
|
}
|
|
@@ -954,12 +965,14 @@ var GmailAdapter = class {
|
|
|
954
965
|
gmail = null;
|
|
955
966
|
accountId = "";
|
|
956
967
|
email = "";
|
|
968
|
+
accountName = "";
|
|
957
969
|
async connect(credentials) {
|
|
958
970
|
if (!credentials.oauth) {
|
|
959
971
|
throw new Error("Gmail adapter requires OAuth credentials");
|
|
960
972
|
}
|
|
961
973
|
this.accountId = credentials.id;
|
|
962
974
|
this.email = credentials.email;
|
|
975
|
+
this.accountName = credentials.name;
|
|
963
976
|
const auth = new OAuth2Client2();
|
|
964
977
|
auth.setCredentials({
|
|
965
978
|
access_token: credentials.oauth.access_token,
|
|
@@ -1157,6 +1170,43 @@ var GmailAdapter = class {
|
|
|
1157
1170
|
});
|
|
1158
1171
|
return { id: res.data.id || draftId };
|
|
1159
1172
|
}
|
|
1173
|
+
/**
|
|
1174
|
+
* The signature Gmail's own editor would add: the one of the send-as
|
|
1175
|
+
* address the From header names (`this.email`, see buildRaw), or the
|
|
1176
|
+
* default send-as when that address is not listed. Read on every call, so
|
|
1177
|
+
* a signature changed in Gmail's settings applies to the next mail.
|
|
1178
|
+
*/
|
|
1179
|
+
async getSignature() {
|
|
1180
|
+
const entries = await this.sendAsList();
|
|
1181
|
+
const entry = this.ownSendAs(entries) || entries.find((e) => e.isDefault);
|
|
1182
|
+
if (!entry) throw new Error(`Gmail lists no send-as address for ${this.email}`);
|
|
1183
|
+
const html = (entry.signature || "").trim();
|
|
1184
|
+
return { sendAs: entry.sendAsEmail || this.email, html: html || null };
|
|
1185
|
+
}
|
|
1186
|
+
async sendAsList() {
|
|
1187
|
+
const gmail = this.ensureConnected();
|
|
1188
|
+
const res = await gmail.users.settings.sendAs.list({ userId: "me" });
|
|
1189
|
+
return res.data.sendAs || [];
|
|
1190
|
+
}
|
|
1191
|
+
ownSendAs(entries) {
|
|
1192
|
+
const own = this.email.toLowerCase();
|
|
1193
|
+
return entries.find((e) => (e.sendAsEmail || "").toLowerCase() === own);
|
|
1194
|
+
}
|
|
1195
|
+
/**
|
|
1196
|
+
* The From header: the account's address with the display name Gmail
|
|
1197
|
+
* keeps for it as a send-as address. When the settings cannot be read the
|
|
1198
|
+
* mail still goes out, named after the account (see `fromAddress`); the
|
|
1199
|
+
* signature outcome in the tool result already reports that failure.
|
|
1200
|
+
*/
|
|
1201
|
+
async from() {
|
|
1202
|
+
let displayName;
|
|
1203
|
+
try {
|
|
1204
|
+
displayName = this.ownSendAs(await this.sendAsList())?.displayName || void 0;
|
|
1205
|
+
} catch {
|
|
1206
|
+
displayName = void 0;
|
|
1207
|
+
}
|
|
1208
|
+
return fromAddress(this.email, displayName, this.accountName);
|
|
1209
|
+
}
|
|
1160
1210
|
async listDrafts(limit, _offset) {
|
|
1161
1211
|
const gmail = this.ensureConnected();
|
|
1162
1212
|
const res = await gmail.users.drafts.list({
|
|
@@ -1583,7 +1633,7 @@ var GmailAdapter = class {
|
|
|
1583
1633
|
* and any attachments. See `buildMimeMessage`.
|
|
1584
1634
|
*/
|
|
1585
1635
|
async buildRaw(params) {
|
|
1586
|
-
const message = await buildMimeMessage(this.
|
|
1636
|
+
const message = await buildMimeMessage(await this.from(), params);
|
|
1587
1637
|
return message.toString("base64url");
|
|
1588
1638
|
}
|
|
1589
1639
|
};
|
|
@@ -2498,6 +2548,7 @@ var ImapAdapter = class {
|
|
|
2498
2548
|
client = null;
|
|
2499
2549
|
accountId = "";
|
|
2500
2550
|
email = "";
|
|
2551
|
+
accountName = "";
|
|
2501
2552
|
passwordCreds = null;
|
|
2502
2553
|
connectingPromise = null;
|
|
2503
2554
|
async connect(credentials) {
|
|
@@ -2506,6 +2557,7 @@ var ImapAdapter = class {
|
|
|
2506
2557
|
}
|
|
2507
2558
|
this.accountId = credentials.id;
|
|
2508
2559
|
this.email = credentials.email;
|
|
2560
|
+
this.accountName = credentials.name;
|
|
2509
2561
|
this.passwordCreds = credentials.password;
|
|
2510
2562
|
await this.ensureConnected();
|
|
2511
2563
|
}
|
|
@@ -2938,7 +2990,7 @@ var ImapAdapter = class {
|
|
|
2938
2990
|
async sendEmail(params) {
|
|
2939
2991
|
if (!this.passwordCreds) throw new Error("No credentials available");
|
|
2940
2992
|
const transport = createSmtpTransport(this.email, this.passwordCreds);
|
|
2941
|
-
const messageId = await sendViaSmtp(transport, this.
|
|
2993
|
+
const messageId = await sendViaSmtp(transport, this.from(), params);
|
|
2942
2994
|
return { id: messageId };
|
|
2943
2995
|
}
|
|
2944
2996
|
/**
|
|
@@ -2947,7 +2999,12 @@ var ImapAdapter = class {
|
|
|
2947
2999
|
* attachments. See `buildMimeMessage`.
|
|
2948
3000
|
*/
|
|
2949
3001
|
buildDraftMessage(params) {
|
|
2950
|
-
return buildMimeMessage(this.
|
|
3002
|
+
return buildMimeMessage(this.from(), params);
|
|
3003
|
+
}
|
|
3004
|
+
/** IMAP keeps no display name on the server, so the account's name is the
|
|
3005
|
+
* only one there is (see `fromAddress`). */
|
|
3006
|
+
from() {
|
|
3007
|
+
return fromAddress(this.email, void 0, this.accountName);
|
|
2951
3008
|
}
|
|
2952
3009
|
async createDraft(params) {
|
|
2953
3010
|
const client = await this.ensureConnected();
|