Skip to main content
Glama

send_message

Destructive

Send an email (Gmail) or a Slack message from one of the user's connected accounts. Gmail: to reply into a thread pass reply_to_external_id (external_id from a search result) — the reply is REPLY ALL by default (original sender + everyone on the original To and Cc, minus only the sending account — the user's other connected accounts are kept like any participant) and is sent FROM THE ACCOUNT THAT RECEIVED THE THREAD, so omit account for replies; subject and threading are derived too. A to you pass replaces the To line but the original recipients stay on Cc, and a cc you pass is added, never a replacement — recipients are only reduced with reply_mode='sender_only', which you should use only when the user explicitly asks to reply to the sender alone. Naming an account that did not receive the thread is refused unless allow_different_sender=true (only on the user's explicit request). The result reports the actual from / to / cc — tell the user who it went to. For a new mail pass to (address) and subject. Slack: set connector='slack', account=workspace label, to=channel ('#name' or channel id) or 'me' (DM to self); no subject. To reply to a Slack search hit, pass its external_id ('channel_id:ts') as reply_to_external_id — the channel is derived and the reply threads under that message; note the BOT posts, so a message can be searchable before it's replyable — a PUBLIC channel works even without the bot being a member (reconnect if the workspace predates chat:write.public), but a PRIVATE channel always needs the bot invited (/invite) regardless. File attachments (Gmail and Slack): pass attachment_ids (upload_id values staged via upload_attachment) and/or attachment_urls (public http(s) URLs fetched at send time). On Slack the body and the files become ONE post (uploaded as the connecting person when the workspace has the user-token files:write, otherwise as the app); a workspace connected before 2026-08-26 lacks files:write and returns a reconnect hint for attachments only — text-only sends there keep working. The user may have several Gmail accounts or Slack workspaces connected — pass account to pick one (call list_accounts first when unsure). This actually sends — confirm the recipient and body with the user before calling. Gmail needs the send scope (reconnect on a permission error); Slack channel-by-name needs channels:read (use a channel id or reconnect otherwise).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ccNoGmail Cc recipient(s). On a reply these are ADDED to the original Cc — never a replacement.
toNoGmail: recipient address (omit to reply). Slack: '#channel' / channel id / 'me' (DM to self).
bodyYesPlain-text message body.
accountNoAccount/workspace label to send from (see list_accounts). Omit when the user has exactly one for the connector.
subjectNoGmail subject (omit to reply, 元件名に Re: を付ける). Ignored for Slack.
connectorYesConnector to send from ('gmail' or 'slack').
reply_modeNoGmail replies only. 'all' (default) = Reply All: original sender + original To and Cc, minus the sending account. 'sender_only' = add nobody automatically: To = your `to` (else the original sender), Cc = only your `cc`. Use 'sender_only' ONLY when the user explicitly asks to reply to the sender alone.
attachment_idsNoGmail and Slack: upload_id values from upload_attachment to attach (staged uploads expire after 24h). Slack posts the body and the files as ONE message; a workspace connected before 2026-08-26 must be reconnected first (files:write).
attachment_urlsNoGmail and Slack: public http(s) URLs to fetch and attach at send time (15s timeout, 20MB total; private/localhost addresses are refused).
reply_to_external_idNoGmail: thread external_id to reply into (from a search result). Slack: a search hit's external_id ('channel_id:ts') to reply in-thread (channel derived), or a bare ts (then `to` is required).
allow_different_senderNoGmail replies only. A reply is sent from the account that RECEIVED the thread; if `account` names a different one the send is refused (reply_account_mismatch). Set true only when the user explicitly wants to answer from that other account.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Annotations carry only destructiveHint=true, so the description must -- and does -- disclose the full behavior profile: reply-all recipient semantics and sender-account lock, the reply_account_mismatch refusal, Slack bot vs user-token posting, public vs private channel bot requirements, files:write reconnect hints for pre-2026-08-26 workspaces, required scopes (Gmail send, channels:read), and the explicit warning to confirm recipient and body before sending.

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 verb and both connectors, and nearly every sentence carries a distinct operational rule. It is nevertheless a single dense block with no visual structure for a two-connector, 11-parameter tool, which makes it harder to scan than a lightly segmented version would be.

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 no output schema, the description still explains what comes back ('the result reports the actual from / to / cc'). Combined with auth/scope failure guidance and the expiry and size limits for attachments, nothing an agent needs 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 coverage is 100%, so the baseline is 3, but the description adds cross-parameter interplay the schema does not state as such -- omit `account` for replies, `to` replaces the To line while original recipients remain on Cc, `cc` is additive not replacing. These coupling rules genuinely help an agent wire 11 parameters together correctly.

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?

Names a specific verb ('send') and the two resources it serves (Gmail email, Slack message) plus the source constraint ('from one of the user's connected accounts'). The line 'This actually sends' implicitly separates it from send_draft / schedule_message / create_draft, so an agent can tell what this is without opening the schema.

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?

Exceptionally rich conditional guidance: when to omit `account` on replies, when reply_mode='sender_only' is permitted ('only when the user explicitly asks'), when allow_different_sender applies, and when to call list_accounts first. The only gap is that it never names sibling alternatives (send_draft, schedule_message, send_ephemeral_message) to route between them, which is what a 5 would require.

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