Skip to main content
Glama

Queue email outreach

queue_email_outreach
Destructive

For single personal emails, use draft_email + send_email.

A campaign already sending without a flow keeps calling this tool without node_id. Every other campaign sends through its flow, even a single email: create it with define_sequence and add the prospects with track_prospects, and the flow's send steps call this tool with their node_id. A call without node_id on an agent that has no flow and hasn't sent any outreach yet is refused.

An agent is required — create one via create_agent if none exists. This tool creates tracking items for the recipients it queues, so don't also call track_prospects for them. Only call this AFTER the user has explicitly confirmed the outreach.

Follow-ups thread on their own. A recipient this agent has already emailed gets a reply in that email's thread, sent from the mailbox that sent it (whatever mailbox says), so one call can mix first emails and follow-ups across mailboxes; write their body as a reply. Everyone else gets a new email from mailbox. If the mailbox that last emailed someone is no longer connected, they get a new email too. Dict with queued_count, follow_up_recipients (the queued recipients sent as replies in their existing thread), skipped items, a preview of the first queued email, first_send_at / last_send_at (see below), and tracking_skipped — recipients already tracked in another campaign, so nothing queued for them. Each entry names existing_agent_title / existing_agent_id; surface these and let the user place them.

This tool QUEUES; it never sends. Nothing has been delivered when it returns — a background beat drains each mailbox in derived order at a human-like pace, minutes to days later. first_send_at / last_send_at are ISO timestamps bounding the projected send window (from the read-time forecast), and awaiting_approval counts rows held for the user's approval. Gated rows are excluded from the window; when every row is gated both bounds are null and nothing is projected until the user approves.

So report queued work as queued, with the window: "Queued 4, first lands 12:02pm, last 12:11pm." Do NOT tell the user these were sent.

Writing a marker into a campaign's own tracker (a sheet, a CRM field) at queue time is fine and is usually what its dedup depends on — skip it and the next run re-queues the same people. But that marker records handoff, not delivery: don't cite it back as proof a send happened, and don't let it turn into "sent" in your summary. For what actually went out, read the queue (manage_email_outreach_queue(action='status')); to act at real send time, the agent needs a sent_email trigger.

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": {
      "recipients": "<recipients>",
      "agent_id": "<agent_id>"
    },
    "name": "queue_email_outreach"
  }
}

Input Schema

