[BUG] Gmail MCP search_threads: per-thread messages array silently truncated to oldest 5, ignoring query filters

Status Open
Maintainer reply None cached
Activity 1 comment · opened Aug 15, 2026

Summary

The Gmail MCP connector's search_threads tool correctly identifies matching threads (resultCountEstimate is accurate), but the messages array embedded in each returned thread object is unconditionally truncated to the oldest 5 messages (ascending chronological order), regardless of the query's date/recency filters. Messages 6+ (i.e. the most recent activity in the thread) are silently dropped — even when the query is specifically constructed to match only a recent message in that thread.

get_thread (called separately with the same thread ID) returns the full, correct message list with no truncation, confirming this is a search_threads-specific bug rather than a data/indexing issue.

Reproduction

  1. Pick a Gmail thread that has more than 5 total messages.
  2. Call search_threads with a query that should unambiguously match only a recent message in that thread, e.g.:
  • in:sent newer_than:2d
  • in:sent after:2026/08/14
  • Even an exact-phrase search matching text that appears in only one specific (recent) message in the thread.
  1. Observe: resultCountEstimate correctly reports the thread as a match, but the returned thread's messages array contains only the oldest 5 messages of the thread. The message that actually satisfied the query is frequently not present in the array at all.
  2. Call get_thread(threadId, messageFormat: "MINIMAL") (or METADATA_ONLY) for the same thread ID — it returns the complete, correct list of messages, including the ones missing from search_threads.

Concrete example (anonymized data)

  • A real thread with 32 total messages spanning 2026-03-31 to 2026-08-10.
  • search_threads, under several different queries (in:sent newer_than:7d, in:sent newer_than:14d, plain in:sent), always returned only the 5 oldest messages (2026-03-31 through 2026-06-08).
  • get_thread on the same thread ID returned all 32 messages, including the most recent one (2026-08-10), which represents over two months of activity invisible to search_threads.

A smaller example: a thread with 8 total messages, where a query specifically scoped to after: a date matching only the 3 most recent messages still returned the same 5 oldest messages (all older than the query's date filter), with none of the 3 actually-matching messages present.

Additional findings

  • The truncation cap appears to be a hard, fixed limit of exactly 5 messages per thread. Confirmed across multiple threads with true message counts of 4, 5, 6, 7, 8, and 32: threads with ≤5 true messages come back complete; threads with 6+ are always truncated to exactly 5.
  • Truncation is independent of the view parameter (THREAD_VIEW_MINIMAL vs THREAD_VIEW_METADATA_ONLY show the same truncation, just with fewer fields per message).
  • Truncation is independent of pageSize (which only affects the number of threads returned per page, not messages within a thread).
  • Truncation is independent of query narrowness — even a query engineered to match exactly one specific (recent) message in the thread still returns the oldest 5 messages, not the matching one. This suggests the truncation happens after thread-level matching but does not account for which individual messages satisfied the query.
  • There is no alternate field in the search_threads response (e.g. a total-message-count or last-message-timestamp field) that could be used to detect truncation without a follow-up call.

Impact

Any caller that infers "most recent activity" or "which side sent the last message" from search_threads's embedded messages array will silently get stale or backwards-wrong results for any thread with more than 5 total messages — with no error, warning, or indication that data is missing. Re-running the same or a narrower query does not help, since the truncation is independent of the query itself.

Expected behavior

One of:

  • The messages array reflects (or is filtered/sorted to prioritize) the messages that actually satisfy the query's filters, and/or the most recent messages rather than the oldest, or
  • The response includes an explicit total-message-count / has-more indicator so callers can detect truncation without an extra round trip, or
  • Per-thread message pagination is exposed (currently pageToken only paginates the thread list, not messages within a thread).

Workaround (used in the interim)

Callers can treat "exactly 5 messages returned for a thread" as "possibly truncated" (4 or fewer is always accurate, based on our testing) and re-fetch that specific thread via get_thread with messageFormat: "METADATA_ONLY" (cheaper than MINIMAL/FULL_CONTENT, since it doesn't include snippet/subject/body) to confirm the true last message before acting on it. This is only a heuristic since we can't confirm the cap is always exactly 5 in every case.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