Watch
0
0
Fork
You've already forked hyperhive
0

docs/tools: the bash and matrix pages say what the tools do around the edges, not how to call them

Each page opens with its audience (the operator). The per-parameter tool
listings, which repeat the tools' own MCP descriptions, become short summaries
of the behaviour an operator needs: the completion todo, what status clears,
the process-group kill, the unread guard, how invites resolve. The wiring and
architecture sections are unchanged.
This commit is contained in:
iris 2026-10-26 16:47:28 +01:00 • committed by mara
commit 2d1b6a4e1a
2 changed files with 56 additions and 137 deletions

View file

@ -1,5 +1,9 @@
# Matrix MCP tools and extra MCP servers
For the operator: this page covers how the harness adds the matrix tools and what
they do around the edges. How an agent calls them is in the tools' own MCP
descriptions.
## Built-in matrix MCP (`mcp__matrix__*`)
When the agent has at least one `services.hyperhive.agent.matrixAccounts`
@ -9,71 +13,31 @@ see Architecture below). No `matrix.enable` switch exists: the account
set *is* the switch, and the module declares the hive-internal `main`
account for you as soon as `services.hyperhive.agent.matrix.url` is
non-null — which hive-c0re fills in per agent whenever the operator
configures the host-level matrix tuwunel. Tools land as `mcp__matrix__<name>`:
configures the host-level matrix tuwunel. Tools land as `mcp__matrix__<name>`.
### Messaging
Each tool's parameters and return values are in its own MCP description, which
is what an agent reads at call time. They fall into four groups:
**Unread guard**: `send_message`, `send_dm`, `send_file`, and
`send_reply` are all rejected if the room has unread messages — call
`read_room` then `mark_read` on the latest event before sending to a
room you haven't read yet.
- **Messaging:** `send_message`, `send_dm`, `send_reply`, `send_reaction`,
`send_file`, `send_redact` and `open_dm`. A room is `!id:server` or
`#alias:server`, and the daemon resolves either. `open_dm` finds or creates the
DM room and returns its id without sending anything, for a case where
`send_dm`'s body is inconvenient, such as a file attachment. `send_file` caps
an upload at 50 MiB. Redacting someone else's event needs moderator power.
- **Reading:** `read_room`, `download_file`, `list_rooms` and
`list_room_members`. `read_room` shows media as `[file: …]`, `[image: …]`,
`[audio: …]` or `[video: …]` markers, and the event id of one goes to
`download_file`.
- **Room membership:** `invite_user`, `list_invites`, `resolve_invite` and
`join_room`. `resolve_invite` accepts or rejects a pending invite and is the
path for invites; `join_room` is for a public room the agent wasn't invited to.
`list_invites` gives the inviter and the topic, so an agent can judge an
invite before it answers.
- **Receipts:** `mark_read` advances the read receipt.
- `send_message(room, body)` — send a markdown message; `room`
accepts `!id:server` or `#alias:server`, daemon resolves either
- `send_dm(user_id, body)` — open (or reuse) the DM room with
`user_id` and post `body` to it
- `open_dm(user_id)` — resolve (find-or-create) the DM room with
`user_id` and return its room id **without sending anything**.
Use the returned id with room-based tools (`send_message`,
`send_file`, …) to deliver into a DM when `send_dm`'s body
parameter is inconvenient (for example for file attachments)
- `send_reply(room, event_id, body)` — threaded reply to a specific
event
- `send_reaction(room, event_id, key)` — react to a message with an
emoji key
- `send_file(room, path, caption?)` — upload a local file and post it
as a room attachment, inferring the MIME type from the file extension
(50 MiB cap); an optional `caption` follows as a separate text message
- `send_redact(room, event_id, reason?)` — redact (delete) a specific
event; works on your own events, redacting others' requires moderator
power level
### Reading
- `read_room(room, limit?)` — recent timeline events; media attachments
appear inline as `[file: name]`, `[image: name]`, `[audio: name]`,
or `[video: name]` markers — pass the event id to `download_file`
to retrieve the attachment
- `download_file(room, event_id, dest_path?)` — download a media
attachment from a message event to a local file and return its path;
pair with `read_room` which surfaces attachments as the markers above
- `list_rooms()` — enumerate joined rooms
(`{ room_id, canonical_alias, name, member_count }` per room)
- `list_room_members(room)` — members of a room
### Room membership
<!-- vale write-good.Passive = NO -->
- `invite_user(room, user_id)` — invite `@user:server` into a room
you're already in; you must have a high enough power level.
The invitee sees a pending invite and resolves it via
`resolve_invite`.
- `resolve_invite(room, action)` — accept or reject a pending invite.
`action` is `"accept"` (join the room) or `"reject"` (decline and
leave). This is the path for invites; `join_room` is for joining a
public room you weren't invited to.
- `join_room(room)` — join a public room by id or alias. Also accepts
a pending invite if one exists, but prefer `resolve_invite` for
invites (it can reject too).
- `list_invites()` — rooms this agent has been invited to but not
yet joined (`{ room_id, canonical_alias, name, inviter, topic }` per room —
`inviter` and `topic` are there so an agent has enough to judge an
invite before `resolve_invite`ing it, not just a bare room id).
<!-- vale write-good.Passive = YES -->
### Receipts
- `mark_read(room, event_id)` — advance the read receipt
**Unread guard.** `send_message`, `send_dm`, `send_file` and `send_reply` fail
while the room has unread messages. The agent calls `read_room` and then
`mark_read` on the latest event before sending to a room it hasn't read.
## Multiple accounts