# Modify Labels — Gmail

> Add and/or remove labels on one or more Gmail messages in a single call. In Gmail, most inbox-state operations are label mutations under the hood, so this one tool covers archive / trash / untrash / star / unstar / mark-read / mark-unread…

- Key: `gmail-modify-labels`
- Type: Action (Write)
- Version: 0.0.4
- App: Gmail (`gmail`) — https://pipedream.com/apps/gmail.md
- This page (HTML): https://pipedream.com/apps/gmail/actions/modify-labels
- Hints: open-world
- Source: https://github.com/PipedreamHQ/pipedream/blob/master/components/gmail/actions/modify-labels/modify-labels.mjs

## Description

Add and/or remove labels on one or more Gmail messages in a single call. In Gmail, most inbox-state operations are label mutations under the hood, so this one tool covers archive / trash / untrash / star / unstar / mark-read / mark-unread / apply-label / remove-label.

**Use this whenever the user asks you to star, unstar, flag, archive, file, sort, label, tag, categorise, move, trash, delete, restore, or mark mail as read or unread** — there is no separate tool for any of those. Pair it with **Find Emails** to turn a description of the mail ("the invoice from billing", "everything from last week") into the `messageIds` this tool needs. Apply it even when some messages already carry the target state: the operation is idempotent, and the user asked for an outcome, not a diff.

**Do NOT use this to set up filters, rules, or any automation that applies to mail that has not arrived yet.** This tool labels messages that already exist, one batch at a time. Gmail filters, auto-forwarding, and the vacation responder are settings-level features with no action in this set — if the user asks to "automatically label incoming mail", "skip the inbox from now on", or "set up a rule", say so outright rather than gathering criteria you cannot act on, and point them at Gmail's own settings.

⚠️ **Trashing is destructive — confirm before you do it.** Adding `TRASH` removes mail from the mailbox, and nothing in this tool set can permanently delete or restore in bulk beyond untrashing. When the request would trash mail the user did not enumerate individually ("trash everything from X", "clear out this label", "delete the old ones"), first say how many messages match and what they are, and get explicit confirmation. Every other operation here is safely reversible and needs no confirmation.

Common recipes (pass these in `addLabels` / `removeLabels`):
- **Archive** → `removeLabels: ["INBOX"]`
- **Move to trash** → `addLabels: ["TRASH"]`
- **Untrash (restore)** → `removeLabels: ["TRASH"]`, `addLabels: ["INBOX"]`
- **Star** → `addLabels: ["STARRED"]`
- **Unstar** → `removeLabels: ["STARRED"]`
- **Mark read** → `removeLabels: ["UNREAD"]`
- **Mark unread** → `addLabels: ["UNREAD"]`
- **Apply a user label** → `addLabels: ["Clients/Acme"]` (pass the name or the label ID)
- **Apply user label AND archive** → `addLabels: ["Clients/Acme"]`, `removeLabels: ["INBOX"]`

`addLabels` and `removeLabels` accept either raw label IDs (system labels like `INBOX`, `STARRED`, `UNREAD`, `TRASH`) or user-visible label names — names are resolved via **List Labels** before the API call. Use **Create Label** first if you need to apply a brand-new label that doesn't yet exist. [See the documentation](https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.messages/batchModify).

## Props

| Prop | Type | Required | Description |
|---|---|---|---|
| `messageIds` | `string[]` | Yes | Message IDs to modify (up to 1000 per request). Obtain these from Find Emails. |
| `addLabels` | `string[]` | No | Labels to add to every message. Accepts label IDs (e.g. STARRED, INBOX) or user-visible label names (e.g. Clients/Acme) — names are resolved server-side. |
| `removeLabels` | `string[]` | No | Labels to remove from every message. Accepts label IDs or user-visible names. To archive, remove INBOX; to mark read, remove UNREAD. |

## Run it

**MCP**

```ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js"
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"
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 accessToken = await pd.rawAccessToken

const transport = new StreamableHTTPClientTransport(
  new URL("https://remote.mcp.pipedream.net/v3"),
  {
    requestInit: {
      headers: {
        Authorization: `Bearer ${accessToken}`,
        "x-pd-project-id": process.env.PIPEDREAM_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-modify-labels",
  arguments: {
    messageIds: ["Message IDs"],
    addLabels: ["Labels to Add"],
  },
})
```

**TypeScript**

```ts
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-modify-labels",
  externalUserId: "{external_user_id}", // any stable ID for this user in your system
  configuredProps: {
    gmail: { authProvisionId: "apn_xxxxxxx" },
    messageIds: ["Message IDs"],
    addLabels: ["Labels to Add"],
  },
})

console.log(result)
```

**cURL**

```bash
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-modify-labels",
    "configured_props": {
      "gmail": { "authProvisionId": "apn_xxxxxxx" },
      "messageIds": ["Message IDs"],
      "addLabels": ["Labels to Add"]
    }
  }'
```

---

- App: https://pipedream.com/apps/gmail.md · All apps: https://pipedream.com/apps
