Spaces:
Sleeping
Sleeping
File size: 2,888 Bytes
7dc28be | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | import type { FastMCP } from 'fastmcp';
import { UserError } from 'fastmcp';
import { z } from 'zod';
import { getGmailClient } from '../../clients.js';
import { prepareMimeRequest } from './helpers.js';
export function register(server: FastMCP) {
server.addTool({
name: 'sendEmail',
description:
'Sends a plain-text email from the authenticated Gmail account. Supports cc/bcc and optional threading by passing replyToMessageId (which copies threadId and sets In-Reply-To/References so the reply lands in the same thread).',
parameters: z.strictObject({
to: z
.union([z.string(), z.array(z.string()).min(1)])
.describe('Recipient email address, or an array of recipient email addresses.'),
subject: z.string().describe('Email subject line.'),
body: z.string().describe('Plain-text body of the email.'),
cc: z.array(z.string()).optional().describe('Optional list of Cc recipients.'),
bcc: z.array(z.string()).optional().describe('Optional list of Bcc recipients.'),
replyToMessageId: z
.string()
.optional()
.describe(
'Optional Gmail message ID to reply to. When set, the new email is threaded with the original and uses In-Reply-To/References headers.'
),
}),
execute: async (args, { log }) => {
const gmail = await getGmailClient();
try {
const { raw, threadId, toList } = await prepareMimeRequest(gmail, args);
log.info(
`Sending Gmail message to ${toList.join(', ')}${
args.replyToMessageId ? ` (reply to ${args.replyToMessageId})` : ''
}`
);
const send = await gmail.users.messages.send({
userId: 'me',
requestBody: {
raw,
...(threadId ? { threadId } : {}),
},
});
return JSON.stringify(
{
success: true,
id: send.data.id,
threadId: send.data.threadId,
labelIds: send.data.labelIds ?? [],
to: toList,
subject: args.subject,
message: `Email sent to ${toList.join(', ')}.`,
},
null,
2
);
} catch (error: any) {
log.error(`Error sending Gmail message: ${error.message || error}`);
if (error.code === 401)
throw new UserError(
'Gmail authorization failed. Re-authorize to grant the gmail.modify scope.'
);
if (error.code === 403)
throw new UserError(
'Permission denied. The account does not have permission to send mail via this OAuth client.'
);
if (error.code === 400)
throw new UserError(`Gmail rejected the message: ${error.message || 'Bad request'}`);
throw new UserError(`Failed to send email: ${error.message || 'Unknown error'}`);
}
},
});
}
|