A new bot cannot accept an invite from the channel mount, and cannot tell that from having none #128
Labels
No labels
blocked
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
waiting-on-julian
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
jlxq0/matrix-mcp#128
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found by Lucy, the first bot created since the channel mount existed. Julian has been messaging
@lucybot:kampong.socialand getting nothing back.CHANNEL_TOOLSiswhoami,list_joined_rooms,read_recent_messages,read_thread,send_text_message,send_reaction,mark_read,download_attachment(src/channel.rs:415-429). Nojoin_room, noinvites_list, noinvites_accept. All three exist on the full mount (src/mcp.rs:6218,:6548,:6595) and none is reachable from the channel.So a newly created bot cannot see an invite, cannot accept one, and cannot tell "nobody invited me" from "I was invited and cannot act on it". Every existing director got its first room by some path nobody wrote down; the gap exists only at the moment of creation, which is why it has never been hit and why nothing says so.
Two defects, and the second is the reason she could not self-diagnose
list_joined_roomsreturning[]is ambiguous.client.joined_rooms()atsrc/mcp.rs:2538says nothing about invited rooms, so an empty list means both "no rooms" and "rooms are waiting and you cannot see them". A bot meeting the first defect is told nothing that distinguishes it from a bot nobody has invited.The mount has no way to accept an invite. That is the capability gap.
The fix is not adding the three tools to
CHANNEL_TOOLSThe channel mount is deliberately small and that is a feature: a bot that can join arbitrary rooms is a wider surface than one that can only speak where it already is.
join_roomtakes any room id the bot can discover, and that is strictly more than this needs.Accepting an invite from a named mxid is a different and narrower capability than joining a room by id. The proposal is a tool shaped like accept the invite from this person, which:
Room::invite_details()returns anInvitecarryinginviter_id(matrix-sdk 0.17,src/room/mod.rs:3689and:4673), so the inviter is available without adding anything to the SDK surface.invites_listas it stands does not carry it —InviteSummaryis room id, display name and encryption state — so surfacing the inviter is part of this work rather than free.And the ambiguity has its own fix, which is smaller and independent:
JoinedRoomsResultgains a count of pending invites, so{"rooms": [], "pending_invites": 2}and{"rooms": [], "pending_invites": 0}are different answers. That one costs a field and no new capability, and it is what would have let her diagnose past the symptom.Acceptance
A newly created bot reaches its principal using only the channel mount, with no operator step and no borrowing of anyone's identity. Today that is impossible.
Not the fix, recorded so nobody reaches for it
Using
matrix-julian's credential to accept on the bot's behalf is Julian accepting an invite with his own identity, and it makes the bot's first room something an operator did rather than something the bot can do. Lucy declined it without being told to. Clark authorised a narrow unblock for her specifically — her own bearer against the full/mcpmount, list invites, accept the one from him, nothing else — which works because the full mount advertises every tool to the same credential. That unblocks her and does not close this.Related
[]reads as "no rooms".The ninth bot is the acceptance for this issue, and tonight gave it a second half.
Lucy was created, invited, and could not accept the invite from the channel mount, which is what this issue is about. She was also silently deaf once she joined, for a different reason: her account had no
app.matrix_mcp.channel, soallowed_senderswas empty and every push was refused exactly as designed. See #129.Both are the same root and it is this one.
README.md:93documents the allowlist JSON and no code writes it. Seven directors work because someone performed that step seven times; the eighth does not because nobody recorded that it was a step. Neither the doing nor the not-doing leaves a trace, so the failure waits for the first bot created by somebody who did not know.So the acceptance is not "invites work". It is that the ninth bot cannot be created without an allowlist. A creation path that accepts an invite and leaves the bot mute has moved the failure rather than removed it.
Two operational facts for whatever performs the write, both measured by Lucy on herself:
set_account_datareplaces rather than merges. Hers was absent so nothing could be lost. The next one's may not be, and a partialapp.matrix_mcp.channelwould be overwritten wholesale by anyone following the README against an account whose current state they had not read.And the check that the write worked needs care.
get_account_datareads the client's local state store while the push path'sconfig()reads the homeserver, so the two can disagree with nothing saying so. A verification must resolve it the way the channel resolves it. Usem.push_rulesas the positive control, neverm.direct:m.directexists only if someone has opened a DM with the account, so a freshly provisioned bot has none and a check built on it reads a working bot as unreadable.