gmail-read-emails
Retrieve and filter emails from Gmail using search queries, label IDs, and a customizable number of results. Integrates with the MCP Server Boilerplate for enhanced functionality.
Instructions
Read/list emails from Gmail with optional search query
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| labelIds | No | Array of label IDs to filter by | |
| maxResults | No | Maximum number of emails to return | |
| query | No | Gmail search query (e.g., 'is:unread', 'from:example@gmail.com') |
Implementation Reference
- src/gmail.ts:214-290 (handler)The main handler function for the 'gmail-read-emails' tool. It authenticates with Gmail API, lists messages based on query/label/maxResults, fetches metadata for each, formats into Markdown, and returns as text content.export async function readEmails(params: z.infer<typeof readEmailsSchema>) { try { const auth = createGmailAuth(); const gmail = google.gmail({ version: "v1", auth }); const listParams: any = { userId: "me", maxResults: params.maxResults, }; if (params.query) listParams.q = params.query; if (params.labelIds) listParams.labelIds = params.labelIds; const response = await gmail.users.messages.list(listParams); if (!response.data.messages || response.data.messages.length === 0) { return { content: [ { type: "text" as const, text: "# No Emails Found\n\nNo emails found matching your search criteria.", }, ], }; } // Get detailed information for each message const emailDetails = await Promise.all( response.data.messages .slice(0, params.maxResults) .map(async (message) => { const detail = await gmail.users.messages.get({ userId: "me", id: message.id!, format: "metadata", metadataHeaders: ["From", "To", "Subject", "Date"], }); const headers = detail.data.payload?.headers || []; const getHeader = (name: string) => headers.find((h) => h.name?.toLowerCase() === name.toLowerCase()) ?.value || ""; return { id: message.id, threadId: message.threadId, from: getHeader("From"), to: getHeader("To"), subject: getHeader("Subject"), date: getHeader("Date"), snippet: detail.data.snippet, labelIds: detail.data.labelIds, }; }) ); return { content: [ { type: "text" as const, text: formatEmailListToMarkdown(emailDetails), }, ], }; } catch (error) { return { content: [ { type: "text" as const, text: `Error reading emails: ${ error instanceof Error ? error.message : String(error) }`, }, ], }; } }
- src/gmail.ts:13-30 (schema)Zod schema defining input parameters for the readEmails tool: optional query string, maxResults (1-100, default 10), optional labelIds array.export const readEmailsSchema = z.object({ query: z .string() .optional() .describe( "Gmail search query (e.g., 'is:unread', 'from:example@gmail.com')" ), maxResults: z .number() .min(1) .max(100) .default(10) .describe("Maximum number of emails to return"), labelIds: z .array(z.string()) .optional() .describe("Array of label IDs to filter by"), });
- src/index.ts:191-198 (registration)Registration of the 'gmail-read-emails' tool on the MCP server, using readEmailsSchema and delegating to the readEmails handler.server.tool( "gmail-read-emails", "Read/list emails from Gmail with optional search query", readEmailsSchema.shape, async (params) => { return await readEmails(params); } );
- src/gmail.ts:49-73 (helper)Helper function to format the list of email details into a structured Markdown string for the tool response.function formatEmailListToMarkdown(emails: any[]): string { if (!emails.length) return "No emails found."; let markdown = `# Inbox (${emails.length} emails)\n\n`; emails.forEach((email, index) => { const date = new Date(email.date).toLocaleDateString(); const from = email.from.replace(/[<>]/g, ''); const subject = email.subject || '(No Subject)'; const snippet = email.snippet || ''; markdown += `## ${index + 1}. ${subject}\n`; markdown += `From: ${from} \n`; markdown += `Date: ${date} \n`; markdown += `ID: \`${email.id}\`\n\n`; if (snippet) { markdown += `${snippet}\n\n`; } markdown += `---\n\n`; }); return markdown; }
- src/gmail.ts:134-165 (helper)Helper function to create OAuth2 authentication client for Gmail API using environment variables.function createGmailAuth() { const clientId = process.env.GOOGLE_CLIENT_ID; const clientSecret = process.env.GOOGLE_CLIENT_SECRET; const redirectUri = process.env.GOOGLE_REDIRECT_URI || "http://localhost:3000/oauth2callback"; if (!clientId || !clientSecret) { throw new Error( "GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are required. Run oauth-setup.js to configure." ); } const oauth2Client = new google.auth.OAuth2( clientId, clientSecret, redirectUri ); const accessToken = process.env.GOOGLE_ACCESS_TOKEN; const refreshToken = process.env.GOOGLE_REFRESH_TOKEN; if (!accessToken || !refreshToken) { throw new Error("OAuth2 tokens missing. Run oauth-setup.js to get tokens."); } oauth2Client.setCredentials({ access_token: accessToken, refresh_token: refreshToken, }); return oauth2Client; }