Agent Send
by iamomiid
README.md
# Agent Send
**Let your agents talk to each other.**
Agent Send is a thin request/reply layer between AI agents. One agent asks a
question and waits; the other answers; the answer comes back to the exact
request that asked for it. Routing, waiting and retries are plain code, so no
model tokens are spent polling an inbox.
```text
Hermes (your Mac) Agent Send bridge Grok Bot (hosted)
───────────────── ───────────────── ────────────────
agent-send grok "…" ──► request file ─► POST routine webhook ──────────► routine runs
│
◄── JSON answer ◄────── reply file ◄─── agent_reply (MCP) ◄────────────────┘
Hermes API run ◄──── POST /v1/runs ◄── agent_call (MCP) ◄──────────────── Grok chat
final output ─────────────────────► agent_await ────────────────► answer
```
**Status: v0.1, early.** Two agent types are supported today:
| Type | How the bridge reaches it | How it answers |
|---|---|---|
| [Hermes](https://hermes-agent.nousresearch.com) | Hermes API server on loopback (`POST /v1/runs`) | Bridge polls the run's final output |
| [Grok Bot](https://docs.x.ai/grok-bot) | A webhook-triggered routine | The Bot calls the `agent_reply` MCP tool |
You can add any number of routes of each type (several Hermes profiles, several
Grok Bots). More agent types may come later; see [Scope](#scope).
## Requirements
- macOS or Linux (the mailbox uses `flock`; Windows is not supported)
- Python 3.11+ and [uv](https://docs.astral.sh/uv/)
- For Grok Bot: a stable public HTTPS URL for the bridge
([options](docs/exposing-the-bridge.md))
## Quickstart
```sh
uv tool install git+https://github.com/iamomiid/agent-send
agent-send init # creates ~/.agent-bridge with a private bridge credential
agent-send doctor # shows configuration; never prints credentials
```
### 1. Connect Hermes
Enable the Hermes API server for the profile that should take part
(`API_SERVER_ENABLED=true` and an `API_SERVER_KEY` in that profile), then:
```sh
agent-send configure hermes --url http://127.0.0.1:8642
# Paste the profile's API_SERVER_KEY into the hidden prompt.
```
A named profile served by a multiplexed gateway uses its own path, for example
`--url http://127.0.0.1:8642/p/work`.
So Hermes can start conversations, copy [`skills/agent-send`](skills/agent-send/SKILL.md)
into that profile's skills and make sure `agent-send` is on its terminal's PATH.
### 2. Run the bridge
```sh
agent-send serve
```
It listens on `127.0.0.1:8766`. To keep it running, see
[running as a service](docs/running-as-a-service.md).
### 3. Connect Grok Bot
1. Expose the bridge at a stable HTTPS URL ([how](docs/exposing-the-bridge.md)),
then tell Agent Send about it and write the connector settings:
```sh
agent-send configure public --url https://agents.example.com
agent-send connector # writes ~/.agent-bridge/grok-connector.json (private)
```
2. In Grok, add a **Remote HTTPS** custom connector with the `/mcp` URL and
`Authorization` header from that file.
3. In the chat of the Bot that should receive requests, create a webhook routine
using the instruction in [docs/grok-bot.md](docs/grok-bot.md), and copy the
routine's webhook URL and key.
4. Register the routine:
```sh
agent-send configure grok --url https://YOUR-ROUTINE-WEBHOOK
# Paste the routine's webhook key into the hidden prompt.
```
### 4. Try it
```sh
agent-send grok "Reply with exactly PING_OK"
```
And from a Grok chat: *"Use agent-send's `agent_call` to ask hermes to reply
with exactly PONG_OK."*
## Usage
```sh
agent-send send <agent-id> "question" # ask and wait up to 25 s
agent-send grok "question" # shorthand for send grok
agent-send wait r_REQUEST_ID # keep waiting; never resends
agent-send status [r_REQUEST_ID] # one result, or all requests
agent-send agents # who can I talk to?
agent-send configure <agent-id> --url … # add or update a route
```
Results are JSON. Exit codes: `0` completed, `2` still pending, `3`
failed/expired/unknown, `1` local or configuration error. Useful flags:
`--wait 0` (submit only), `--deadline` (1–3600 s, default 300), and `--key`
(idempotent retries of the same request).
Remote agents get five MCP tools:
| Tool | Purpose |
|---|---|
| `agent_list()` | Discover yourself and the agents you may call |
| `agent_register(description?, capabilities?)` | Optionally introduce yourself |
| `agent_call(to, message, wait_seconds?, deadline_seconds?, idempotency_key?)` | Ask another agent |
| `agent_await(request_id, wait_seconds?)` | Keep waiting for a pending answer |
| `agent_reply(request_id, result)` | Answer a request delivered by webhook |
Remote waits are capped at 25 seconds per call; a pending request is resumed
with `agent_await`, never sent again.
## Adding more agents
`configure` accepts any ID. The type is inferred from the URL: a loopback URL is
a Hermes profile, an HTTPS webhook is a Grok Bot routine (`--kind` overrides).
The running bridge reloads `routes.json` automatically; no restart is needed.
```sh
agent-send configure research --url http://127.0.0.1:8642/p/research
agent-send configure creator-analyst --url https://ROUTINE-WEBHOOK \
--name "Creator Analyst" --allow-from grok
```
`--allow-from grok` lets Grok Bots call that route too; without it, only local
agents can. Grok Bot cannot relay messages to its sibling Bots from inside a
webhook routine, so each Bot you want to reach needs its own routine and route
([details](docs/grok-bot.md#reaching-more-grok-bots)).
## How it works
Everything lives in one private directory, `~/.agent-bridge/` by default
(override with `AGENT_SEND_HOME` or `--home`):
```text
routes.json routes and permissions (no secrets)
secrets.json credentials, mode 0600
agents/<agent-id>.json automatic registration and optional introduction
requests/r_<id>.json immutable request
state/r_<id>.json bridge-owned delivery state
replies/r_<id>.json immutable answer or failure
```
Files are written atomically. A single `agent-send serve` process owns the
mailbox, rescans it every 0.5 seconds, delivers requests and serves the MCP
endpoint. Agents are registered automatically the first time they connect or
send; no greeting turn is needed. See [the protocol](docs/protocol.md) for the
file formats and state machine.
## Guarantees and limits
- **Answers survive restarts.** A reply file is the authority even after a crash.
- **No blind retries.** A Hermes run is resumed by its run ID; a Grok webhook is
posted once. If delivery is uncertain the request becomes `unknown` and waits
for a late reply, its deadline, or `agent-send abandon <id>`.
- **One active request per recipient**, in submission order. Calls that would
make two agents wait on each other are rejected.
- **Identity comes from credentials**, never from what a model claims. Remote
callers can only call permitted targets, read their own results and answer
requests addressed to them.
- **Small messages.** 32 KiB per request, 64 KiB per answer, no attachments.
- **Grok Bots share one identity.** A Grok connector credential is account-wide,
so every Bot on the account authenticates as `grok`.
- A deadline ends the wait; it does not stop remote work that already started.
See [SECURITY.md](SECURITY.md) for the trust model.
## Scope
Agent Send is deliberately small: request/reply between agents you own, over
files and one local process. It is not a chat room, a message bus, an agent
marketplace or a hosted service. Adapters for other agent types are welcome to
be discussed in an issue first.
## Development
```sh
git clone https://github.com/iamomiid/agent-send && cd agent-send
uv sync
uv run pytest
uv run ruff check . && uv run ruff format --check .
```
Tests use temporary mailboxes, fake Hermes/Grok endpoints and the official MCP
client; they never contact real agents. See [CONTRIBUTING.md](CONTRIBUTING.md).
## License
[MIT](LICENSE) © Omid Sayfun
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo recent community issues