NameRequiredDescriptionDefault
enrichNoWhen True, look up each recipient's LinkedIn URL via Apollo (using their `email` plus optional `first_name` / `last_name`) and stamp it on the tracking row. Costs 1 Sliq credit per verified hit (a zero Sliq balance skips the whole lookup); free with BYO Apollo. Recipients whose LinkedIn URL already gives their profile slug, and those missing inputs, are silently skipped. Reverse of `queue_linkedin_outreach(enrich=True)`.
mailboxNoEmail address of a connected mailbox (e.g. 'alice@acme.io') for new emails. Omit to use the user's default mailbox. When the user has multiple mailboxes connected, ask which to use rather than guessing — surfacing the choice is the agent's job, not a silent fallback. For segmented delivery ("first third from A, second from B, last from C"), call this tool once per segment with the segment's recipients and the segment's mailbox. The tool does not rotate across calls; per-call recipient lists are how segmentation is expressed.
node_idNoOptional. The id of the sequence-DAG node this batch enacts (a node in the agent's `sequence`, authored via `define_sequence`). Stamped on every queued row so the Campaign Flow view can place each prospect and count per node. Pass it whenever the agent has a sequence. Rejected with ModelRetry if it isn't a node in the agent's sequence.
agent_idYesRequired. Agent ID to associate with the queued items.
recipientsYesThe people to email, one entry each.
on_behalf_ofNoA teammate's email, or an agency client's from list_agency_clients, to run this call in that account: their agents, settings, connected accounts, and credits. Omit it to act on your own account.
body_templateNoBatch fallback body for recipients without their own `body`. Final literal text, as for a per-recipient `body`. Bodies (this and per-recipient `body`) are Markdown, rendered to HTML at send time for every provider — write hyperlinks as [text](url) so the link reads as its anchor text rather than a raw URL.
subject_templateNoBatch fallback subject for recipients without their own `subject`. Final literal text, as for a per-recipient `subject`.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / on_behalf_of / description
      Previous value: -"An agency client's email, from list_agency_clients, to run this call in that client's account: their agents, settings, connected accounts, and credits. Omit it to act on your own account."New value: +"A teammate's email, or an agency client's from list_agency_clients, to run this call in that account: their agents, settings, connected accounts, and credits. Omit it to act on your own account."
  2. Changed4 schema fields changed
    • removedInput schema / properties / recipients / items / properties / data
      Removed value: -{
      -  "additionalProperties": true,
      -  "description": "Read only for a linkedin_url key, used when the top-level linkedin_url is empty.",
      -  "type": "object"
      -}
    • changedInput schema / properties / recipients / items / properties / linkedin_provider_id / description
      Previous value: -"The recipient's LinkedIn provider id, copied exactly as the tool that surfaced this person returned it. Lands on the prospect's LinkedIn fields with linkedin_url."New value: +"The recipient's LinkedIn provider id, copied exactly as the tool that surfaced this person returned it. Lands on the prospect's LinkedIn fields with linkedin_slug."
    • addedInput schema / properties / recipients / items / properties / linkedin_slug
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "The recipient's LinkedIn profile slug or profile URL. Pass it on mixed-channel campaigns so the tool dedups against an existing LinkedIn-keyed tracking row for this person, and forward find_email's `linkedin_url` here verbatim when it returned one with the email. On a flow email node it binds a just-discovered address to the prospect resting on the node instead of creating a new one."
      +}
    • removedInput schema / properties / recipients / items / properties / linkedin_url
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "default": null,
      -  "description": "The recipient's LinkedIn profile URL. Pass it on mixed-channel campaigns so the tool dedups against an existing LinkedIn-keyed tracking row for this person, and forward it verbatim when find_email returned it with the email. On a flow email node it binds a just-discovered address to the prospect resting on the node instead of creating a new one."
      -}
  3. Changed2 schema fields changed
    • changedInput schema / properties / enrich / description
      Previous value: -"When True, look up each recipient's LinkedIn URL via Apollo (using\ntheir `email` plus optional `first_name` / `last_name`) and stamp it\non the tracking row. Costs 1 Sliq credit per verified hit (a zero\nSliq balance skips the whole lookup); free with BYO Apollo. Recipients\nthat already carry `linkedin_url` and those missing inputs are\nsilently skipped. Reverse of `queue_linkedin_outreach(enrich=True)`."New value: +"When True, look up each recipient's LinkedIn URL via Apollo (using\ntheir `email` plus optional `first_name` / `last_name`) and stamp it\non the tracking row. Costs 1 Sliq credit per verified hit (a zero\nSliq balance skips the whole lookup); free with BYO Apollo. Recipients\nwhose LinkedIn URL already gives their profile slug, and those missing\ninputs, are silently skipped. Reverse of `queue_linkedin_outreach(enrich=True)`."
    • changedInput schema / properties / recipients / items / properties / linkedin_provider_id / description
      Previous value: -"The recipient's LinkedIn provider id, from search_linkedin_people or query_prospects, copied exactly as that tool returned it. Lands on the prospect's LinkedIn fields with linkedin_url."New value: +"The recipient's LinkedIn provider id, copied exactly as the tool that surfaced this person returned it. Lands on the prospect's LinkedIn fields with linkedin_url."
  4. Added

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only supply readOnlyHint=false and destructiveHint=true; the description goes far beyond that by disclosing that the tool only QUEUES and never sends, that a background beat drains mailboxes minutes to days later, how approval gating affects the projected window, and that tracking rows are created and depend on the campaign marker for dedup. It also documents follow-up threading behavior and the stale-mailbox fallback, which no structured field conveys.

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?

The summary leads with the core behavior and the alternatives, and the returns block is justified because no output schema exists. It is nevertheless long and repeats the 'don't claim these were sent' warning in several forms, which costs space without adding new information.

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?

With eight parameters, quotas of side effects, and no output schema, the definition covers everything an agent needs: prerequisites, refusal conditions, the queued-vs-sent distinction, the shape of the return dict including first_send_at/last_send_at and tracking_skipped, and where to go for real send status. Nothing material is left to inference.

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 100%, so the baseline is 3, but the description adds cross-parameter semantics the schema does not: a call can mix first emails and follow-ups across mailboxes because follow-ups go out from the mailbox that last emailed the recipient regardless of the `mailbox` argument. That meaningfully changes how an agent should populate and batch the parameters, though the individual fields are already well documented in the schema.

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 opening sentence names the specific verb and resource ('Queue bulk email outreach') and immediately scopes it as a campaign/batch tool with rate limiting, staggering, and automatic tracking. It explicitly distinguishes itself from draft_email + send_email and from track_prospects, so an agent can separate it from its nearest siblings without reading any schema.

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?

It gives explicit when-to-use routing ('For single personal emails, use draft_email + send_email'), prerequisite setup (create_agent, define_sequence, track_prospects), a gating rule ('Only call this AFTER the user has explicitly confirmed the outreach'), and the exact condition that triggers a refusal (no node_id, no flow, no prior outreach). It also states a negative rule — do not also call track_prospects for these recipients.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources