Skip to main content
Glama

send_message

Sends Markdown coordination messages to named agents in the same project, with idempotency and delivery observations, for handoffs, results, blockers, or resource notices.

Instructions

Send a Markdown message to named agents in the same project. An unregistered, retired or closed recipient fails the whole send with persisted:false and a reason. Bound source loss also rejects. Returns the stored message and delivery observations/warnings; unknown standalone state is not proof of death. Storage is not task acceptance. To answer a message, use reply_message, which keeps the thread and addresses the sender. Without idempotency_key, a retry sends another message; reuse a nonempty key with identical arguments within 7 days to replay its stored result instead; delivery observations on replay are historical. Alternatively provide resource_notice instead of subject/body_md: one recipient, a nonempty idempotency key, no free-text or delivery overrides. Released/cancelled notices generate readable text; next_action:none stays quiet, other allowed actions wake the dependent receiver. Claimed release is not admission or permission. Send only when the recipient needs to act or know: a handoff, requested result, blocker or shared-resource change. Make clear to the human and receiver whether the message informs or requests work; for requests, name the action, repository and owner. Distinguish implementing source, installing an update and adding guidance. Write coordination messages in Markdown. Open with the action, decision or changed result. Add up to three short facts the receiver needs, then a Next action line naming the requested action or stating No action requested. Link supporting records on an Evidence line; omit that line when no record exists. Keep the requested action, authority, scope and essential holds inline. Put logs, metrics, hashes, execution details and authorization history in the linked records. When a decision depends on those details, ask the receiver to inspect the record. Preserve exact identifiers, paths and commands. Use spaces between words and numbers. Under T3 Code, refer to another agent by its thread link, title, not its registered name; use the name only if the user asks, no thread id is known or T3 fails. Elsewhere include its verified session title or repository beside its name; use this session for the current receiver only after matching session identity. For relayed authorization, preserve the source, exact selected action and target owner; a relayed bare approval such as "B" or "go" is ambiguous. Contact only still-dependent resource owners, sending release or cancellation before dropping waiting recipients. For resource coordination, name only the resource, finite phase boundary and receiver action; omit unrelated progress and errors. Use resource_notice for typed release/cancellation mail; it generates readable text and derives quiet or actionable delivery. Use one supported transport per recipient and purpose; uncertain delivery is not a reason to resend by another route. Keep routine progress in your own conversation; do not send courtesy acknowledgements or reply to thanks.

Input Schema

NameRequiredDescriptionDefault
ccNoRecipients copied, visible to everyone.
toYesRecipient agent names in this project.
bccNoRecipients the others do not see.
topicNoA label fetch_inbox can filter on.
body_mdNoThe message body, in Markdown.
subjectNoOne line, shown in inbox listings.
thread_idNoA thread to join. reply_message sets it for you.
importanceNolow, normal (default), high or urgent.
project_keyYesAbsolute path of the repository's primary checkout.
sender_nameYesYour registered agent name.
ack_requiredNoAsk recipients to call acknowledge_message.
delivery_policyNochecked (default) or durable. Both currently admit and store mail the same way. Neither bypasses closed T3 or unavailable bound sources. Unqualified standalone state remains unknown and is returned with warnings; storage does not transfer task ownership.
idempotency_keyNoNonempty key for this tool and agent. Identical arguments replay with idempotent_replay:true; different arguments fail with IDEMPOTENCY_KEY_CONFLICT. Cleanup runs at server startup and hourly, removing keys older than 7 days. Retries can replay until removal; afterward a retry may perform the operation again.
resource_noticeNoResource release or dependency cancellation. Exactly four fields: resource_id and phase_id are opaque ASCII identifiers (1..96 characters, starting with a letter/digit, then letters/digits/_.:-). released allows none or retry_admission; cancelled allows none or drop_dependency. Only request an action from a receiver with that dependency. Identifiers and receipts do not prove release or grant permission.
notification_policyNowake permits automatic inbox hints. quiet stores normal/low mail for inbox/search without waking the recipient; high/urgent importance or ack_required:true rejects. Omitted policy defaults to quiet only for normal/low, acknowledgement-free mail when every recipient has a valid registered T3 thread ID; otherwise wake. Ping probes keep wake by default. Replies use this same rule, not the original policy. Set wake explicitly for actionable handoffs, requested results and blockers.

