Agents that message each other
A project in Cydonia can have several sessions going at once, each an agent working on its own thread. Since 0.1.14 they can reach each other, through three MCP tools every session is offered: session_send, session_read and session_search.
Turns, and how to name them
A session is made of turns. A turn begins with a message sent to the agent and holds everything the agent did in answer, up to the next message. Turns are counted from 1.
Every session is a project entry with a number, so a run of turns has a short name that you and an agent can both write:
| Reference | Names |
|---|---|
#43 |
Session 43 in this project |
#43:5 |
Turn 5 of session 43 |
#43:5-7 |
Turns 5 to 7, both ends included |
cydonia#43:5-7 |
The same, in the open project whose folder is named cydonia |
cydonia://cydonia#43:5-7 |
The same, as a link |
The project name is the last part of the folder's path. When two open projects share a name, the reference is refused and both paths are listed. The full grammar, including the forms for article lines and headings, is on the References page.
Reading
session_read takes a reference and answers those turns. With no turns named it answers the last 3. Each turn comes back under a heading carrying its own reference, ## #43:5, so whatever the agent quotes from it is already addressable.
By default the answer is the conversation: the user's messages, the agent's replies, notices, and each tool call as a single line with its status, tool: … — ok. Thinking, tool output and the agent process's own output are left out unless the call sets full. A turn range past the end is cut to the last turn; one that starts past the end is refused with the number of turns the session has.
It reads archived sessions too, and sessions in another open project when the reference names one.
Searching
session_search finds text case-insensitively, in one session or in every session of the project, archived ones included. Each matching turn comes back as a reference with the line it matched:
#43:5 Fix the parser — the span is off by one when the range is open
At most 20 turns are answered, with a note to narrow the query when there are more. The references are what session_read takes, so the usual pattern is a search followed by a read of the turn it found.
Sending
session_send queues a message as another session's next prompt. If that session is in the middle of a turn, the message waits in its queue; if it is idle, it is sent. Sending to an archived session brings it back into use.
Leave out the session and name an agent instead, and the message becomes the first prompt of a new session on that agent. The tool's schema lists the agents configured in settings.toml, by registry id where there is one, so the model picks from names that exist.
It is fire and forget. Nothing is waited for and no answer comes back through the tool. A session that wants to know what happened reads the other one later.
Signed with a turn
A message one session sends to another starts with where it came from: the sending session and the turn it was on. In 0.1.14 that was a plain reference, from #42:7. Since 0.1.27 it is a chip link:
from [cydonia://cydonia#42:7](cydonia://cydonia#42:7 "chip")
Review the diff in turn 7 before I merge it.
In the transcript the chip paints as the sender's mark and title. For the receiving agent it is a reference it can pass straight to session_read, so the context behind the message is one call away rather than lost.
A message sent by anything that is not a session, such as an MCP client you added by hand, is not signed.
How the server knows who is calling
Cydonia runs one MCP server for the app, on loopback. When it starts an agent, it puts two headers on that agent's MCP connection: x-cydonia-project, the project directory, and x-cydonia-session, the record id of the session. The server reads the sender's current turn off disk when the message is sent. A session with no turn on disk yet sends unsigned.
Since 0.1.27 each turn's session context also names the session itself (Current session: #43), so an agent can give out its own reference.
Boundaries
session_sendreaches sessions in the project the call is about.session_readandsession_searchreach any open project.- The target project must be open in Cydonia. Sessions run in the app.
session_sendis a write tool. With writing switched off in Settings it is left out oftools/list.
The session tools, with the rest, are listed in the MCP docs.