Gmail ACTION
Find Emails
q parameter accepts the full Gmail search operator set — combine operators freely: from:alan@ingen.com is:unread newer_than:7d has:attachment subject:"DNA sequences". Common operators: from:, to:, subject:, has:attachment, filename:pdf, is:unread, is:starred, label:INBOX, newer_than:7d, older_than:1m, after:2025/01/01, before:2025/12/31, category:primary. labelIds accepts either raw label IDs (INBOX, STARRED) or user-visible names (Clients/Acme) — names are resolved server-side via List Labels. Each returned message carries id, threadId, labelIds, the decoded subject/sender/recipient/date, and a snippet. With format: "full" the decoded body text and payload.parts[].body.attachmentId + filename + mimeType are also included — feed those into Download Attachment, or feed threadId into Get Thread for the whole conversation. Set fields on every call to name just what you need — message records are large, and a wide search returns tens of thousands of characters that crowd out the rest of the task. id and threadId are always returned. To BROWSE or COUNT, use ["subject", "sender", "date"]. To READ or SUMMARISE — "catch me up", "what did X say about Y", "is there anything I need to reply to" — use ["subject", "sender", "date", "bodyText"]. bodyText is the decoded plain-text body (HTML converted, MIME scaffolding and attachments stripped), about half the size of the raw payload, and requesting it fetches full messages for you. Notification and marketing mail is mostly tracking links: pass includeLinks: false to read it, and keep the default only when you need a URL from the email. Never answer a question about what an email SAYS from snippet — it is a fixed ~200-character prefix, so the sentence you need is usually past its end, and nothing in a snippet indicates that it was cut. Where the snippet is all you asked for and content was likely cut, the message carries snippetTruncated: true. format stays metadata unless you need the raw MIME tree for Download Attachment, in which case pass format: "full" and request payload. Responses are capped. Over the cap: if you named fields, whole messages are dropped rather than your chosen fields being removed, and the note says how many of how many are shown — narrow q and retry. If you named none, messages are compacted instead so counts stay accurate. bodyText shrinks toward a floor before anything is dropped, flagging each cut message with bodyTruncated: true. See the documentation and Gmail search operators.- Action
- Read only
- OAuth
- SDK
- MCP
IMPLEMENTATION
Call this tool
Connect a user's Gmail account once, then configure and run Find Emails from your backend or agent.
import { PipedreamClient } from "@pipedream/sdk"
const pd = new PipedreamClient({
projectId: process.env.PIPEDREAM_PROJECT_ID!,
clientId: process.env.PIPEDREAM_CLIENT_ID!,
clientSecret: process.env.PIPEDREAM_CLIENT_SECRET!,
projectEnvironment: "production",
})
const result = await pd.actions.run({
id: "gmail-find-email",
externalUserId: "{external_user_id}", // any stable ID for this user in your system
configuredProps: {
gmail: { authProvisionId: "apn_xxxxxxx" },
q: "Search Query",
labelIds: ["Label IDs or Names"],
},
})
console.log(result)curl -X POST https://api.pipedream.com/v1/connect/{project_id}/actions/run \
-H "Content-Type: application/json" \
-H "X-PD-Environment: production" \
-H "Authorization: Bearer {access_token}" \
-d '{
"external_user_id": "{external_user_id}",
"id": "gmail-find-email",
"configured_props": {
"gmail": { "authProvisionId": "apn_xxxxxxx" },
"q": "Search Query",
"labelIds": ["Label IDs or Names"]
}
}'// accessToken: mint a short-lived token with the Connect SDK — see the MCP guide
const transport = new StreamableHTTPClientTransport(
new URL("https://remote.mcp.pipedream.net/v3"),
{
requestInit: {
headers: {
Authorization: `Bearer ${accessToken}`,
"x-pd-project-id": "{project_id}",
"x-pd-environment": "production",
"x-pd-external-user-id": "{external_user_id}", // any stable ID for this user in your system
"x-pd-app-slug": "gmail",
},
},
},
)
const mcp = new Client({ name: "my-agent", version: "1.0.0" })
await mcp.connect(transport)
const { tools } = await mcp.listTools()
// listTools() hands your model this tool's input schema, so it can
// fill the arguments itself:
const result = await mcp.callTool({
name: "gmail-find-email",
arguments: {
q: "Search Query",
labelIds: ["Label IDs or Names"],
},
})SCHEMA
Inputs
Pipedream supplies the connected account. Your application provides the operation-specific values below. Dynamic inputs are resolved against that user's account.
| Property | Type | Description |
|---|---|---|
q Search Query | string | Gmail search query using standard search operators. Examples: is:unread newer_than:7d, from:noreply@github.com has:attachment, subject:"Eval-Thread-Test", label:INBOX is:starred. Leave blank to return the most recent messages across the mailbox. Optional |
labelIds Label IDs or Names | string[] | Only return messages that carry all of these labels. Accepts either raw label IDs (e.g. INBOX, STARRED, UNREAD, TRASH, SPAM) or user-visible label names (e.g. Clients/Acme) — names are resolved against List Labels before the request is sent. Optional |
includeSpamTrash Include Spam and Trash | boolean | Include messages from SPAM and TRASH in results. Defaults to false. Optional |
maxResults Max Results | integer | Maximum number of messages to return. Default 25, Gmail API max 500. Lower this for large/busy inboxes to keep responses under the token cap. Optional |
format Format | string | metadata (default) — headers + snippet only, much smaller responses. Use this for every "find", "count", "which" query. full — includes decoded body text and attachment IDs. Use only when you need to read message contents or download an attachment. Optional |
fields Fields | string[] | Return only these fields on each message, instead of the full record. Always set this unless you genuinely need every field — message records are large, and a wide search can return tens of thousands of characters that crowd out the rest of the task. Choose by what you are doing:
Do NOT try to answer a content question from Optional |
bodyChars Body Characters | integer | Maximum characters of bodyText to return per message. Default 2000, which covers a normal one-page email in full. Only applies when bodyText is requested in fields. Any message whose body is cut comes back with bodyTruncated: true and bodyTotalChars (its real length) — re-fetch that single message with a higher limit, or use Get Thread, to read the rest. Raise it for long newsletters or threads; lower it to fit more messages in one response. Optional |
includeLinks Include Links | boolean | Keep link URLs and image URLs in bodyText and in the decoded HTML text of payload. Defaults to true. Set false to read what an email says: links are often most of a newsletter's or notification's text, so their bodies come back several times shorter. Keep true when you need a URL from the email, such as an unsubscribe, approval, or document link. Optional |
REFERENCE
Tool details
Behavior hints are published with the component in the Pipedream registry and surface as MCP tool annotations, so an agent can reason about a tool before it calls it.
- Registry key
- gmail-find-email
- Version
- 0.4.1
- App
- Gmail
- Authentication
- OAuth
- Read-only
- Yes
- Destructive
- No
- Open world
- Yes
- Source
- View on GitHub ↗