gmcp 0.3.0 → 0.5.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 +4 -2
- package/dist/index.js +360 -160
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -148,7 +148,7 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
|
148
148
|
|
|
149
149
|
## Tools
|
|
150
150
|
|
|
151
|
-
### Gmail (
|
|
151
|
+
### Gmail (17 tools)
|
|
152
152
|
|
|
153
153
|
| Tool | Description |
|
|
154
154
|
|------|-------------|
|
|
@@ -160,6 +160,8 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
|
160
160
|
| `gmcp_gmail_send_email` | Send new email |
|
|
161
161
|
| `gmcp_gmail_reply` | Reply to email in thread |
|
|
162
162
|
| `gmcp_gmail_create_draft` | Create draft message |
|
|
163
|
+
| `gmcp_gmail_delete_email` | Permanently delete email (bypasses trash) |
|
|
164
|
+
| `gmcp_gmail_archive_email` | Archive email (remove from inbox) |
|
|
163
165
|
| `gmcp_gmail_list_labels` | List all labels |
|
|
164
166
|
| `gmcp_gmail_get_label` | Get label details |
|
|
165
167
|
| `gmcp_gmail_create_label` | Create custom label |
|
|
@@ -193,7 +195,7 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
|
193
195
|
|-------|--------|
|
|
194
196
|
| `gmail.readonly` | Read emails and labels |
|
|
195
197
|
| `gmail.send` | Send emails |
|
|
196
|
-
| `gmail.modify` | Read, modify labels |
|
|
198
|
+
| `gmail.modify` | Read, modify labels, delete emails |
|
|
197
199
|
| `gmail.labels` | Manage labels |
|
|
198
200
|
| `gmail.compose` | Create drafts and send |
|
|
199
201
|
| `calendar.readonly` | Read calendars and events |
|
package/dist/index.js
CHANGED
|
@@ -647,6 +647,16 @@ function createGmailClient(auth, logger) {
|
|
|
647
647
|
} catch (error) {
|
|
648
648
|
throw new Error(`Failed to delete label ${labelId}: ${error}`);
|
|
649
649
|
}
|
|
650
|
+
},
|
|
651
|
+
async deleteEmail(messageId) {
|
|
652
|
+
try {
|
|
653
|
+
await gmail.users.messages.delete({
|
|
654
|
+
userId: "me",
|
|
655
|
+
id: messageId
|
|
656
|
+
});
|
|
657
|
+
} catch (error) {
|
|
658
|
+
throw new Error(`Failed to delete message ${messageId}: ${error}`);
|
|
659
|
+
}
|
|
650
660
|
}
|
|
651
661
|
};
|
|
652
662
|
}
|
|
@@ -729,7 +739,7 @@ function registerTools(server, client, tools, logger) {
|
|
|
729
739
|
}
|
|
730
740
|
}
|
|
731
741
|
|
|
732
|
-
// src/tools/
|
|
742
|
+
// src/tools/archive-email.ts
|
|
733
743
|
import json2md from "json2md";
|
|
734
744
|
import { z } from "zod";
|
|
735
745
|
|
|
@@ -765,13 +775,108 @@ function createErrorResponse(context, error, logger) {
|
|
|
765
775
|
};
|
|
766
776
|
}
|
|
767
777
|
|
|
768
|
-
// src/tools/
|
|
769
|
-
var
|
|
770
|
-
|
|
771
|
-
add_labels: z.array(z.string()).optional().describe("Label IDs to add to all messages (e.g., ['STARRED', 'IMPORTANT'])"),
|
|
772
|
-
remove_labels: z.array(z.string()).optional().describe("Label IDs to remove from all messages (e.g., ['UNREAD', 'INBOX'])"),
|
|
778
|
+
// src/tools/archive-email.ts
|
|
779
|
+
var ArchiveEmailInputSchema = z.object({
|
|
780
|
+
message_id: z.string().min(1, "Message ID cannot be empty").describe("The Gmail message ID to archive"),
|
|
773
781
|
output_format: z.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
774
782
|
});
|
|
783
|
+
function archiveToMarkdown(email) {
|
|
784
|
+
const sections = [
|
|
785
|
+
{ h1: "Email Archived Successfully" },
|
|
786
|
+
{ h2: "Message Details" },
|
|
787
|
+
{
|
|
788
|
+
ul: [
|
|
789
|
+
`**Subject:** ${email.subject}`,
|
|
790
|
+
`**From:** ${email.from}`,
|
|
791
|
+
`**Message ID:** ${email.id}`
|
|
792
|
+
]
|
|
793
|
+
},
|
|
794
|
+
{ h2: "Current Labels" },
|
|
795
|
+
{
|
|
796
|
+
p: email.labels.length > 0 ? email.labels.join(", ") : "*No labels on this message*"
|
|
797
|
+
},
|
|
798
|
+
{ h2: "Notes" },
|
|
799
|
+
{
|
|
800
|
+
ul: [
|
|
801
|
+
"The email has been removed from your inbox",
|
|
802
|
+
"The email is still accessible in All Mail",
|
|
803
|
+
"To unarchive, add the INBOX label back to the message"
|
|
804
|
+
]
|
|
805
|
+
}
|
|
806
|
+
];
|
|
807
|
+
return json2md(sections);
|
|
808
|
+
}
|
|
809
|
+
async function archiveEmailTool(gmailClient, params) {
|
|
810
|
+
try {
|
|
811
|
+
const email = await gmailClient.modifyLabels(params.message_id, undefined, [
|
|
812
|
+
"INBOX"
|
|
813
|
+
]);
|
|
814
|
+
const formattedEmail = formatEmailForOutput(email);
|
|
815
|
+
const output = {
|
|
816
|
+
message_id: params.message_id,
|
|
817
|
+
subject: email.subject,
|
|
818
|
+
archived: true,
|
|
819
|
+
removed_labels: ["INBOX"],
|
|
820
|
+
current_labels: email.labels || []
|
|
821
|
+
};
|
|
822
|
+
const textContent = params.output_format === "json" ? JSON.stringify(output, null, 2) : archiveToMarkdown({
|
|
823
|
+
...formattedEmail,
|
|
824
|
+
labels: email.labels || []
|
|
825
|
+
});
|
|
826
|
+
return {
|
|
827
|
+
content: [{ type: "text", text: textContent }],
|
|
828
|
+
structuredContent: output
|
|
829
|
+
};
|
|
830
|
+
} catch (error) {
|
|
831
|
+
return createErrorResponse("archiving email", error);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
var ARCHIVE_EMAIL_DESCRIPTION = `Archive a Gmail email by removing it from the inbox.
|
|
835
|
+
|
|
836
|
+
This tool archives an email message by removing the INBOX label. The email remains accessible in "All Mail" and can be unarchived by adding the INBOX label back.
|
|
837
|
+
|
|
838
|
+
**Parameters**:
|
|
839
|
+
- \`message_id\` (string, required): The Gmail message ID to archive
|
|
840
|
+
- \`output_format\` (string, optional): Output format: "markdown" (default) or "json"
|
|
841
|
+
|
|
842
|
+
**Returns**:
|
|
843
|
+
- \`message_id\`: The archived message ID
|
|
844
|
+
- \`subject\`: Email subject
|
|
845
|
+
- \`archived\`: Always true on success
|
|
846
|
+
- \`removed_labels\`: Labels that were removed (always ["INBOX"])
|
|
847
|
+
- \`current_labels\`: All current labels on the message after archiving
|
|
848
|
+
|
|
849
|
+
**Examples**:
|
|
850
|
+
- Archive email: \`{ "message_id": "18f3c5d4e8a2b1c0" }\`
|
|
851
|
+
- Archive with JSON output: \`{ "message_id": "18f3c5d4e8a2b1c0", "output_format": "json" }\`
|
|
852
|
+
|
|
853
|
+
**Important Notes**:
|
|
854
|
+
- This is a reversible operation - archived emails can be unarchived
|
|
855
|
+
- The email is moved out of the inbox but remains in "All Mail"
|
|
856
|
+
- To unarchive, use \`modify_labels\` with \`add_labels: ["INBOX"]\`
|
|
857
|
+
- This is different from \`delete_email\` which permanently removes the message
|
|
858
|
+
|
|
859
|
+
**Use Cases**:
|
|
860
|
+
- Clean up inbox without deleting emails
|
|
861
|
+
- Archive emails after reading/processing them
|
|
862
|
+
- Remove emails from inbox while keeping them for reference
|
|
863
|
+
|
|
864
|
+
**Error Handling**:
|
|
865
|
+
- Returns error if message ID doesn't exist
|
|
866
|
+
- Returns error if authentication lacks sufficient permissions
|
|
867
|
+
|
|
868
|
+
**Scope Requirements**:
|
|
869
|
+
- Requires \`gmail.modify\` or full \`mail.google.com\` scope`;
|
|
870
|
+
|
|
871
|
+
// src/tools/batch-modify.ts
|
|
872
|
+
import json2md2 from "json2md";
|
|
873
|
+
import { z as z2 } from "zod";
|
|
874
|
+
var BatchModifyInputSchema = z2.object({
|
|
875
|
+
message_ids: z2.array(z2.string()).min(1, "Must provide at least one message ID").max(1000, "Maximum 1000 messages per batch").describe("Array of Gmail message IDs to modify (max 1000)"),
|
|
876
|
+
add_labels: z2.array(z2.string()).optional().describe("Label IDs to add to all messages (e.g., ['STARRED', 'IMPORTANT'])"),
|
|
877
|
+
remove_labels: z2.array(z2.string()).optional().describe("Label IDs to remove from all messages (e.g., ['UNREAD', 'INBOX'])"),
|
|
878
|
+
output_format: z2.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
879
|
+
});
|
|
775
880
|
function batchModificationToMarkdown(messageCount, addedLabels, removedLabels) {
|
|
776
881
|
const sections = [
|
|
777
882
|
{ h1: "Batch Label Modification Successful" },
|
|
@@ -788,7 +893,7 @@ function batchModificationToMarkdown(messageCount, addedLabels, removedLabels) {
|
|
|
788
893
|
sections.push({
|
|
789
894
|
p: `All ${messageCount} messages have been updated successfully.`
|
|
790
895
|
});
|
|
791
|
-
return
|
|
896
|
+
return json2md2(sections);
|
|
792
897
|
}
|
|
793
898
|
async function batchModifyTool(gmailClient, params) {
|
|
794
899
|
try {
|
|
@@ -880,10 +985,10 @@ This tool allows you to efficiently add or remove labels from multiple Gmail mes
|
|
|
880
985
|
- Recommended for operations affecting more than 5 messages`;
|
|
881
986
|
|
|
882
987
|
// src/tools/calendar-create.ts
|
|
883
|
-
import { z as
|
|
988
|
+
import { z as z3 } from "zod";
|
|
884
989
|
|
|
885
990
|
// src/utils/markdown.ts
|
|
886
|
-
import
|
|
991
|
+
import json2md3 from "json2md";
|
|
887
992
|
function emailToJson2md(email) {
|
|
888
993
|
const elements = [
|
|
889
994
|
{ h2: email.subject },
|
|
@@ -925,7 +1030,7 @@ function searchResultsToMarkdown(query, data) {
|
|
|
925
1030
|
});
|
|
926
1031
|
}
|
|
927
1032
|
}
|
|
928
|
-
return
|
|
1033
|
+
return json2md3(elements);
|
|
929
1034
|
}
|
|
930
1035
|
function calendarListToMarkdown(data) {
|
|
931
1036
|
const sections = [
|
|
@@ -951,7 +1056,7 @@ function calendarListToMarkdown(data) {
|
|
|
951
1056
|
sections.push({ ul: details });
|
|
952
1057
|
}
|
|
953
1058
|
}
|
|
954
|
-
return
|
|
1059
|
+
return json2md3(sections);
|
|
955
1060
|
}
|
|
956
1061
|
function formatEventTime(time) {
|
|
957
1062
|
if (time.date) {
|
|
@@ -1018,7 +1123,7 @@ function eventListToMarkdown(data) {
|
|
|
1018
1123
|
sections.push({ hr: "" });
|
|
1019
1124
|
}
|
|
1020
1125
|
}
|
|
1021
|
-
return
|
|
1126
|
+
return json2md3(sections);
|
|
1022
1127
|
}
|
|
1023
1128
|
function formatAttendeeDetailed(att) {
|
|
1024
1129
|
const name = att.display_name || att.email;
|
|
@@ -1066,23 +1171,23 @@ function eventToMarkdown(event, successMessage) {
|
|
|
1066
1171
|
sections.push({ ul: event.attendees.map(formatAttendeeDetailed) });
|
|
1067
1172
|
}
|
|
1068
1173
|
addEventMetadata(sections, event);
|
|
1069
|
-
return
|
|
1174
|
+
return json2md3(sections);
|
|
1070
1175
|
}
|
|
1071
1176
|
|
|
1072
1177
|
// src/tools/calendar-create.ts
|
|
1073
|
-
var CalendarCreateEventInputSchema =
|
|
1074
|
-
calendar_id:
|
|
1075
|
-
summary:
|
|
1076
|
-
start:
|
|
1077
|
-
end:
|
|
1078
|
-
description:
|
|
1079
|
-
location:
|
|
1080
|
-
attendees:
|
|
1081
|
-
timezone:
|
|
1082
|
-
recurrence:
|
|
1083
|
-
add_meet:
|
|
1084
|
-
confirm:
|
|
1085
|
-
output_format:
|
|
1178
|
+
var CalendarCreateEventInputSchema = z3.object({
|
|
1179
|
+
calendar_id: z3.string().default("primary").describe('Calendar ID to create event in (default: "primary")'),
|
|
1180
|
+
summary: z3.string().min(1, "Event title is required").describe("Event title/summary (required)"),
|
|
1181
|
+
start: z3.string().min(1, "Start time is required").describe('Start time: RFC3339 (e.g., "2024-01-15T09:00:00-08:00") or date for all-day (e.g., "2024-01-15")'),
|
|
1182
|
+
end: z3.string().min(1, "End time is required").describe('End time: RFC3339 (e.g., "2024-01-15T10:00:00-08:00") or date for all-day (e.g., "2024-01-15")'),
|
|
1183
|
+
description: z3.string().optional().describe("Event description (optional)"),
|
|
1184
|
+
location: z3.string().optional().describe("Event location (optional)"),
|
|
1185
|
+
attendees: z3.array(z3.string().email()).optional().describe("Array of attendee email addresses (optional)"),
|
|
1186
|
+
timezone: z3.string().optional().describe('IANA timezone (e.g., "America/Los_Angeles", optional)'),
|
|
1187
|
+
recurrence: z3.array(z3.string()).optional().describe('Recurrence rules as RRULE strings (e.g., ["RRULE:FREQ=WEEKLY;COUNT=10"], optional)'),
|
|
1188
|
+
add_meet: z3.boolean().default(false).describe("Auto-create Google Meet conference link (default: false)"),
|
|
1189
|
+
confirm: z3.boolean().default(false).describe("Must be true to create the event (safety check)"),
|
|
1190
|
+
output_format: z3.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
1086
1191
|
});
|
|
1087
1192
|
async function calendarCreateEventTool(calendarClient, params) {
|
|
1088
1193
|
if (!params.confirm) {
|
|
@@ -1233,16 +1338,16 @@ Created event object containing:
|
|
|
1233
1338
|
- Returns error if Calendar API request fails`;
|
|
1234
1339
|
|
|
1235
1340
|
// src/tools/calendar-events.ts
|
|
1236
|
-
import { z as
|
|
1237
|
-
var CalendarEventsInputSchema =
|
|
1238
|
-
calendar_id:
|
|
1239
|
-
time_min:
|
|
1240
|
-
time_max:
|
|
1241
|
-
max_results:
|
|
1242
|
-
query:
|
|
1243
|
-
single_events:
|
|
1244
|
-
order_by:
|
|
1245
|
-
output_format:
|
|
1341
|
+
import { z as z4 } from "zod";
|
|
1342
|
+
var CalendarEventsInputSchema = z4.object({
|
|
1343
|
+
calendar_id: z4.string().default("primary").describe('Calendar ID to list events from (default: "primary")'),
|
|
1344
|
+
time_min: z4.string().optional().describe("Lower bound for event start time (RFC3339, e.g., 2024-01-01T00:00:00Z)"),
|
|
1345
|
+
time_max: z4.string().optional().describe("Upper bound for event start time (RFC3339, e.g., 2024-12-31T23:59:59Z)"),
|
|
1346
|
+
max_results: z4.number().int().min(1).max(250).default(10).describe("Maximum number of events to return (default: 10, max: 250)"),
|
|
1347
|
+
query: z4.string().optional().describe("Free text search query to filter events"),
|
|
1348
|
+
single_events: z4.boolean().default(true).describe("Expand recurring events into individual instances (default: true)"),
|
|
1349
|
+
order_by: z4.enum(["startTime", "updated"]).default("startTime").describe('Sort order: "startTime" (default) or "updated"'),
|
|
1350
|
+
output_format: z4.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
1246
1351
|
});
|
|
1247
1352
|
async function calendarEventsTool(calendarClient, params) {
|
|
1248
1353
|
try {
|
|
@@ -1340,11 +1445,11 @@ This tool retrieves events from a specified calendar with support for time range
|
|
|
1340
1445
|
- Returns empty array if no events match filters`;
|
|
1341
1446
|
|
|
1342
1447
|
// src/tools/calendar-get-event.ts
|
|
1343
|
-
import { z as
|
|
1344
|
-
var CalendarGetEventInputSchema =
|
|
1345
|
-
calendar_id:
|
|
1346
|
-
event_id:
|
|
1347
|
-
output_format:
|
|
1448
|
+
import { z as z5 } from "zod";
|
|
1449
|
+
var CalendarGetEventInputSchema = z5.object({
|
|
1450
|
+
calendar_id: z5.string().default("primary").describe('Calendar ID (default: "primary")'),
|
|
1451
|
+
event_id: z5.string().min(1, "Event ID is required").describe("Event ID to retrieve"),
|
|
1452
|
+
output_format: z5.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
1348
1453
|
});
|
|
1349
1454
|
async function calendarGetEventTool(calendarClient, params) {
|
|
1350
1455
|
try {
|
|
@@ -1436,10 +1541,10 @@ Complete event object containing:
|
|
|
1436
1541
|
- Returns error if Calendar API request fails`;
|
|
1437
1542
|
|
|
1438
1543
|
// src/tools/calendar-list.ts
|
|
1439
|
-
import { z as
|
|
1440
|
-
var CalendarListInputSchema =
|
|
1441
|
-
show_hidden:
|
|
1442
|
-
output_format:
|
|
1544
|
+
import { z as z6 } from "zod";
|
|
1545
|
+
var CalendarListInputSchema = z6.object({
|
|
1546
|
+
show_hidden: z6.boolean().default(false).describe("Include hidden calendars in the results (default: false)"),
|
|
1547
|
+
output_format: z6.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
1443
1548
|
});
|
|
1444
1549
|
async function calendarListTool(calendarClient, params) {
|
|
1445
1550
|
try {
|
|
@@ -1501,16 +1606,16 @@ This tool retrieves all calendars accessible by the authenticated user, includin
|
|
|
1501
1606
|
- Returns error if Calendar API request fails`;
|
|
1502
1607
|
|
|
1503
1608
|
// src/tools/create-draft.ts
|
|
1504
|
-
import
|
|
1505
|
-
import { z as
|
|
1506
|
-
var CreateDraftInputSchema =
|
|
1507
|
-
to:
|
|
1508
|
-
subject:
|
|
1509
|
-
body:
|
|
1510
|
-
content_type:
|
|
1511
|
-
cc:
|
|
1512
|
-
bcc:
|
|
1513
|
-
output_format:
|
|
1609
|
+
import json2md4 from "json2md";
|
|
1610
|
+
import { z as z7 } from "zod";
|
|
1611
|
+
var CreateDraftInputSchema = z7.object({
|
|
1612
|
+
to: z7.email("Must be a valid email address").describe("Recipient email address"),
|
|
1613
|
+
subject: z7.string().min(1, "Subject cannot be empty").describe("Email subject"),
|
|
1614
|
+
body: z7.string().min(1, "Body cannot be empty").describe("Email body content"),
|
|
1615
|
+
content_type: z7.enum(["text/plain", "text/html"]).default("text/plain").describe("Content type: text/plain (default) or text/html for HTML emails"),
|
|
1616
|
+
cc: z7.email("CC must be a valid email address").optional().describe("CC (carbon copy) email address"),
|
|
1617
|
+
bcc: z7.email("BCC must be a valid email address").optional().describe("BCC (blind carbon copy) email address"),
|
|
1618
|
+
output_format: z7.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
1514
1619
|
});
|
|
1515
1620
|
function draftCreatedToMarkdown(params, result) {
|
|
1516
1621
|
const sections = [
|
|
@@ -1530,7 +1635,7 @@ function draftCreatedToMarkdown(params, result) {
|
|
|
1530
1635
|
p: "The draft has been saved and will appear in your Drafts folder. You can edit and send it later from Gmail."
|
|
1531
1636
|
}
|
|
1532
1637
|
];
|
|
1533
|
-
return
|
|
1638
|
+
return json2md4(sections);
|
|
1534
1639
|
}
|
|
1535
1640
|
async function createDraftTool(gmailClient, params) {
|
|
1536
1641
|
try {
|
|
@@ -1624,15 +1729,15 @@ This tool creates a draft email in your Gmail Drafts folder. Unlike sending an e
|
|
|
1624
1729
|
- Collaborative: Others with access can review drafts`;
|
|
1625
1730
|
|
|
1626
1731
|
// src/tools/create-label.ts
|
|
1627
|
-
import
|
|
1628
|
-
import { z as
|
|
1629
|
-
var CreateLabelInputSchema =
|
|
1630
|
-
name:
|
|
1631
|
-
message_list_visibility:
|
|
1632
|
-
label_list_visibility:
|
|
1633
|
-
background_color:
|
|
1634
|
-
text_color:
|
|
1635
|
-
output_format:
|
|
1732
|
+
import json2md5 from "json2md";
|
|
1733
|
+
import { z as z8 } from "zod";
|
|
1734
|
+
var CreateLabelInputSchema = z8.object({
|
|
1735
|
+
name: z8.string().min(1, "Label name cannot be empty").describe("The label name (e.g., 'Work', 'Personal/Family'). Use '/' for nested labels."),
|
|
1736
|
+
message_list_visibility: z8.enum(["show", "hide"]).optional().describe("How label appears in message list. Default: 'show'. Use 'hide' to hide messages with this label from message list."),
|
|
1737
|
+
label_list_visibility: z8.enum(["labelShow", "labelShowIfUnread", "labelHide"]).optional().describe("How label appears in label list. Default: 'labelShow'. Options: 'labelShow' (always visible), 'labelShowIfUnread' (only when unread), 'labelHide' (hidden)."),
|
|
1738
|
+
background_color: z8.string().optional().describe("Background color in hex format (e.g., '#ff0000'). Must provide both background and text color together."),
|
|
1739
|
+
text_color: z8.string().optional().describe("Text color in hex format (e.g., '#ffffff'). Must provide both background and text color together."),
|
|
1740
|
+
output_format: z8.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
1636
1741
|
});
|
|
1637
1742
|
function createdLabelToMarkdown(label) {
|
|
1638
1743
|
const sections = [
|
|
@@ -1669,7 +1774,7 @@ function createdLabelToMarkdown(label) {
|
|
|
1669
1774
|
sections.push({
|
|
1670
1775
|
p: `You can now use this label ID (${label.id}) with other tools like modify_labels or batch_modify.`
|
|
1671
1776
|
});
|
|
1672
|
-
return
|
|
1777
|
+
return json2md5(sections);
|
|
1673
1778
|
}
|
|
1674
1779
|
async function createLabelTool(gmailClient, params) {
|
|
1675
1780
|
try {
|
|
@@ -1760,9 +1865,88 @@ This tool creates a new label with customizable visibility and color settings. L
|
|
|
1760
1865
|
**Scope Requirements**:
|
|
1761
1866
|
- Requires \`gmail.labels\` or \`gmail.modify\` scope`;
|
|
1762
1867
|
|
|
1868
|
+
// src/tools/delete-email.ts
|
|
1869
|
+
import json2md6 from "json2md";
|
|
1870
|
+
import { z as z9 } from "zod";
|
|
1871
|
+
var DeleteEmailInputSchema = z9.object({
|
|
1872
|
+
message_id: z9.string().min(1, "Message ID cannot be empty").describe("The Gmail message ID to permanently delete"),
|
|
1873
|
+
output_format: z9.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
1874
|
+
});
|
|
1875
|
+
function deletionToMarkdown(messageId) {
|
|
1876
|
+
const sections = [
|
|
1877
|
+
{ h1: "Email Deleted Successfully" },
|
|
1878
|
+
{
|
|
1879
|
+
p: `Message with ID **${messageId}** has been permanently deleted from your Gmail account.`
|
|
1880
|
+
},
|
|
1881
|
+
{ h2: "Important Notes" },
|
|
1882
|
+
{
|
|
1883
|
+
ul: [
|
|
1884
|
+
"The email has been permanently deleted (not moved to trash)",
|
|
1885
|
+
"This action cannot be undone",
|
|
1886
|
+
"The email cannot be recovered"
|
|
1887
|
+
]
|
|
1888
|
+
}
|
|
1889
|
+
];
|
|
1890
|
+
return json2md6(sections);
|
|
1891
|
+
}
|
|
1892
|
+
async function deleteEmailTool(gmailClient, params) {
|
|
1893
|
+
try {
|
|
1894
|
+
await gmailClient.deleteEmail(params.message_id);
|
|
1895
|
+
const output = {
|
|
1896
|
+
message_id: params.message_id,
|
|
1897
|
+
deleted: true,
|
|
1898
|
+
message: "Email permanently deleted. This action cannot be undone."
|
|
1899
|
+
};
|
|
1900
|
+
const textContent = params.output_format === "json" ? JSON.stringify(output, null, 2) : deletionToMarkdown(params.message_id);
|
|
1901
|
+
return {
|
|
1902
|
+
content: [{ type: "text", text: textContent }],
|
|
1903
|
+
structuredContent: output
|
|
1904
|
+
};
|
|
1905
|
+
} catch (error) {
|
|
1906
|
+
return createErrorResponse("deleting email", error);
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
var DELETE_EMAIL_DESCRIPTION = `Permanently delete a Gmail email message.
|
|
1910
|
+
|
|
1911
|
+
**WARNING: This is a destructive operation that CANNOT be undone. The email is permanently deleted and bypasses the trash folder.**
|
|
1912
|
+
|
|
1913
|
+
This tool permanently deletes an email message from your Gmail account. Unlike moving to trash, this operation immediately and permanently removes the email.
|
|
1914
|
+
|
|
1915
|
+
**Parameters**:
|
|
1916
|
+
- \`message_id\` (string, required): The Gmail message ID to delete
|
|
1917
|
+
- \`output_format\` (string, optional): Output format: "markdown" (default) or "json"
|
|
1918
|
+
|
|
1919
|
+
**Returns**:
|
|
1920
|
+
- \`message_id\`: The deleted message ID
|
|
1921
|
+
- \`deleted\`: Always true on success
|
|
1922
|
+
- \`message\`: Confirmation message
|
|
1923
|
+
|
|
1924
|
+
**Examples**:
|
|
1925
|
+
- Delete email: \`{ "message_id": "18f3c5d4e8a2b1c0" }\`
|
|
1926
|
+
- Delete with JSON output: \`{ "message_id": "18f3c5d4e8a2b1c0", "output_format": "json" }\`
|
|
1927
|
+
|
|
1928
|
+
**Safety Considerations**:
|
|
1929
|
+
- This is a destructive operation marked with \`destructiveHint: true\`
|
|
1930
|
+
- The email is permanently deleted, not moved to trash
|
|
1931
|
+
- This action cannot be undone - the email cannot be recovered
|
|
1932
|
+
- Consider using \`modify_labels\` with \`add_labels: ["TRASH"]\` if you want recoverable deletion
|
|
1933
|
+
- Use \`get_email\` first to verify which email you're deleting
|
|
1934
|
+
|
|
1935
|
+
**Use Cases**:
|
|
1936
|
+
- Permanently remove sensitive emails
|
|
1937
|
+
- Clean up emails that should not be recoverable
|
|
1938
|
+
- Remove emails that are already in trash permanently
|
|
1939
|
+
|
|
1940
|
+
**Error Handling**:
|
|
1941
|
+
- Returns error if message ID doesn't exist
|
|
1942
|
+
- Returns error if authentication lacks sufficient permissions
|
|
1943
|
+
|
|
1944
|
+
**Scope Requirements**:
|
|
1945
|
+
- Requires \`gmail.modify\` or full \`mail.google.com\` scope`;
|
|
1946
|
+
|
|
1763
1947
|
// src/tools/delete-label.ts
|
|
1764
|
-
import
|
|
1765
|
-
import { z as
|
|
1948
|
+
import json2md7 from "json2md";
|
|
1949
|
+
import { z as z10 } from "zod";
|
|
1766
1950
|
var SYSTEM_LABELS = [
|
|
1767
1951
|
"INBOX",
|
|
1768
1952
|
"SENT",
|
|
@@ -1778,11 +1962,11 @@ var SYSTEM_LABELS = [
|
|
|
1778
1962
|
"CATEGORY_UPDATES",
|
|
1779
1963
|
"CATEGORY_FORUMS"
|
|
1780
1964
|
];
|
|
1781
|
-
var DeleteLabelInputSchema =
|
|
1782
|
-
label_id:
|
|
1783
|
-
output_format:
|
|
1965
|
+
var DeleteLabelInputSchema = z10.object({
|
|
1966
|
+
label_id: z10.string().min(1, "Label ID cannot be empty").describe("The label ID to delete (e.g., 'Label_123'). Cannot delete system labels."),
|
|
1967
|
+
output_format: z10.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
1784
1968
|
});
|
|
1785
|
-
function
|
|
1969
|
+
function deletionToMarkdown2(labelId) {
|
|
1786
1970
|
const sections = [
|
|
1787
1971
|
{ h1: "Label Deleted Successfully" },
|
|
1788
1972
|
{
|
|
@@ -1798,7 +1982,7 @@ function deletionToMarkdown(labelId) {
|
|
|
1798
1982
|
]
|
|
1799
1983
|
}
|
|
1800
1984
|
];
|
|
1801
|
-
return
|
|
1985
|
+
return json2md7(sections);
|
|
1802
1986
|
}
|
|
1803
1987
|
async function deleteLabelTool(gmailClient, params) {
|
|
1804
1988
|
try {
|
|
@@ -1830,7 +2014,7 @@ async function deleteLabelTool(gmailClient, params) {
|
|
|
1830
2014
|
deleted: true,
|
|
1831
2015
|
message: "Label deleted successfully. The label has been removed from all messages."
|
|
1832
2016
|
};
|
|
1833
|
-
const textContent = params.output_format === "json" ? JSON.stringify(output, null, 2) :
|
|
2017
|
+
const textContent = params.output_format === "json" ? JSON.stringify(output, null, 2) : deletionToMarkdown2(params.label_id);
|
|
1834
2018
|
return {
|
|
1835
2019
|
content: [{ type: "text", text: textContent }],
|
|
1836
2020
|
structuredContent: output
|
|
@@ -1920,11 +2104,11 @@ This tool permanently deletes a user-created label from your Gmail account. Syst
|
|
|
1920
2104
|
If you want to hide a label instead of deleting it, consider using the \`update_label\` tool to set \`label_list_visibility\` to "labelHide" instead.`;
|
|
1921
2105
|
|
|
1922
2106
|
// src/tools/get-attachment.ts
|
|
1923
|
-
import { z as
|
|
1924
|
-
var GetAttachmentInputSchema =
|
|
1925
|
-
message_id:
|
|
1926
|
-
attachment_id:
|
|
1927
|
-
output_format:
|
|
2107
|
+
import { z as z11 } from "zod";
|
|
2108
|
+
var GetAttachmentInputSchema = z11.object({
|
|
2109
|
+
message_id: z11.string().min(1, "Message ID cannot be empty").describe("The Gmail message ID containing the attachment"),
|
|
2110
|
+
attachment_id: z11.string().min(1, "Attachment ID cannot be empty").describe("The attachment ID to download (from list_attachments)"),
|
|
2111
|
+
output_format: z11.enum(["base64", "json"]).default("base64").describe("Output format: base64 (default, returns raw base64url string) or json (returns structured object)")
|
|
1928
2112
|
});
|
|
1929
2113
|
async function getAttachmentTool(gmailClient, params) {
|
|
1930
2114
|
try {
|
|
@@ -1991,12 +2175,12 @@ To decode:
|
|
|
1991
2175
|
3. Decode base64url data to get original file content`;
|
|
1992
2176
|
|
|
1993
2177
|
// src/tools/get-email.ts
|
|
1994
|
-
import
|
|
1995
|
-
import { z as
|
|
1996
|
-
var GetEmailInputSchema =
|
|
1997
|
-
message_id:
|
|
1998
|
-
include_body:
|
|
1999
|
-
output_format:
|
|
2178
|
+
import json2md8 from "json2md";
|
|
2179
|
+
import { z as z12 } from "zod";
|
|
2180
|
+
var GetEmailInputSchema = z12.object({
|
|
2181
|
+
message_id: z12.string().min(1, "Message ID cannot be empty").describe("The Gmail message ID to retrieve"),
|
|
2182
|
+
include_body: z12.boolean().default(true).describe("Whether to include full email body in results (default: true)"),
|
|
2183
|
+
output_format: z12.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
2000
2184
|
});
|
|
2001
2185
|
function emailToMarkdown(email) {
|
|
2002
2186
|
const sections = [
|
|
@@ -2023,7 +2207,7 @@ function emailToMarkdown(email) {
|
|
|
2023
2207
|
sections.push({ h2: "Snippet" });
|
|
2024
2208
|
sections.push({ p: email.snippet });
|
|
2025
2209
|
}
|
|
2026
|
-
return
|
|
2210
|
+
return json2md8(sections);
|
|
2027
2211
|
}
|
|
2028
2212
|
async function getEmailTool(gmailClient, params) {
|
|
2029
2213
|
try {
|
|
@@ -2074,11 +2258,11 @@ This tool retrieves a specific email message from Gmail using its unique message
|
|
|
2074
2258
|
- Retrieve email for further processing or analysis`;
|
|
2075
2259
|
|
|
2076
2260
|
// src/tools/get-label.ts
|
|
2077
|
-
import
|
|
2078
|
-
import { z as
|
|
2079
|
-
var GetLabelInputSchema =
|
|
2080
|
-
label_id:
|
|
2081
|
-
output_format:
|
|
2261
|
+
import json2md9 from "json2md";
|
|
2262
|
+
import { z as z13 } from "zod";
|
|
2263
|
+
var GetLabelInputSchema = z13.object({
|
|
2264
|
+
label_id: z13.string().min(1, "Label ID cannot be empty").describe("The label ID to retrieve (e.g., 'INBOX', 'Label_123')"),
|
|
2265
|
+
output_format: z13.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
2082
2266
|
});
|
|
2083
2267
|
function labelToMarkdown(label) {
|
|
2084
2268
|
const sections = [
|
|
@@ -2113,7 +2297,7 @@ function labelToMarkdown(label) {
|
|
|
2113
2297
|
]
|
|
2114
2298
|
});
|
|
2115
2299
|
}
|
|
2116
|
-
return
|
|
2300
|
+
return json2md9(sections);
|
|
2117
2301
|
}
|
|
2118
2302
|
async function getLabelTool(gmailClient, params) {
|
|
2119
2303
|
try {
|
|
@@ -2180,12 +2364,12 @@ This tool retrieves comprehensive details about a label, including its name, typ
|
|
|
2180
2364
|
- System labels and custom labels are both supported`;
|
|
2181
2365
|
|
|
2182
2366
|
// src/tools/get-thread.ts
|
|
2183
|
-
import
|
|
2184
|
-
import { z as
|
|
2185
|
-
var GetThreadInputSchema =
|
|
2186
|
-
thread_id:
|
|
2187
|
-
include_body:
|
|
2188
|
-
output_format:
|
|
2367
|
+
import json2md10 from "json2md";
|
|
2368
|
+
import { z as z14 } from "zod";
|
|
2369
|
+
var GetThreadInputSchema = z14.object({
|
|
2370
|
+
thread_id: z14.string().min(1, "Thread ID cannot be empty").describe("The Gmail thread ID to retrieve"),
|
|
2371
|
+
include_body: z14.boolean().default(false).describe("Whether to include full email body for all messages (default: false)"),
|
|
2372
|
+
output_format: z14.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
2189
2373
|
});
|
|
2190
2374
|
function threadToMarkdown(threadId, messages) {
|
|
2191
2375
|
const sections = [
|
|
@@ -2220,7 +2404,7 @@ function threadToMarkdown(threadId, messages) {
|
|
|
2220
2404
|
sections.push({ p: "---" });
|
|
2221
2405
|
}
|
|
2222
2406
|
}
|
|
2223
|
-
return
|
|
2407
|
+
return json2md10(sections);
|
|
2224
2408
|
}
|
|
2225
2409
|
async function getThreadTool(gmailClient, params) {
|
|
2226
2410
|
try {
|
|
@@ -2278,11 +2462,11 @@ This tool retrieves all messages in a Gmail conversation thread (email chain). T
|
|
|
2278
2462
|
- Extract all messages from a discussion thread`;
|
|
2279
2463
|
|
|
2280
2464
|
// src/tools/list-attachments.ts
|
|
2281
|
-
import
|
|
2282
|
-
import { z as
|
|
2283
|
-
var ListAttachmentsInputSchema =
|
|
2284
|
-
message_id:
|
|
2285
|
-
output_format:
|
|
2465
|
+
import json2md11 from "json2md";
|
|
2466
|
+
import { z as z15 } from "zod";
|
|
2467
|
+
var ListAttachmentsInputSchema = z15.object({
|
|
2468
|
+
message_id: z15.string().min(1, "Message ID cannot be empty").describe("The Gmail message ID to list attachments from"),
|
|
2469
|
+
output_format: z15.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
2286
2470
|
});
|
|
2287
2471
|
function formatBytes(bytes) {
|
|
2288
2472
|
if (bytes === 0) {
|
|
@@ -2314,7 +2498,7 @@ function attachmentsToMarkdown(messageId, attachments) {
|
|
|
2314
2498
|
});
|
|
2315
2499
|
}
|
|
2316
2500
|
}
|
|
2317
|
-
return
|
|
2501
|
+
return json2md11(sections);
|
|
2318
2502
|
}
|
|
2319
2503
|
async function listAttachmentsTool(gmailClient, params) {
|
|
2320
2504
|
try {
|
|
@@ -2372,10 +2556,10 @@ This tool retrieves metadata about all attachments in a specific email message,
|
|
|
2372
2556
|
- List attachment IDs for use with get_attachment tool`;
|
|
2373
2557
|
|
|
2374
2558
|
// src/tools/list-labels.ts
|
|
2375
|
-
import
|
|
2376
|
-
import { z as
|
|
2377
|
-
var ListLabelsInputSchema =
|
|
2378
|
-
output_format:
|
|
2559
|
+
import json2md12 from "json2md";
|
|
2560
|
+
import { z as z16 } from "zod";
|
|
2561
|
+
var ListLabelsInputSchema = z16.object({
|
|
2562
|
+
output_format: z16.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
2379
2563
|
});
|
|
2380
2564
|
function labelsToMarkdown(labels) {
|
|
2381
2565
|
const sections = [{ h1: "Gmail Labels" }];
|
|
@@ -2392,7 +2576,7 @@ function labelsToMarkdown(labels) {
|
|
|
2392
2576
|
if (labels.system.length === 0 && labels.user.length === 0) {
|
|
2393
2577
|
sections.push({ p: "*No labels found*" });
|
|
2394
2578
|
}
|
|
2395
|
-
return
|
|
2579
|
+
return json2md12(sections);
|
|
2396
2580
|
}
|
|
2397
2581
|
async function listLabelsTool(gmailClient, params) {
|
|
2398
2582
|
try {
|
|
@@ -2465,13 +2649,13 @@ Custom labels are created by users for organizing emails. They have IDs like \`L
|
|
|
2465
2649
|
- Returns error if Gmail API is unreachable`;
|
|
2466
2650
|
|
|
2467
2651
|
// src/tools/modify-labels.ts
|
|
2468
|
-
import
|
|
2469
|
-
import { z as
|
|
2470
|
-
var ModifyLabelsInputSchema =
|
|
2471
|
-
message_id:
|
|
2472
|
-
add_labels:
|
|
2473
|
-
remove_labels:
|
|
2474
|
-
output_format:
|
|
2652
|
+
import json2md13 from "json2md";
|
|
2653
|
+
import { z as z17 } from "zod";
|
|
2654
|
+
var ModifyLabelsInputSchema = z17.object({
|
|
2655
|
+
message_id: z17.string().min(1, "Message ID cannot be empty").describe("The Gmail message ID to modify labels for"),
|
|
2656
|
+
add_labels: z17.array(z17.string()).optional().describe("Label IDs to add (e.g., ['STARRED', 'INBOX', 'UNREAD'] or custom label IDs)"),
|
|
2657
|
+
remove_labels: z17.array(z17.string()).optional().describe("Label IDs to remove (e.g., ['UNREAD', 'INBOX'] to mark read and archive)"),
|
|
2658
|
+
output_format: z17.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
2475
2659
|
});
|
|
2476
2660
|
function labelModificationToMarkdown(email, addedLabels, removedLabels) {
|
|
2477
2661
|
const sections = [
|
|
@@ -2497,7 +2681,7 @@ function labelModificationToMarkdown(email, addedLabels, removedLabels) {
|
|
|
2497
2681
|
sections.push({
|
|
2498
2682
|
p: email.labels.length > 0 ? email.labels.join(", ") : "*No labels on this message*"
|
|
2499
2683
|
});
|
|
2500
|
-
return
|
|
2684
|
+
return json2md13(sections);
|
|
2501
2685
|
}
|
|
2502
2686
|
async function modifyLabelsTool(gmailClient, params) {
|
|
2503
2687
|
try {
|
|
@@ -2588,15 +2772,15 @@ This tool allows you to add or remove labels from a Gmail message. Labels are us
|
|
|
2588
2772
|
- Move messages to trash or spam`;
|
|
2589
2773
|
|
|
2590
2774
|
// src/tools/reply.ts
|
|
2591
|
-
import
|
|
2592
|
-
import { z as
|
|
2593
|
-
var ReplyInputSchema =
|
|
2594
|
-
message_id:
|
|
2595
|
-
body:
|
|
2596
|
-
content_type:
|
|
2597
|
-
cc:
|
|
2598
|
-
confirm:
|
|
2599
|
-
output_format:
|
|
2775
|
+
import json2md14 from "json2md";
|
|
2776
|
+
import { z as z18 } from "zod";
|
|
2777
|
+
var ReplyInputSchema = z18.object({
|
|
2778
|
+
message_id: z18.string().min(1, "Message ID cannot be empty").describe("The Gmail message ID to reply to"),
|
|
2779
|
+
body: z18.string().min(1, "Reply body cannot be empty").describe("Reply message body"),
|
|
2780
|
+
content_type: z18.enum(["text/plain", "text/html"]).default("text/plain").describe("Content type: text/plain (default) or text/html for HTML replies"),
|
|
2781
|
+
cc: z18.email("CC must be a valid email address").optional().describe("CC (carbon copy) email address"),
|
|
2782
|
+
confirm: z18.boolean().default(false).describe("Set to true to confirm and send the reply. If false, returns preview only."),
|
|
2783
|
+
output_format: z18.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
2600
2784
|
});
|
|
2601
2785
|
function replyPreviewToMarkdown(originalEmail, replyBody, contentType, cc) {
|
|
2602
2786
|
const sections = [
|
|
@@ -2624,7 +2808,7 @@ function replyPreviewToMarkdown(originalEmail, replyBody, contentType, cc) {
|
|
|
2624
2808
|
{ h2: "Reply Body" },
|
|
2625
2809
|
{ p: replyBody }
|
|
2626
2810
|
];
|
|
2627
|
-
return
|
|
2811
|
+
return json2md14(sections);
|
|
2628
2812
|
}
|
|
2629
2813
|
function replySentToMarkdown(originalEmail, result, cc) {
|
|
2630
2814
|
const sections = [
|
|
@@ -2643,7 +2827,7 @@ function replySentToMarkdown(originalEmail, result, cc) {
|
|
|
2643
2827
|
p: "Your reply has been sent and added to the conversation thread."
|
|
2644
2828
|
}
|
|
2645
2829
|
];
|
|
2646
|
-
return
|
|
2830
|
+
return json2md14(sections);
|
|
2647
2831
|
}
|
|
2648
2832
|
async function replyTool(gmailClient, params) {
|
|
2649
2833
|
try {
|
|
@@ -2767,13 +2951,13 @@ This tool sends a reply to an existing email, automatically threading it in the
|
|
|
2767
2951
|
4. Call with \`confirm: true\` to send`;
|
|
2768
2952
|
|
|
2769
2953
|
// src/tools/search.ts
|
|
2770
|
-
import { z as
|
|
2771
|
-
var SearchEmailsInputSchema =
|
|
2772
|
-
query:
|
|
2773
|
-
max_results:
|
|
2774
|
-
include_body:
|
|
2775
|
-
page_token:
|
|
2776
|
-
output_format:
|
|
2954
|
+
import { z as z19 } from "zod";
|
|
2955
|
+
var SearchEmailsInputSchema = z19.object({
|
|
2956
|
+
query: z19.string().min(1, "Query cannot be empty").describe('Gmail search query using Gmail search syntax (e.g., "from:user@example.com subject:test is:unread")'),
|
|
2957
|
+
max_results: z19.number().int().min(1).max(100).default(10).describe("Maximum number of emails to return (default: 10, max: 100)"),
|
|
2958
|
+
include_body: z19.boolean().default(false).describe("Whether to include full email body in results (default: false)"),
|
|
2959
|
+
page_token: z19.string().optional().describe("Token for pagination to fetch next page of results"),
|
|
2960
|
+
output_format: z19.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
2777
2961
|
});
|
|
2778
2962
|
async function searchEmailsTool(gmailClient, params) {
|
|
2779
2963
|
try {
|
|
@@ -2843,17 +3027,17 @@ This tool allows you to search through your Gmail messages using the same query
|
|
|
2843
3027
|
- Empty results if no emails match the query`;
|
|
2844
3028
|
|
|
2845
3029
|
// src/tools/send-email.ts
|
|
2846
|
-
import
|
|
2847
|
-
import { z as
|
|
2848
|
-
var SendEmailInputSchema =
|
|
2849
|
-
to:
|
|
2850
|
-
subject:
|
|
2851
|
-
body:
|
|
2852
|
-
content_type:
|
|
2853
|
-
cc:
|
|
2854
|
-
bcc:
|
|
2855
|
-
confirm:
|
|
2856
|
-
output_format:
|
|
3030
|
+
import json2md15 from "json2md";
|
|
3031
|
+
import { z as z20 } from "zod";
|
|
3032
|
+
var SendEmailInputSchema = z20.object({
|
|
3033
|
+
to: z20.email("Must be a valid email address").describe("Recipient email address"),
|
|
3034
|
+
subject: z20.string().min(1, "Subject cannot be empty").describe("Email subject"),
|
|
3035
|
+
body: z20.string().min(1, "Body cannot be empty").describe("Email body content"),
|
|
3036
|
+
content_type: z20.enum(["text/plain", "text/html"]).default("text/plain").describe("Content type: text/plain (default) or text/html for HTML emails"),
|
|
3037
|
+
cc: z20.email("CC must be a valid email address").optional().describe("CC (carbon copy) email address"),
|
|
3038
|
+
bcc: z20.email("BCC must be a valid email address").optional().describe("BCC (blind carbon copy) email address"),
|
|
3039
|
+
confirm: z20.boolean().default(false).describe("Set to true to confirm and send the email. If false, returns preview only."),
|
|
3040
|
+
output_format: z20.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
2857
3041
|
});
|
|
2858
3042
|
function emailPreviewToMarkdown(params) {
|
|
2859
3043
|
const sections = [
|
|
@@ -2874,7 +3058,7 @@ function emailPreviewToMarkdown(params) {
|
|
|
2874
3058
|
{ h2: "Body" },
|
|
2875
3059
|
{ p: params.body }
|
|
2876
3060
|
];
|
|
2877
|
-
return
|
|
3061
|
+
return json2md15(sections);
|
|
2878
3062
|
}
|
|
2879
3063
|
function emailSentToMarkdown(params, result) {
|
|
2880
3064
|
const sections = [
|
|
@@ -2894,7 +3078,7 @@ function emailSentToMarkdown(params, result) {
|
|
|
2894
3078
|
p: "The email has been sent and will appear in your Sent folder."
|
|
2895
3079
|
}
|
|
2896
3080
|
];
|
|
2897
|
-
return
|
|
3081
|
+
return json2md15(sections);
|
|
2898
3082
|
}
|
|
2899
3083
|
async function sendEmailTool(gmailClient, params) {
|
|
2900
3084
|
try {
|
|
@@ -3000,8 +3184,8 @@ This tool sends email through your Gmail account. It includes a safety feature:
|
|
|
3000
3184
|
3. Call again with \`confirm: true\` to send`;
|
|
3001
3185
|
|
|
3002
3186
|
// src/tools/update-label.ts
|
|
3003
|
-
import
|
|
3004
|
-
import { z as
|
|
3187
|
+
import json2md16 from "json2md";
|
|
3188
|
+
import { z as z21 } from "zod";
|
|
3005
3189
|
var SYSTEM_LABELS2 = [
|
|
3006
3190
|
"INBOX",
|
|
3007
3191
|
"SENT",
|
|
@@ -3012,14 +3196,14 @@ var SYSTEM_LABELS2 = [
|
|
|
3012
3196
|
"IMPORTANT",
|
|
3013
3197
|
"UNREAD"
|
|
3014
3198
|
];
|
|
3015
|
-
var UpdateLabelInputSchema =
|
|
3016
|
-
label_id:
|
|
3017
|
-
name:
|
|
3018
|
-
message_list_visibility:
|
|
3019
|
-
label_list_visibility:
|
|
3020
|
-
background_color:
|
|
3021
|
-
text_color:
|
|
3022
|
-
output_format:
|
|
3199
|
+
var UpdateLabelInputSchema = z21.object({
|
|
3200
|
+
label_id: z21.string().min(1, "Label ID cannot be empty").describe("The label ID to update (e.g., 'Label_123' or 'INBOX')"),
|
|
3201
|
+
name: z21.string().optional().describe("New label name. Cannot rename system labels. Use '/' for nested labels."),
|
|
3202
|
+
message_list_visibility: z21.enum(["show", "hide"]).optional().describe("How label appears in message list"),
|
|
3203
|
+
label_list_visibility: z21.enum(["labelShow", "labelShowIfUnread", "labelHide"]).optional().describe("How label appears in label list (sidebar)"),
|
|
3204
|
+
background_color: z21.string().optional().describe("Background color in hex format (e.g., '#ff0000'). Must provide both background and text color together."),
|
|
3205
|
+
text_color: z21.string().optional().describe("Text color in hex format (e.g., '#ffffff'). Must provide both background and text color together."),
|
|
3206
|
+
output_format: z21.enum(["markdown", "json"]).default("markdown").describe("Output format: markdown (default) or json")
|
|
3023
3207
|
});
|
|
3024
3208
|
function updatedLabelToMarkdown(label, updates) {
|
|
3025
3209
|
const sections = [
|
|
@@ -3067,7 +3251,7 @@ function updatedLabelToMarkdown(label, updates) {
|
|
|
3067
3251
|
]
|
|
3068
3252
|
});
|
|
3069
3253
|
}
|
|
3070
|
-
return
|
|
3254
|
+
return json2md16(sections);
|
|
3071
3255
|
}
|
|
3072
3256
|
async function updateLabelTool(gmailClient, params) {
|
|
3073
3257
|
try {
|
|
@@ -3337,6 +3521,22 @@ async function startServer() {
|
|
|
3337
3521
|
inputSchema: DeleteLabelInputSchema,
|
|
3338
3522
|
annotations: DESTRUCTIVE_ANNOTATIONS,
|
|
3339
3523
|
handler: deleteLabelTool
|
|
3524
|
+
},
|
|
3525
|
+
{
|
|
3526
|
+
name: "gmcp_gmail_delete_email",
|
|
3527
|
+
title: "Delete Gmail Email",
|
|
3528
|
+
description: DELETE_EMAIL_DESCRIPTION,
|
|
3529
|
+
inputSchema: DeleteEmailInputSchema,
|
|
3530
|
+
annotations: DESTRUCTIVE_ANNOTATIONS,
|
|
3531
|
+
handler: deleteEmailTool
|
|
3532
|
+
},
|
|
3533
|
+
{
|
|
3534
|
+
name: "gmcp_gmail_archive_email",
|
|
3535
|
+
title: "Archive Gmail Email",
|
|
3536
|
+
description: ARCHIVE_EMAIL_DESCRIPTION,
|
|
3537
|
+
inputSchema: ArchiveEmailInputSchema,
|
|
3538
|
+
annotations: MODIFY_ANNOTATIONS,
|
|
3539
|
+
handler: archiveEmailTool
|
|
3340
3540
|
}
|
|
3341
3541
|
];
|
|
3342
3542
|
const calendarTools = [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gmcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "GMCP Server for Google Workspace with OAuth2 authentication",
|
|
5
5
|
"module": "src/index.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -50,19 +50,19 @@
|
|
|
50
50
|
"googleapis": "^170.1.0",
|
|
51
51
|
"json2md": "^2.0.3",
|
|
52
52
|
"kleur": "^4.1.5",
|
|
53
|
-
"pino": "^
|
|
54
|
-
"pino-pretty": "^13.
|
|
53
|
+
"pino": "^10.3.0",
|
|
54
|
+
"pino-pretty": "^13.1.3",
|
|
55
55
|
"zod": "^4.3.6"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@biomejs/biome": "2.3.
|
|
58
|
+
"@biomejs/biome": "2.3.13",
|
|
59
59
|
"@changesets/changelog-github": "^0.5.2",
|
|
60
60
|
"@changesets/cli": "^2.29.8",
|
|
61
61
|
"@types/bun": "latest",
|
|
62
62
|
"@types/json2md": "^1.5.4",
|
|
63
63
|
"bunup": "^0.16.20",
|
|
64
|
-
"lefthook": "^2.0.
|
|
65
|
-
"ultracite": "7.
|
|
64
|
+
"lefthook": "^2.0.16",
|
|
65
|
+
"ultracite": "7.1.1",
|
|
66
66
|
"vitest": "^4.0.18"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|