list_threads
Retrieve email conversation threads from your Gmail mailbox, with options to filter by search queries, labels, and other criteria.
Instructions
List threads in the user's mailbox
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| maxResults | No | Maximum number of threads to return | |
| pageToken | No | Page token to retrieve a specific page of results | |
| q | No | Only return threads matching the specified query | |
| labelIds | No | Only return threads with labels that match all of the specified label IDs | |
| includeSpamTrash | No | Include threads from SPAM and TRASH in the results | |
| includeBodyHtml | No | Whether to include the parsed HTML in the return for each body, excluded by default because they can be excessively large |
Implementation Reference
- src/index.ts:763-786 (handler)The handler function for the 'list_threads' tool. It uses handleTool to authenticate and execute the Gmail API call to list threads with the provided parameters, processes each thread's messages by decoding and filtering their payloads if includeBodyHtml is specified, and returns the formatted response.async (params) => { return handleTool(config, async (gmail: gmail_v1.Gmail) => { const { data } = await gmail.users.threads.list({ userId: 'me', ...params }) if (data.threads) { data.threads = data.threads.map(thread => { if (thread.messages) { thread.messages = thread.messages.map(message => { if (message.payload) { message.payload = processMessagePart( message.payload, params.includeBodyHtml ) } return message }) } return thread }) } return formatResponse(data) }) }
- src/index.ts:755-762 (schema)Zod input schema defining parameters for the list_threads tool: maxResults, pageToken, q (search query), labelIds, includeSpamTrash, includeBodyHtml.{ maxResults: z.number().optional().describe("Maximum number of threads to return"), pageToken: z.string().optional().describe("Page token to retrieve a specific page of results"), q: z.string().optional().describe("Only return threads matching the specified query"), labelIds: z.array(z.string()).optional().describe("Only return threads with labels that match all of the specified label IDs"), includeSpamTrash: z.boolean().optional().describe("Include threads from SPAM and TRASH in the results"), includeBodyHtml: z.boolean().optional().describe("Whether to include the parsed HTML in the return for each body, excluded by default because they can be excessively large"), },
- src/index.ts:753-787 (registration)Registration of the 'list_threads' tool on the MCP server, including name, description, input schema, and handler function.server.tool("list_threads", "List threads in the user's mailbox", { maxResults: z.number().optional().describe("Maximum number of threads to return"), pageToken: z.string().optional().describe("Page token to retrieve a specific page of results"), q: z.string().optional().describe("Only return threads matching the specified query"), labelIds: z.array(z.string()).optional().describe("Only return threads with labels that match all of the specified label IDs"), includeSpamTrash: z.boolean().optional().describe("Include threads from SPAM and TRASH in the results"), includeBodyHtml: z.boolean().optional().describe("Whether to include the parsed HTML in the return for each body, excluded by default because they can be excessively large"), }, async (params) => { return handleTool(config, async (gmail: gmail_v1.Gmail) => { const { data } = await gmail.users.threads.list({ userId: 'me', ...params }) if (data.threads) { data.threads = data.threads.map(thread => { if (thread.messages) { thread.messages = thread.messages.map(message => { if (message.payload) { message.payload = processMessagePart( message.payload, params.includeBodyHtml ) } return message }) } return thread }) } return formatResponse(data) }) } )
- src/index.ts:94-108 (helper)Helper function used by list_threads to process message parts: decodes base64 data for non-HTML or specified HTML bodies, recurses on parts, filters headers to specific list.const processMessagePart = (messagePart: MessagePart, includeBodyHtml = false): MessagePart => { if ((messagePart.mimeType !== 'text/html' || includeBodyHtml) && messagePart.body) { messagePart.body = decodedBody(messagePart.body) } if (messagePart.parts) { messagePart.parts = messagePart.parts.map(part => processMessagePart(part, includeBodyHtml)) } if (messagePart.headers) { messagePart.headers = messagePart.headers.filter(header => RESPONSE_HEADERS_LIST.includes(header.name || '')) } return messagePart }