Skip to main content
Glama
readEmails.ts4.94 kB
import { google } from "googleapis"; interface ReadEmailsArgs { limit: number; folder: string; unreadOnly: boolean; } interface EmailMessage { id: string; threadId: string; from: string; to: string; subject: string; snippet: string; date: string; isUnread: boolean; body?: string; } function getGmailConfig() { return { clientId: process.env.GMAIL_CLIENT_ID!, clientSecret: process.env.GMAIL_CLIENT_SECRET!, refreshToken: process.env.GMAIL_REFRESH_TOKEN!, accessToken: process.env.GMAIL_ACCESS_TOKEN, }; } async function getGmailClient() { const config = getGmailConfig(); if (!config.clientId || !config.clientSecret || !config.refreshToken) { throw new Error("Gmail configuration missing. Please set GMAIL_CLIENT_ID, GMAIL_CLIENT_SECRET, and GMAIL_REFRESH_TOKEN"); } const oauth2Client = new google.auth.OAuth2( config.clientId, config.clientSecret ); oauth2Client.setCredentials({ refresh_token: config.refreshToken, access_token: config.accessToken, }); return google.gmail({ version: "v1", auth: oauth2Client }); } function parseEmailHeaders(headers: any[]): { from: string; to: string; subject: string; date: string } { const result = { from: "", to: "", subject: "", date: "" }; for (const header of headers) { switch (header.name.toLowerCase()) { case "from": result.from = header.value; break; case "to": result.to = header.value; break; case "subject": result.subject = header.value; break; case "date": result.date = header.value; break; } } return result; } function extractEmailBody(payload: any): string { if (payload.body?.data) { return Buffer.from(payload.body.data, "base64").toString("utf-8"); } if (payload.parts) { for (const part of payload.parts) { if (part.mimeType === "text/plain" && part.body?.data) { return Buffer.from(part.body.data, "base64").toString("utf-8"); } } // If no plain text, try HTML for (const part of payload.parts) { if (part.mimeType === "text/html" && part.body?.data) { return Buffer.from(part.body.data, "base64").toString("utf-8"); } } } return ""; } export function createReadEmailsTool() { return async (args: ReadEmailsArgs) => { try { const gmail = await getGmailClient(); // Build query let query = ""; if (args.folder !== "INBOX") { query += `in:${args.folder}`; } if (args.unreadOnly) { query += query ? " is:unread" : "is:unread"; } // Get message list const messagesResponse = await gmail.users.messages.list({ userId: "me", q: query || undefined, maxResults: args.limit, }); const messages = messagesResponse.data.messages || []; const emails: EmailMessage[] = []; // Get details for each message for (const message of messages) { if (!message.id) continue; const messageDetail = await gmail.users.messages.get({ userId: "me", id: message.id, }); const payload = messageDetail.data.payload; if (!payload?.headers) continue; const headers = parseEmailHeaders(payload.headers); const body = extractEmailBody(payload); const isUnread = messageDetail.data.labelIds?.includes("UNREAD") || false; emails.push({ id: message.id, threadId: messageDetail.data.threadId || "", from: headers.from, to: headers.to, subject: headers.subject, snippet: messageDetail.data.snippet || "", date: headers.date, isUnread, body: body.length > 1000 ? body.substring(0, 1000) + "..." : body, }); } const resultText = emails.length > 0 ? `📧 Found ${emails.length} email(s):\n\n` + emails.map((email, index) => `${index + 1}. ${email.isUnread ? "🔵 " : ""}**${email.subject}**\n` + ` From: ${email.from}\n` + ` Date: ${email.date}\n` + ` Snippet: ${email.snippet}\n` + ` Message ID: ${email.id}\n` + (email.body ? ` Body Preview: ${email.body.substring(0, 200)}...\n` : "") + ` ---\n` ).join("\n") : `📭 No emails found in ${args.folder}${args.unreadOnly ? " (unread only)" : ""}`; return { content: [ { type: "text", text: resultText, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "Unknown error occurred"; return { content: [ { type: "text", text: `❌ Failed to read emails: ${errorMessage}`, }, ], }; } }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/guangxiangdebizi/email-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server