Output Schema

NameRequiredDescriptionDefault
ccYes
idYes
toYes
bccYes
fromYes
topicYes
body_mdYes
subjectYes
deliveryNo
revisionNo
sender_idYes
thread_idYes
created_tsYes
importanceYes
project_idYes
ack_requiredYes
sender_locationYes
idempotent_replayNo
notification_policyNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv0.3.1
    • addedInput schema / oneOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "resource_notice"
      +      ]
      +    },
      +    "required": [
      +      "subject",
      +      "body_md"
      +    ]
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "idempotency_key": {
      +        "pattern": "\\S",
      +        "type": "string"
      +      },
      +      "project_key": {},
      +      "resource_notice": {},
      +      "sender_name": {},
      +      "thread_id": {},
      +      "to": {
      +        "items": {
      +          "pattern": "\\S",
      +          "type": "string"
      +        },
      +        "maxItems": 1,
      +        "minItems": 1,
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "resource_notice",
      +      "idempotency_key"
      +    ]
      +  }
      +]
    • changedInput schema / properties / idempotency_key / description
      Previous value: -"Nonempty key for this tool and agent. Identical arguments replay with idempotent_replay:true; different arguments fail with IDEMPOTENCY_KEY_CONFLICT. Hourly cleanup removes keys older than 7 days. Retries can replay until removal; afterward a retry may perform the operation again."New value: +"Nonempty key for this tool and agent. Identical arguments replay with idempotent_replay:true; different arguments fail with IDEMPOTENCY_KEY_CONFLICT. Cleanup runs at server startup and hourly, removing keys older than 7 days. Retries can replay until removal; afterward a retry may perform the operation again."
    • addedInput schema / properties / notification_policy
      Added value: +{
      +  "description": "wake permits automatic inbox hints. quiet stores normal/low mail for inbox/search without waking the recipient; high/urgent importance or ack_required:true rejects. Omitted policy defaults to quiet only for normal/low, acknowledgement-free mail when every recipient has a valid registered T3 thread ID; otherwise wake. Ping probes keep wake by default. Replies use this same rule, not the original policy. Set wake explicitly for actionable handoffs, requested results and blockers.",
      +  "enum": [
      +    "wake",
      +    "quiet"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / resource_notice
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Resource release or dependency cancellation. Exactly four fields: resource_id and phase_id are opaque ASCII identifiers (1..96 characters, starting with a letter/digit, then letters/digits/_.:-). released allows none or retry_admission; cancelled allows none or drop_dependency. Only request an action from a receiver with that dependency. Identifiers and receipts do not prove release or grant permission.",
      +  "oneOf": [
      +    {
      +      "properties": {
      +        "next_action": {
      +          "enum": [
      +            "none",
      +            "retry_admission"
      +          ]
      +        },
      +        "state": {
      +          "const": "released"
      +        }
      +      }
      +    },
      +    {
      +      "properties": {
      +        "next_action": {
      +          "enum": [
      +            "none",
      +            "drop_dependency"
      +          ]
      +        },
      +        "state": {
      +          "const": "cancelled"
      +        }
      +      }
      +    }
      +  ],
      +  "properties": {
      +    "next_action": {
      +      "enum": [
      +        "none",
      +        "retry_admission",
      +        "drop_dependency"
      +      ],
      +      "type": "string"
      +    },
      +    "phase_id": {
      +      "maxLength": 96,
      +      "minLength": 1,
      +      "not": {
      +        "pattern": "\\s"
      +      },
      +      "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]*$",
      +      "type": "string"
      +    },
      +    "resource_id": {
      +      "maxLength": 96,
      +      "minLength": 1,
      +      "not": {
      +        "pattern": "\\s"
      +      },
      +      "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]*$",
      +      "type": "string"
      +    },
      +    "state": {
      +      "enum": [
      +        "released",
      +        "cancelled"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "resource_id",
      +    "phase_id",
      +    "state",
      +    "next_action"
      +  ],
      +  "type": "object"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "project_key",
      -  "sender_name",
      -  "to",
      -  "subject",
      -  "body_md"
      -]New value: +[
      +  "project_key",
      +  "sender_name",
      +  "to"
      +]
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "additionalProperties": false,
      +  "anyOf": [
      +    {
      +      "required": [
      +        "delivery",
      +        "revision",
      +        "notification_policy"
      +      ]
      +    },
      +    {
      +      "properties": {
      +        "idempotent_replay": {
      +          "const": true
      +        }
      +      },
      +      "required": [
      +        "idempotent_replay"
      +      ]
      +    }
      +  ],
      +  "properties": {
      +    "ack_required": {
      +      "type": "boolean"
      +    },
      +    "bcc": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "body_md": {
      +      "type": "string"
      +    },
      +    "cc": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "created_ts": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "delivery": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "admission_checked_at": {
      +          "type": "string"
      +        },
      +        "historical": {
      +          "type": "boolean"
      +        },
      +        "persisted": {
      +          "type": "boolean"
      +        },
      +        "recipients": {
      +          "items": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "availability": {
      +                "enum": [
      +                  "eligible",
      +                  "unavailable",
      +                  "unknown"
      +                ]
      +              },
      +              "historical": {
      +                "type": "boolean"
      +              },
      +              "lifecycle": {
      +                "type": "string"
      +              },
      +              "observed_at": {
      +                "type": "string"
      +              },
      +              "process": {
      +                "enum": [
      +                  "present",
      +                  "unknown"
      +                ]
      +              },
      +              "reason": {
      +                "type": "string"
      +              },
      +              "recipient": {
      +                "type": "string"
      +              },
      +              "reported_end_at": {
      +                "type": "string"
      +              },
      +              "source": {
      +                "enum": [
      +                  "t3",
      +                  "registry",
      +                  "registration"
      +                ]
      +              },
      +              "wake": {
      +                "const": "unknown"
      +              }
      +            },
      +            "required": [
      +              "recipient",
      +              "availability",
      +              "lifecycle",
      +              "process",
      +              "wake",
      +              "source",
      +              "reason",
      +              "observed_at"
      +            ],
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "warnings": {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        }
      +      },
      +      "required": [
      +        "persisted",
      +        "admission_checked_at",
      +        "historical",
      +        "recipients",
      +        "warnings"
      +      ],
      +      "type": "object"
      +    },
      +    "from": {
      +      "type": "string"
      +    },
      +    "id": {
      +      "type": "integer"
      +    },
      +    "idempotent_replay": {
      +      "type": "boolean"
      +    },
      +    "importance": {
      +      "type": "string"
      +    },
      +    "notification_policy": {
      +      "enum": [
      +        "wake",
      +        "quiet"
      +      ]
      +    },
      +    "project_id": {
      +      "type": "integer"
      +    },
      +    "revision": {
      +      "type": "integer"
      +    },
      +    "sender_id": {
      +      "type": "integer"
      +    },
      +    "sender_location": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "branch": {
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "repo": {
      +          "type": "string"
      +        },
      +        "title": {
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "worktree": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "repo",
      +        "worktree",
      +        "branch",
      +        "title"
      +      ],
      +      "type": [
      +        "object",
      +        "null"
      +      ]
      +    },
      +    "subject": {
      +      "type": "string"
      +    },
      +    "thread_id": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "to": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "topic": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    }
      +  },
      +  "required": [
      +    "id",
      +    "project_id",
      +    "sender_id",
      +    "thread_id",
      +    "topic",
      +    "subject",
      +    "body_md",
      +    "importance",
      +    "ack_required",
      +    "created_ts",
      +    "from",
      +    "sender_location",
      +    "to",
      +    "cc",
      +    "bcc"
      +  ],
      +  "type": "object"
      +}
  2. Changed1 schema field changedv0.3.0
    • addedInput schema / properties / delivery_policy
      Added value: +{
      +  "description": "checked (default) or durable. Both currently admit and store mail the same way. Neither bypasses closed T3 or unavailable bound sources. Unqualified standalone state remains unknown and is returned with warnings; storage does not transfer task ownership.",
      +  "enum": [
      +    "checked",
      +    "durable"
      +  ],
      +  "type": "string"
      +}
  3. Changed1 schema field changedv0.2.5
    • changedInput schema / properties / idempotency_key / description
      Previous value: -"Any string. A retry with the same key and arguments returns the first result."New value: +"Nonempty key for this tool and agent. Identical arguments replay with idempotent_replay:true; different arguments fail with IDEMPOTENCY_KEY_CONFLICT. Hourly cleanup removes keys older than 7 days. Retries can replay until removal; afterward a retry may perform the operation again."
  4. Changed10 schema fields changedv0.2.2
    • addedInput schema / properties / ack_required / description
      Added value: +"Ask recipients to call acknowledge_message."
    • addedInput schema / properties / bcc / description
      Added value: +"Recipients the others do not see."
    • addedInput schema / properties / body_md / description
      Added value: +"The message body, in Markdown."
    • addedInput schema / properties / cc / description
      Added value: +"Recipients copied, visible to everyone."
    • addedInput schema / properties / idempotency_key / description
      Added value: +"Any string. A retry with the same key and arguments returns the first result."
    • changedInput schema / properties / importance / description
      Previous value: -"low, normal, high or urgent"New value: +"low, normal (default), high or urgent."
    • addedInput schema / properties / subject / description
      Added value: +"One line, shown in inbox listings."
    • addedInput schema / properties / thread_id / description
      Added value: +"A thread to join. reply_message sets it for you."
    • addedInput schema / properties / to / description
      Added value: +"Recipient agent names in this project."
    • addedInput schema / properties / topic / description
      Added value: +"A label fetch_inbox can filter on."
  5. First observedv0.2.1

