send_message
Send Markdown messages to project agents, with optional attachments, then store canonical and inbox/outbox copies in Git for auditable team coordination.
Instructions
Send a Markdown message to one or more recipients and persist canonical and mailbox copies to Git.
Discovery
To discover available agent names for recipients, use: resource://agents/{project_key} Agent names are NOT the same as program names or user names.
What this does
Stores message (and recipients) in the database; updates sender's activity
Writes a canonical
.mdundermessages/YYYY/MM/Writes sender outbox and per-recipient inbox copies
Optionally converts referenced images to WebP and embeds small images inline
Supports explicit attachments via
attachment_pathsin addition to inline references
Parameters
project_key : str
Project identifier (same used with ensure_project/register_agent).
sender_name : str
Must match an agent registered in the project.
to : list[str]
Primary recipients (agent names). At least one of to/cc/bcc must be non-empty.
subject : str
Short subject line that will be visible in inbox/outbox and search results.
body_md : str
GitHub-Flavored Markdown body. Image references can be file paths or data URIs.
cc, bcc : Optional[list[str]]
Additional recipients by name.
attachment_paths : Optional[list[str]]
Extra file paths to include as attachments; will be converted to WebP and stored.
convert_images : Optional[bool]
Overrides server default for image conversion/inlining. If None, server settings apply.
Note: sender attachments_policy "inline"/"file" always forces conversion/inlining.
importance : str
One of {"low","normal","high","urgent"} (free form tolerated; used by filters).
ack_required : bool
If true, recipients should call acknowledge_message after reading.
thread_id : Optional[str]
If provided, message will be associated with an existing thread.
broadcast : bool
If true and to is empty, expand recipients to all registered agents in the
project (excluding the sender). Mutually exclusive with explicit to recipients.
Respects contact_policy settings and is best-effort across contact boundaries:
expanded recipients that are retired, set block_all, or would need contact
approval are skipped rather than blocking the send, and are reported in
broadcast_skipped ([{"agent": name, "reason": ...}]). No contact request
is created for them — request contact explicitly if you want them included.
auto_contact_if_blocked therefore never fires for broadcast-expanded
recipients; it still applies to explicitly named to/cc/bcc names.
topic : Optional[str]
Optional topic tag (max 64 chars). Must start with a letter or digit and may
otherwise contain alphanumerics, '.', '_', or '-' — so beads_rust hierarchical
IDs like br-abc.1 can be used verbatim. Stored on the message for topic-based
filtering via fetch_inbox(topic=...) or fetch_topic().
auto_contact_if_blocked : Optional[bool]
When True (and contact policy blocks delivery to one or more recipients), the
server will attempt to resolve the block automatically:
- If the recipient is already authenticated in the **same MCP session**, run
``macro_contact_handshake(..., auto_accept=True)`` to approve the link in-band.
The current send proceeds normally and the message is delivered.
- Otherwise, fall back to creating a **pending** ``request_contact`` aimed at the
recipient. This call then **fails loud** with ``CONTACT_REQUIRED`` carrying
``auto_contact_requested`` in ``data``. **The message body is not queued** —
once the recipient approves the contact (``respond_contact(..., accept=True)``),
the sender must re-call ``send_message`` to actually deliver the payload.
Defaults to the server-wide ``MESSAGING_AUTO_HANDSHAKE_ON_BLOCK`` setting (true
unless overridden). The pending-request TTL is governed by
``CONTACT_PENDING_TTL_SECONDS`` (default 7 days, separate from the in-session
auto-approval TTL ``CONTACT_AUTO_TTL_SECONDS``).Returns
dict { "deliveries": [ { "project": str, "payload": { ... message payload ... } } ], "count": int }
Edge cases
If no recipients are given, the call fails.
Unknown recipient names fail fast; register them first.
Non-absolute attachment paths are resolved relative to the project archive root.
Do / Don't
Do:
Keep subjects concise and specific (aim for ≤ 80 characters).
Use
thread_id(orreply_message) to keep related discussion in a single thread.Address only relevant recipients; use CC/BCC sparingly and intentionally.
Prefer Markdown links; attach images only when they materially aid understanding. The server auto-converts images to WebP and may inline small images depending on policy.
Don't:
Send large, repeated binaries—reuse prior attachments via
attachment_pathswhen possible.Change topics mid-thread—start a new thread for a new subject.
Broadcast to "all" agents unnecessarily—target just the agents who need to act.
Examples
Simple message:
{"jsonrpc":"2.0","id":"5","method":"tools/call","params":{"name":"send_message","arguments":{
"project_key":"/abs/path/backend","sender_name":"GreenCastle","to":["BlueLake"],
"subject":"Plan for /api/users","body_md":"See below."
}}}Inline image (auto-convert to WebP and inline if small):
{"jsonrpc":"2.0","id":"6a","method":"tools/call","params":{"name":"send_message","arguments":{
"project_key":"/abs/path/backend","sender_name":"GreenCastle","to":["BlueLake"],
"subject":"Diagram","body_md":"","convert_images":true
}}}Explicit attachments:
{"jsonrpc":"2.0","id":"6b","method":"tools/call","params":{"name":"send_message","arguments":{
"project_key":"/abs/path/backend","sender_name":"GreenCastle","to":["BlueLake"],
"subject":"Screenshots","body_md":"Please review.","attachment_paths":["shots/a.png","shots/b.png"]
}}}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | ||
| to | Yes | ||
| bcc | No | ||
| topic | No | ||
| format | No | ||
| body_md | Yes | ||
| subject | Yes | ||
| broadcast | No | ||
| thread_id | No | ||
| importance | No | normal | |
| project_key | Yes | ||
| sender_name | Yes | ||
| ack_required | No | ||
| sender_token | No | ||
| convert_images | No | ||
| attachment_paths | No | ||
| auto_contact_if_blocked | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||