Skip to main content
Glama

modify_labels

Idempotent

Add or remove labels on one or many Gmail threads in a single call. Unknown labels in add are created automatically; archive or mark read by removing INBOX or UNREAD.

Instructions

Add/remove labels on a thread. Archive = remove 'INBOX'; mark read = remove 'UNREAD'. Labels may be given by name or by id: an unknown name in add is created automatically (use '/' for nested labels), an unknown name in remove is ignored. USE WHEN: applying custom labels or label combinations in one call. DO NOT USE: for plain archive/read/unread — the dedicated tools are clearer. Pass threadIds (a list of up to 100) instead of threadId to apply the same change to every listed thread in one call — for 'exactly these threads, as approved'. The answer then reports per thread: changed, failed (with code and message; the others still ran) and notAttempted (the run stopped at a rate limit, dead token or missing scope, which would have hit every remaining thread alike); ok is true only when all were changed. SIDE EFFECTS: changes the thread's labels (and may create a label named in add, once per call even for a list); reversible by the inverse call.

Tool call template

This tool declares no required parameters. Add optional parameters from the input schema as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {},
    "name": "modify_labels"
  }
}

Input Schema

NameRequiredDescriptionDefault
addNo
removeNo
threadIdNo
threadIdsNo

Output Schema

NameRequiredDescriptionDefault
okYes
failedNo
changedNo
notAttemptedNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv0.25.0
    • removedInput schema / additionalProperties
      Removed value: -false
    • addedInput schema / properties / threadIds
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "minItems": 1,
      +  "type": "array"
      +}
    • removedInput schema / required
      Removed value: -[
      -  "threadId"
      -]
    • addedOutput schema / properties / changed
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / failed
      Added value: +{
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "code": {
      +        "type": "string"
      +      },
      +      "message": {
      +        "type": "string"
      +      },
      +      "retryable": {
      +        "type": "boolean"
      +      },
      +      "threadId": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "threadId",
      +      "code",
      +      "message",
      +      "retryable"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / notAttempted
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  2. First observedv0.1.8

TDQS

A4.8/5.0
Behavior5/5

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

Annotations declare readOnlyHint=false, destructiveHint=false and idempotentHint=true, but the description adds substantial context beyond them: label creation as a side effect (once per call even for a list), reversibility by the inverse call, and partial-failure semantics (changed/failed/notAttempted with the reason the run stopped, and ok only when all changed). No claim conflicts with the annotations — nothing described is destructive in the annotation's sense.

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

Conciseness4/5

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

Front-loaded with the core action and the archive/read equivalence before the conditional guidance. Dense but nearly every clause carries operational weight; only the quoted phrase "for 'exactly these threads, as approved'" reads as filler.

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?

There is an output schema, yet the per-thread result contract (changed/failed/notAttempted) is explained where it matters because it describes partial-failure behavior an agent must handle. With four optional params and full annotation coverage, nothing needed to call this correctly is missing.

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

Parameters4/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 burden and largely does: it defines name-vs-id for add/remove, states that unknown names in `add` are created (with '/' for nesting) while unknown names in `remove` are silently ignored, and explains threadId vs threadIds including the 100-item cap and same-change-to-all semantics. It does not cover the empty-array defaults or whether both add and remove can be supplied in one call, which holds it below a 5.

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?

States a specific verb+resource ("Add/remove labels on a thread") and immediately disambiguates the two most likely confusions by defining archive and mark-read in terms of label removal. An agent can distinguish it from archive, mark_read, mark_unread, and create_label from the description alone.

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

Usage Guidelines5/5

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

Explicit "USE WHEN: applying custom labels or label combinations in one call" and "DO NOT USE: for plain archive/read/unread — the dedicated tools are clearer" name both the trigger and the alternatives. The threadIds paragraph adds a second routing rule (single vs multi-thread intent).

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