Skip to main content
gmail_move_email files the email that started the task under a label of the connected Gmail mailbox and takes it out of the Inbox, as Gmail’s Move to does: for example Nanonets/In progress when the agent takes an invoice on and Nanonets/Processed when it is done. It changes the mailbox: it adds and removes labels on that one email and creates labels that are missing. It never deletes, trashes or marks anything as spam.

Authentication & enablement

Connect Gmail on the Connectors page. The connection’s gmail.modify permission, which every Gmail connection already grants, covers changing labels; the access token is injected at run time and never visible to the model.
  • Set the tool up as one configured tool per destination, each with a fixed destination_label: for example file_email_in_progress for Nanonets/In progress and file_email_processed for Nanonets/Processed. The agent chooses which one to call, never the label: the tool reads every input from its configured tool when it runs, so nothing in the call can change them, and the bare gmail_move_email refuses to run on its own.
  • The tool reads the address of the mailbox its connection opens and refuses to act when the email arrived at a different one. If the workspace has several Gmail connections, bind each configured tool to the connection of the mailbox the trigger watches.
The tool is off by default; add it to an agent explicitly.

Inputs

All inputs are set on the configured tool, never by the agent, and read from it when the tool runs.
  • destination_label (required): the label, with / between the levels of a nested label, for example Nanonets/Processed. Labels are matched by name, ignoring case, as Gmail does.
  • keep_in_inbox: only add the label and leave the email in the Inbox, as Gmail’s Label as does, default false. Use it for a status that should stay visible, such as Nanonets/In progress.
  • create_missing_labels: create any label on the path that does not exist yet, parent first so Gmail shows it nested, default true. With false, a missing label is refused.
  • remove_labels: labels to take off the email as it is filed. List the status the email leaves (Nanonets/In progress on the tool that files under Nanonets/Processed), so the email carries one status, and the label a New labeled email trigger watches, so filing moves the email out of it. No other label is taken off: a label you did not list, such as a person’s Nanonets/Vendor-A, stays. In the configure dialog, separate several labels with commas; a label whose name contains a comma needs the JSON form, ["Vendors, Inc"]. Matched by name, ignoring case; a label the email does not carry is skipped. Only your own labels: a Gmail system label (see below) is refused.
There is no message input: the tool always acts on the email that started the task, looked up from the task itself. It needs a task a Gmail email trigger started; the trigger records which email that was and the mailbox it arrived at.

Output

  • status is moved, or already_labeled when the email already has the label and nothing else would change; running the tool twice for the same label changes nothing.
  • removed_labels lists what the call took off: the remove_labels the email carried, and Inbox.
  • in_inbox says whether the email is still in the Inbox afterwards.
  • conversation_in_inbox is true when other emails in the same conversation are still in the Inbox: Gmail’s conversation view then still shows the conversation there, although this email left it.
  • created_labels lists labels the call created, if any.
  • The Gmail message id never changes, so replies and later tools keep working with it.

Limits & errors

A refusal comes back to the agent as a limitation: calling the tool again gives the same answer, so the step is not retried. A rate or quota limit, a timeout, a 5xx or a 401 from Gmail is an error and is retried as usual (a 401 is usually an access token that expired in flight; if it keeps failing, reconnect Gmail). So is an email or a label that changed while the call was filing: the retry reads them again, refuses an email that is gone and creates a label that is. Labels created before a failure are left in place and named in the message; the retry uses them.
  • Refused labels: a label a New labeled email trigger watches (see below), and Gmail’s system labels, or a path under one. System labels are the ones Gmail’s label list marks as system, matched by name ignoring case: INBOX, SPAM, TRASH, SENT, DRAFT, STARRED, IMPORTANT, UNREAD, CHAT and the category tabs (CATEGORY_UPDATES and the like). A name Gmail keeps for one of its views, such as Drafts or Snoozed, is refused when Gmail will not create it. Below one of your labels such a name is an ordinary label: Nanonets/Spam is allowed.
  • Up to 5 label levels.
  • “gmail_move_email … does not run on its own” → the agent called the bare tool, which an agent without strict base tools sees beside its configured ones; it changes nothing.
  • “the configured tool sets no destination label” → set destination_label on the configured tool.
  • “this task was started by …, not by a Gmail email trigger” → the task came from a person (in the app or from a chat), an eval run, a schedule, a migration comparison, another agent, an MCP client or the API. An eval run never touches a real mailbox.
  • “this task is a fork of task …” → a fork (Resume from here › Fork into a new task) copies the original task’s starting email, but it is a branch kept for comparison, often on a draft version, so it never files the email. To file it, use Resume from here › Resume in same task on the original task.
  • “this task was not started by a Gmail email” → the task came from another trigger, or was started before the triggering email was recorded.
  • “this tool is connected to …, but the email that started this task arrived at …” → the tool is bound to another mailbox’s connection; nothing was read or changed.
  • “this task does not record which mailbox its email arrived at” → the tool cannot check it is filing in the right mailbox, so it does nothing.
  • “the email that started this task is in the mailbox’s Trash” (or Spam) → someone deleted it, or Gmail filtered it as spam; it is left there and no label is created.
  • “the email that started this task is no longer in the mailbox” → it was deleted for good.
  • A connection without permission to change labels is refused with a request to reconnect Gmail.
  • Only the email that started the task is labeled. In Gmail’s conversation view a conversation stays in the Inbox while any of its emails is there (conversation_in_inbox), so an earlier email in the thread, or a later reply, keeps it visible; those are separate emails the tool does not touch.
  • One email can start tasks for several agents: when a Gmail trigger is linked to more than one agent, or several agents’ triggers watch the same mailbox. Each of those tasks files the same email, so it shows the labels of whichever filed it last. Give the filing tools to one of those agents, or give each agent its own labels (AP/Processed, Intake/Done).
  • “a Gmail “New labeled email” trigger in this workspace watches that label” → adding it would start a task for that trigger’s agents, so the tool refuses; choose a label no trigger watches. Every “New labeled email” trigger on the same mailbox in the workspace counts, enabled or not (a re-enabled trigger picks up labels added while it was off), whether or not an agent is linked to it. A “New email” trigger does not count: it never reacts to labels. Triggers in other workspaces that connect the same mailbox are not checked. An email that already carries the label is not refused: the label is not added again, so the call only takes the email out of the Inbox and its remove_labels.
  • A “New labeled email” trigger re-reads an email carrying its label whenever any label is added to it, by this tool or by a person. It never starts a second task for an email it already started one for, so filing the email that started the task is safe. An email that got the trigger’s label before the trigger existed would start a task: list the trigger’s label in remove_labels to take it off as the email is filed.
  • A New email trigger never reacts to labels, so filing an email, or moving it back into the Inbox by hand, starts no task for it.
  • Billed per call, however many labels it creates.

Agent Instruction Guidance

Call the configured filing tools at the points where the email’s state changes for the people reading the mailbox, for example when the agent takes the email on and when its work is finished. Leave emails the agent will not process in the Inbox: do not call the tool for them. A failed call never blocks the rest of the task; report it and carry on.