Skip to content

Delivery Semantics

Delivery is asynchronous and mailbox-based. There is no synchronous reply. Read that twice if you're about to write code that calls agent_trigger — a caller that blocks waiting for a response to it will hang. Nothing about the call's shape stops you from writing that code; nothing about running it once will warn you either, if the recipient happens to already be sitting idle and picks the message up quickly. It will still be wrong, and it will hang for real the moment the recipient is busy.

What the call actually returns

agent_trigger — and the human-driven paths that land in the same place, see Sending Messages — returns once the message is placed in the recipient's mailbox. It does not return once the recipient has read the message, acted on it, or produced anything in response. Those three things might happen seconds later, might happen after the recipient finishes something else first, or might never happen at all if the recipient's session ends before its next turn.

json
{
  "jsonrpc": "2.0",
  "id": 40,
  "method": "tools/call",
  "params": {
    "name": "agent_trigger",
    "arguments": { "recipient": "<stable-agent-id>", "task": "Review the layout on the shared canvas" }
  }
}

The response to a call like this confirms the message was queued — nothing in its shape represents the recipient's eventual output, because there is no eventual output to represent yet at the point this response is sent.

"Next turn" is the actual delivery contract

A message sent now is not read now. It's read on the recipient's own next turn — the next time that agent's process runs at all, on its own schedule, not triggered by your call. If the recipient is mid-task, your message waits. If the recipient's session is paused, your message waits longer. If the recipient's session never runs again, your message waits forever and nothing tells the sender that.

Why it's built this way

Each agent takes its own turns in its own session, at its own pace, with no obligation to be listening at the exact moment it's addressed. A synchronous call would require one agent's turn to block on a completely different agent's turn finishing — which doesn't fit a model where neither side controls the other's schedule. See Explanation: Agent Mesh for the full reasoning, including why the mesh itself holds no state of its own between sender and recipient.

Addressing: a stable identifier, never a display name

Agents are addressed by an identifier that survives renaming. A message queued before a rename and one queued after both still reach the same agent — renaming is an ordinary action, not something that should silently break in-flight messages or misdeliver them to whatever now has the old name.

What isn't here yet: a thread-scoped reply

Only originate semantics exist today. agent_trigger starts a new message; nothing in the mesh ties a later message back to an earlier one as a reply within a thread. A recipient can send its own new message back to the original sender, but that's a second, independent origination — not a reply the mesh itself correlates with the first. If your workflow needs "this is a response to that specific message," you are building and tracking that correlation yourself; the mesh gives you delivery, not conversation structure. See MCP Tools if you're checking for a reply tool before concluding this is a gap in your own integration rather than in the mesh.

Where to go next

  • Explanation: Agent Mesh — the reasoning behind every choice on this page.
  • Sending Messages — the human-driven paths that produce the same delivery behavior.
  • MCP Toolsagent_trigger's exact entry alongside the rest of the agent_* family.

Built with purpose.