listEmails
Retrieve and filter emails from Gmail with subject, sender, and body in Markdown format. Supports search queries and optional summarization.
Instructions
List emails from Gmail with subject, sender, and body in Markdown format. Optionally filter and summarize results.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | The search query to filter emails. Use 'in:inbox','in:spam' 'in:unread', 'in:starred', 'in:sent', 'in:all', 'in:category_social', 'in:category_promotions', 'in:category_updates', 'in:category_forums', 'in:primary' or 'in:draft' to filter by label. | in:inbox |
| maxResults | No | The maximum number of emails to retrieve. |
Implementation Reference
- src/index.ts:82-142 (handler)The handler function that executes the listEmails tool logic - fetches messages from Gmail API and parses them.case "listEmails": { if (!GMAIL_API_KEY) { return { content: [{ type: "text", text: "API Key not set." }] }; } try { const { query, maxResults } = request.params.arguments || {}; const queryParam = query ? `?q=${encodeURIComponent(query as string)}&maxResults=${maxResults}` : `?maxResults=${maxResults}`; const messageListResponse = await fetch( `https://gmail.googleapis.com/gmail/v1/users/${GMAIL_USER_ID}/messages${queryParam}`, { headers: { Authorization: `Bearer ${GMAIL_API_KEY}` } } ); if (!messageListResponse.ok) { const errorData = await messageListResponse.json(); const errorMessage = errorData.error?.message || messageListResponse.statusText; return { content: [{ type: "text", text: `Error: ${errorMessage}` }], }; } const messageList = await messageListResponse.json(); if (!messageList.messages) { return { content: [{ type: "text", text: "No messages found." }] }; } const emailMessages = []; for (const message of messageList.messages) { const messageId = message.id; const messageResponse = await fetch( `https://gmail.googleapis.com/gmail/v1/users/${GMAIL_USER_ID}/messages/${messageId}?format=full`, { headers: { Authorization: `Bearer ${GMAIL_API_KEY}` } } ); if (!messageResponse.ok) { const errorData = await messageResponse.json(); const errorMessage = errorData.error?.message || messageResponse.statusText; return { content: [{ type: "text", text: `Error: ${errorMessage}` }], }; } const fullMessage = await messageResponse.json(); emailMessages.push(await parseMessage(fullMessage)); } return { content: [{ type: "text", text: JSON.stringify(emailMessages) }], }; } catch (error: any) { return { content: [{ type: "text", text: `Error: ${error.message}` }] }; } }
- src/index.ts:28-42 (schema)Zod schema defining the input parameters for the listEmails tool (query and maxResults).const ListEmailsSchema = z.object({ query: z .string() .describe( "The search query to filter emails. Use 'in:inbox','in:spam' 'in:unread', 'in:starred', 'in:sent', 'in:all', 'in:category_social', 'in:category_promotions', 'in:category_updates', 'in:category_forums', 'in:primary' or 'in:draft' to filter by label." ) .optional() .default("in:inbox"), maxResults: z .number() .optional() .describe("The maximum number of emails to retrieve.") .default(3), });
- src/index.ts:60-64 (registration)Tool registration in the ListToolsRequestSchema handler, exposing listEmails to MCP clients.name: "listEmails", description: "List emails from Gmail with subject, sender, and body in Markdown format. Optionally filter and summarize results.", inputSchema: zodToJsonSchema(ListEmailsSchema), },
- src/index.ts:258-299 (helper)Helper function used by listEmails to parse Gmail message payload and extract subject, sender, and body.async function parseMessage(message: { payload: { headers: { name: string; value: string }[]; parts: { mimeType: string; body: { data: WithImplicitCoercion<string> } }[]; body: { data: WithImplicitCoercion<string> }; }; id: string; }) { const headers = message.payload.headers; const subject = headers.find( (header: { name: string }) => header.name === "Subject" )?.value; const from = headers.find( (header: { name: string }) => header.name === "From" )?.value; let body = ""; if (message.payload.parts) { const textPart = message.payload.parts.find( (part) => part.mimeType === "text/plain" ); if (textPart) { body = Buffer.from(textPart.body.data, "base64").toString("utf-8"); } else { const htmlPart = message.payload.parts.find( (part) => part.mimeType === "text/html" ); if (htmlPart) { body = Buffer.from(htmlPart.body.data, "base64").toString("utf-8"); } } } else if (message.payload.body.data) { body = Buffer.from(message.payload.body.data, "base64").toString("utf-8"); } return { id: message.id, subject: subject, from: from, body: body, }; }