Skip to main content
Glama

get_thread

Read-only

Fetch an email thread by ID with headers, bodies, attachment metadata and SPF/DKIM/DMARC authentication; trim HTML, quoted replies or message count to keep long threads manageable.

Instructions

Fetch a thread by ID: headers, plaintext + HTML bodies, and attachment metadata. WHEN A THREAD IS LONG OR HTML-HEAVY, shrink the answer instead of skipping content: bodies: "text" drops htmlBody and keeps plaintextBody (an HTML-only mail is reduced to text and marked bodyFromHtml: true); bodies: "new" is text without the quoted history at the end of a reply (the trailing > block with its 'On ... wrote:' line, or an Outlook 'Original Message' block) and marks a cut message quotedStripped: true — inline answers between quoted lines, answers below a quote and forwarded messages (recognised by a forwarded-message line or a Fwd/FW/WG subject) are kept whole, except an answer below an Outlook plain-text From/Sent/Subject block, which goes with it; bodies: "none" drops both bodies and keeps everything else, INCLUDING the real attachment list; lastN: 2 returns only the newest two messages, afterMessageId only the messages after one you have already read (both compose: after X, then the last N). The quota cost is the same whatever you keep — Gmail hands over the whole thread, these options only decide how much of it you read. messageCount is always the whole thread and omittedMessages how many the selection left out, so a partial view never passes for the whole; bodies is echoed when it is not full. full defaults to true and should stay true whenever content matters. full: false is a headers-and-labels fetch that does NOT fetch bodies or attachment metadata — the result then omits plaintextBody, htmlBody and attachments entirely and sets metadataOnly: true. full: false together with any bodies is rejected as invalid_input rather than silently ignored. full: false is kept for compatibility but DEPRECATED: use bodies: "none" instead, which costs the same quota and keeps the real attachment list. The fields are omitted rather than empty on purpose: an empty attachment list from a request that never looked is indistinguishable from a message that truly has none, and treating it as 'no attachment' has already nearly caused an invoice to be archived as attachment-less. If search reported hasAttachments: true, or the sender matters, use full: true (any bodies). EVERY MESSAGE CARRIES authentication — SPF/DKIM/DMARC as the RECEIVING server reported them, for answering 'is this mail really from who it says?'. That holds on a full: false fetch too — the metadata request asks for Authentication-Results by name, so checking whether a mail is really from who it says never costs a body. Read dmarc first: it is the only one of the three that ties a passing check to the visible From domain, so spf: pass alone proves nothing about the sender the user sees (a lookalike domain gets that trivially). signedBy/mailedBy/headerFrom name the domains each check actually validated. They do NOT have to match each other or the From address, and a mismatch is not by itself suspicious: a forwarded message legitimately shows the forwarder in mailedBy and returnPath (the envelope sender is rewritten in transit), while headerFrom still names the original sender — which is exactly why dmarc is the result that carries meaning. Read those three as the explanation of a result, not as a test of their own. A message often carries several DKIM signatures (a forwarder or the sender's mail provider re-signs in transit): signedBy is the passing one aligned with the From domain wherever there is one — the one DMARC can pass on — and alsoSignedBy names the other domains whose signature also passed, which is where a forwarder shows. dkimAligned says whether that reported signature belongs to the From domain or a parent or child of it, so false means NO passing signature did; it is absent when that cannot be told without a public-suffix list (two sibling subdomains), so a missing field is not a mismatch. authservId says WHO asserts all this: a message can carry forged Authentication-Results headers of its own, and only Gmail's own report (mx.google.com) is ever read; otherReports counts the reports that were NOT read, and alsoReported lists results that disagree with the ones above. unchecked: true means the message carried no report from Gmail — that is 'nobody looked', NOT 'nothing wrong'; unauthenticated does not imply forged, and authenticated does not imply honest (a phisher can hold a passing DMARC on his own lookalike domain). USE WHEN: reading a thread's content after finding it via search. DO NOT USE: with a message ID — this takes thread IDs. SIDE EFFECTS: none (does not mark as read).

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "threadId": "<threadId>"
    },
    "name": "get_thread"
  }
}

Input Schema

NameRequiredDescriptionDefault
fullNo
lastNNo
bodiesNo
threadIdYes
afterMessageIdNo

Output Schema

