Skip to main content
Glama

gmail-read-emails

Retrieve and list emails from Gmail accounts using search queries, label filters, and result limits for email management.

Instructions

Read/list emails from Gmail with optional search query

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryNoGmail search query (e.g., 'is:unread', 'from:example@gmail.com')
maxResultsNoMaximum number of emails to return
labelIdsNoArray of label IDs to filter by

Implementation Reference

  • Main handler function that fetches emails from Gmail API using search query or labels, retrieves metadata, formats to markdown, and returns structured content or error.
    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)
              }`,
            },
          ],
        };
      }
    }
  • Zod schema defining the input parameters for the gmail-read-emails tool: optional query, maxResults (default 10), optional labelIds.
    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)
    Registers the 'gmail-read-emails' tool on the MCP server using the readEmails handler and readEmailsSchema.
    server.tool(
      "gmail-read-emails",
      "Read/list emails from Gmail with optional search query",
      readEmailsSchema.shape,
      async (params) => {
        return await readEmails(params);
      }
    );
  • Helper function to create authenticated Gmail client using environment variables for OAuth2.
    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;
    }
  • Helper function to format the list of retrieved emails into a 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;
    }

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/CaptainCrouton89/maps-mcp'

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