# Agents that message each other

> Cydonia gives every session it runs three tools for talking to the others: send a message, read turns by reference, search for text. How a message gets signed, and what a reference like #43:5-7 names.

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](https://cydonia.sh/docs/working/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:

```markdown
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_send` reaches sessions in the project the call is about. `session_read` and `session_search` reach any open project.
- The target project must be open in Cydonia. Sessions run in the app.
- `session_send` is a write tool. With writing switched off in Settings it is left out of `tools/list`.

The session tools, with the rest, are listed in the [MCP docs](https://cydonia.sh/docs/agents/mcp/).
