Skip to content

read_emails

Read emails from Gmail using service-account delegation. The tool constructs a Gmail search query from the supplied filters and returns matching messages or a count. It is intended for OTP and transactional email retrieval.

See configuration for the integrations file and service-account settings.

Signature

async def read_emails(
    to: str,
    sender: str | None = None,
    subject: str | None = None,
    after: str | None = None,
    *,
    latest: bool = False,
    count: bool = False,
) -> dict

Parameters

Name Type Default Description
to str Required Recipient email address; used as to:{to} in the query. Empty or whitespace-only values are rejected.
sender str \| None None Sender filter, appended as from:{sender}.
subject str \| None None Subject filter, quoted with backslashes and double quotes escaped.
after str \| None None Look-back duration such as 30s, 2m, 5m, 1h or 1d; uses digits followed by s, m, h or d.
latest bool False Request at most one matching email instead of up to ten. Keyword-only in Python.
count bool False Walk all matching result pages and return a count. Takes precedence over latest. Keyword-only in Python.

The query includes in:anywhere. Recipient and sender filters are interpolated without escaping; supply the intended email addresses. Empty optional string filters are treated as omitted. Invalid or overflowing durations return an INVALID: error.

Responses

Success uses status: "ok". Normal mode returns up to ten messages; latest=True requests at most one. Each email contains from, to, subject, date and body.

{
  "status": "ok",
  "data": {
    "emails": [
      {
        "from": "[email protected]",
        "to": "[email protected]",
        "subject": "Your code",
        "date": "Sat, 12 Sep 2026 10:00:00 +0000",
        "body": "Your code is 123456"
      }
    ]
  }
}

Plain-text MIME content is preferred. HTML is converted to plain text and links are rendered as text (url). A failed individual message fetch is logged and skipped; a malformed message body can be returned as an empty string.

Count mode walks all result pages and returns the matching count, including zero:

{
  "status": "ok",
  "data": {
    "count": 0
  }
}

Failures use an error string with a category prefix:

{
  "status": "error",
  "error": "NO_EMAILS_FOUND: no matching emails found"
}
Prefix Meaning
INVALID: Empty recipient or invalid look-back duration.
NOT_CONFIGURED: The integrations file is missing, empty or malformed, or its email configuration is invalid.
API_ERROR: Gmail client creation or an API request failed, or all matched messages failed to fetch.
NO_EMAILS_FOUND: Content mode found no matching messages. Count mode instead returns zero.

For an OTP still in transit, a later call may find the message. The tool does not perform an automatic polling loop. Correct configuration and input errors before retrying.

Scope

The Gmail client requests only https://www.googleapis.com/auth/gmail.readonly. This server exposes no tools to send, delete, modify or mark messages.