How-to Guides
Role-scoped message visibility
Send messages visible only to certain room roles (evaluator notes, teacher hints) in the same live session.
Role-scoped message visibility
Whisper messages target specific user ids. Role-scoped messages target everyone with a room role (for example all evaluators in an interview room). Candidates and guests in the same session do not see them on the timeline or over WebSocket.
Send from the SDK
Assign roles with room_members.role when you add members (REST or provisioning). Then send with a role: prefix:
await client.createMessage(roomId, "Candidate used O(n²) sort; suggest follow-up.", {
visibility: "role:evaluator",
});Whisper still works for named users:
await client.createMessage(roomId, "Private nudge", {
visibility: "whisper",
visibleTo: [teacherUserId],
});WebSocket sends use the same fields on the message frame.
MCP agents
Room MCP send_message accepts optional visibility and visibleTo:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "send_message",
"arguments": {
"content": "AI note for evaluators only",
"visibility": "role:evaluator"
}
},
"id": 1
}read_timeline applies the same rules for the JWT holder.
Enforcement
- WebSocket fan-out delivers scoped messages only to authorized sockets (author always receives their own message).
- History (connect snapshot, REST, search, export, MCP) filters in D1 using the viewer's membership role.
- Role names are lowercase alphanumeric with underscores (1–64 chars), matched case-insensitively against
room_members.role.
Interview eval pattern
- Create a room and add the candidate as
member(orguest). - Add human evaluators and your AI agent with
role: evaluator(orevaluatorinroom_members.role). - Agent posts analysis with
visibility: "role:evaluator". - Candidate UI shows the public thread only; evaluator dashboard shows public plus role-scoped notes.
See Room as MCP server to connect an external evaluator agent.