pollen

peer messaging for agents

pollen

carry what matters.

One agent asks another a question and uses the answer, without a supervisor having to relay it. An agent nobody has vouched for cannot simply talk to yours: it knocks, and a person opens the gate.

One file of Node. No dependencies. Any MCP host.

sorrel · two peers and a stranger
brack sends, and is told what actually happened
$ pollen_send to sorrel
  Sent to sorrel.

thistle is not vouched for
$ pollen_send to sorrel
  Held at sorrel's trust gate — sorrel must
  allow "thistle" before this is delivered.

sorrel's watcher rings, one line per arrival
[pollen] message from brack — pollen_inbox to
        read: schema is frozen — migration 0007
        is the last one before the cut
[pollen] thistle is knocking — pollen_allow
        or pollen_deny

$ pollen_inbox
  [brack]: schema is frozen — migration 0007
  is the last one before the cut

$ pollen_deny thistle
  Denied and dropped message from thistle.

where it sits

The sideways channel

umbel and pleach both speak down the tree. pollen speaks across it.

umbel

Fans workers out from one stem and holds each of them steady. The supervisor talks to every worker; the workers do not talk to each other.

pleach

Interweaves the branches — conducts a plan through gates, deciding what is done and what goes next. Direction still flows downward.

pollen

What growers say to each other. One peer asks, another answers, and nothing above them has to carry the message — with a person at the gate.

the gate

Strangers knock; you decide.

Messaging between autonomous programs is only safe when a person decides who is let in. That decision is the product's spine, and the sender is always told which way it went.

held

An unvouched peer is stopped at the gate. Its message is kept, not shown — the doorbell rings without quoting what it said. Held at sorrel's trust gate — sorrel must allow "thistle" before this is delivered.

allowed

A person opens the gate and every knock that peer made is delivered, oldest first — a follow-up never destroys the message it was asking about. Allowed thistle. Their message has been delivered.

denied

The message is dropped and never rung out. Echoing text a human just rejected onto the channel they watch would defeat denying it. Denied and dropped message from thistle.

A held knock survives a restart: the gate is rebuilt from the journal, so something you were rung about is still there to answer. Pre-approve the peers you already trust with POLLEN_ALLOW.

how it works

One file, three modes

Raw MCP over stdio, no SDK. Mailboxes are files on one machine and an HTTP relay across machines; the agent does not know which it is using.

node pollen.mjs

The MCP server your host spawns. Five tools: send, agents, inbox, allow, deny.

node pollen.mjs --relay

An HTTP hop between machines, over any tunnel or VPN. It forwards; it holds nothing.

node pollen.mjs --watch id

The doorbell. One line per arrival, so any harness that reads lines can wake the agent instead of polling.

Every arrival is written to an append-only journal before the mailbox file is removed, and a cursor records how far the agent has read. A message that arrived but was never read is still there after a restart, and the agent is told how many are waiting.

install

Put it in your agent's hands

One file to fetch, one block of config. Node 18 or newer, nothing else.

install
$ curl -O https://raw.githubusercontent.com/jahala/pollen/main/pollen.mjs

# then, in .mcp.json
{
  "mcpServers": {
    "pollen": {
      "command": "node",
      "args": ["./pollen.mjs"],
      "env": { "POLLEN_ID": "my-agent" }
    }
  }
}

Then run the doorbell as a background task: node pollen.mjs --watch my-agent. Full options and the environment table are in the README.