NameRequiredDescriptionDefault
bodiesNo
messagesYes
threadIdYes
messageCountYes
metadataOnlyNo
omittedMessagesYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.27.1
    • addedOutput schema / properties / messages / items / properties / authentication / properties / alsoSignedBy
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  2. Changed12 schema fields changedv0.25.0
    • removedInput schema / additionalProperties
      Removed value: -false
    • addedInput schema / properties / afterMessageId
      Added value: +{
      +  "type": "string"
      +}
    • addedInput schema / properties / bodies
      Added value: +{
      +  "enum": [
      +    "full",
      +    "text",
      +    "new",
      +    "none"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / lastN
      Added value: +{
      +  "exclusiveMinimum": 0,
      +  "maximum": 9007199254740991,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / bodies
      Added value: +{
      +  "enum": [
      +    "text",
      +    "new",
      +    "none"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / messageCount
      Added value: +{
      +  "maximum": 9007199254740991,
      +  "minimum": -9007199254740991,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / messages / items / properties / authentication / properties / otherReports / maximum
      Added value: +9007199254740991
    • addedOutput schema / properties / messages / items / properties / authentication / properties / otherReports / minimum
      Added value: +-9007199254740991
    • addedOutput schema / properties / messages / items / properties / bodyFromHtml
      Added value: +{
      +  "const": true,
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / messages / items / properties / quotedStripped
      Added value: +{
      +  "const": true,
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / omittedMessages
      Added value: +{
      +  "maximum": 9007199254740991,
      +  "minimum": -9007199254740991,
      +  "type": "integer"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "threadId",
      -  "messages"
      -]New value: +[
      +  "threadId",
      +  "messageCount",
      +  "omittedMessages",
      +  "messages"
      +]
  3. Changed1 schema field changedv0.23.0
    • addedOutput schema / properties / messages / items / properties / authentication / properties / dkimAligned
      Added value: +{
      +  "type": "boolean"
      +}
  4. Changed2 schema fields changedv0.17.0
    • addedOutput schema / properties / messages / items / properties / authentication
      Added value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "alsoReported": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "authservId": {
      +      "type": "string"
      +    },
      +    "dkim": {
      +      "type": "string"
      +    },
      +    "dmarc": {
      +      "type": "string"
      +    },
      +    "headerFrom": {
      +      "type": "string"
      +    },
      +    "mailedBy": {
      +      "type": "string"
      +    },
      +    "otherReports": {
      +      "type": "integer"
      +    },
      +    "returnPath": {
      +      "type": "string"
      +    },
      +    "signedBy": {
      +      "type": "string"
      +    },
      +    "spf": {
      +      "type": "string"
      +    },
      +    "unchecked": {
      +      "const": true,
      +      "type": "boolean"
      +    }
      +  },
      +  "type": "object"
      +}
    • changedOutput schema / properties / messages / items / required
      Previous value: -[
      -  "id",
      -  "threadId",
      -  "labelIds",
      -  "from",
      -  "to",
      -  "subject",
      -  "date",
      -  "snippet"
      -]New value: +[
      +  "id",
      +  "threadId",
      +  "labelIds",
      +  "from",
      +  "to",
      +  "subject",
      +  "date",
      +  "snippet",
      +  "authentication"
      +]
  5. Changed2 schema fields changedv0.15.1
    • changedOutput schema / properties / messages / items / required
      Previous value: -[
      -  "id",
      -  "threadId",
      -  "labelIds",
      -  "from",
      -  "to",
      -  "subject",
      -  "date",
      -  "snippet",
      -  "plaintextBody",
      -  "htmlBody",
      -  "attachments"
      -]New value: +[
      +  "id",
      +  "threadId",
      +  "labelIds",
      +  "from",
      +  "to",
      +  "subject",
      +  "date",
      +  "snippet"
      +]
    • addedOutput schema / properties / metadataOnly
      Added value: +{
      +  "const": true,
      +  "type": "boolean"
      +}
  6. First observedv0.1.8

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations already declaring readOnlyHint=true, the description adds substantial behavioral context: no side effects, no mark-as-read, equal quota cost across body options, rejection of full=false with bodies, deprecated full=false, field-omission rationale, and detailed authentication-report caveats. Nothing contradicts the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded and the USE WHEN / DO NOT USE / SIDE EFFECTS labels help, but the description is very long for a five-parameter read tool. Much of the detailed SPF/DKIM/DMARC explanation is useful for interpreting results but exceeds what is needed to select and invoke the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the high-complexity body-selection options, authentication fields, output schema, and read-only annotations, the description is complete enough for correct invocation. It explains the major behavioral modes and error cases an agent must understand.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full parameter burden. It explains threadId, full, bodies enum values (full/text/new/none), lastN, and afterMessageId in depth, including composition and rejection behavior for invalid combinations.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb and resource: 'Fetch a thread by ID: headers, plaintext + HTML bodies, and attachment metadata.' It also distinguishes the tool from search by saying to use it after finding a thread via search, and from message-ID tools by noting it takes thread IDs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit usage context ('USE WHEN: reading a thread's content after finding it via search') and an explicit exclusion ('DO NOT USE: with a message ID'). It does not name a specific alternative tool for message-ID reads, so it falls just short of full alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.