TDQS

A4.6/5.0
Behavior5/5

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

Annotations only declare the coarse flags (non-read-only, non-destructive, not idempotent, closed-world). The description goes well beyond them, disclosing failure semantics (unregistered/retired/closed recipient fails the whole send with persisted:false and a reason), the 7-day idempotency replay window versus a duplicate-on-retry default, that replay observations are historical, that storage is not task acceptance, and the transport rule against re-routing on uncertain delivery. The idempotentHint:false annotation is not contradicted: it correctly describes the keyless default path that the description qualifies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a dense wall of prose that mixes invocation-critical facts with message-composition style coaching (open with the action, add up to three short facts, add a Next action line, put hashes and metrics in linked records, use spaces between words and numbers). Those craft instructions crowd out the routing and failure facts and are not front-loaded, so the piece is over-specified rather than concise even though individual sentences are grammatically tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 15-parameter tool with nested oneOf branches, an output schema and annotations, the description covers the important gaps: mutating nature, recipient failure modes, idempotency, notice-mode constraints, threading and transport selection. The only shortfall is that the crucial branch conditions (resource_notice vs subject/body_md) are buried mid-paragraph, so completeness is achieved at the cost of discoverability.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/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 real meaning: the resource_notice branch is summarized as "one recipient, a nonempty idempotency key, no free-text or delivery overrides," the idempotency_key replay/conflict contract is restated operationally, and the descendance rule (only contact still-dependent resource owners, send release/cancellation before dropping waiting recipients) constrains how parameters should be used. It clarifies the oneOf branching that the schema only expresses structurally.

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?

Opens with a specific verb+resource+scope: "Send a Markdown message to named agents in the same project." It explicitly distinguishes itself from the nearest sibling (reply_message) and from resource_notice mail, so an agent can route correctly without opening either 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?

Gives explicit inclusion criteria ("Send only when the recipient needs to act or know: a handoff, requested result, blocker or shared-resource change") and exclusions ("do not send courtesy acknowledgements or reply to thanks"), plus a named alternative with its selecting condition ("To answer a message, use reply_message"). This is textbook when/when-not/alternative guidance.

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