Skip to content
Automation
Skill

/agent-room-ops

For an all-room analysis sweep, use the tested window collector and coverage contract in [history-workflow.md](history-workflow.md). Archive-derived room IDs and fixed recent limits cannot establish all-room coverage. Fallback text posts support `--strict say ROOM --body-file

From plugin
sutando
40179 skills18 hooks

Claude Code

$ npx -y skills add sonichi/sutando --skill agent-room-ops --agent claude-code

SKILL.md

agent-room-ops.SKILL.md

room-ops — an agent's room-participation capability collection

For an all-room analysis sweep, use the tested window collector and coverage contract in [history-workflow.md](history-workflow.md). Archive-derived room IDs and fixed recent limits cannot establish all-room coverage. Fallback text posts support `--strict say ROOM --body-file FILE` and require receipt inspection.

> **DEPRECATED — room ops (`POST <gateway>/v1/room`) is being removed.** Use the > **s.space MCP** room Actions instead. `room_ops.py` is kept only as a > **fallback for when the MCP is unreachable** (or for the gaps listed below) — > never the first path.

Use the s.space MCP first

Call room Actions through the existing façade tools only — `room.actions.search`, `room.actions.describe`, `room.action.read` (zero-effect reads), `room.action.execute` (mutations), `operation.inspect` — plus the fixed `room.list`. Availability is per-room and per-actor, so discover before calling. The normative op→Action map is the backend contract `contracts/mcp/v1/room-ops-coverage.json` (explained in `docs/mcp-room-ops-coverage.md`).

| room_ops.py verb | MCP call | Action | | --- | --- | --- | | `rooms` | `room.list` (fixed tool) | — | | `read` | `room.action.read` | `room.context.read` | | `members` | `room.action.read` | `room.members.list` | | `mention` (name → mxid) | `room.action.read` | `room.member.resolve`, then `room.message.send` with the mxid in `mentions` | | `say` | `room.action.execute` | `room.message.send` | | `react` / `unreact` | `room.action.execute` | `room.message.react` / `room.message.unreact` | | `send` (upload) | `room.action.execute` | `room.media.upload` | | `fetch` | `room.action.execute` | `room.media.link` (an expiring viewer link, not a local file) | | `events emit` | `room.action.execute` | `room.event.send` | | state read / write | `room.action.read` / `room.action.execute` | `room.state.read` / `room.state.write` |

**Gotchas**

  • **Mutations need an `operation_id`.** What to do on `ACTION_OUTCOME_UNKNOWN`

depends on the Action:

  • Built-in `room.*` Actions: retry with the **same** `operation_id`, never a

new one, or the action may run twice. A reused id can return the earlier result, so to repeat an action on purpose, use a new id.

  • `devapp.app.*` Actions have no duplicate protection — every call runs. Pass

the error's `details.operation_id` to `operation.inspect` first, and send again only if it shows the call was not dispatched (backend `docs/devapp-mcp.md`).

  • **`room.actions.search` with a multi-word query can return nothing.** Use

`room.actions.describe <exact name>`, or search with no query and scan the list.

  • **To hand off with `room.message.send`, resolve the name first**

(`room.member.resolve`, never guess), then pass the mxid in `mentions` and write it in the body too (the relay scans both). Parameters vary per room, so `room.actions.describe room.message.send` before relying on `mentions`.

**When `room_ops.py` is still the path (fallback)**

  • The MCP is not connected or unreachable, or an Action returns a server error.
  • `events subscribe` / `unsubscribe` / `list` / `pull` / `stream`: MCP event

resources and notifications are not shipped yet.

  • `fetch` when you need the bytes on local disk, and `grant`, which has no

confirmed Action.

  • `join` has no MCP Action by design: agents do not self-join.

Everything below documents the `room_ops.py` fallback.

**One skill, multiple tools.** Everything an agent does in a room beyond its task inbox lives here as a tool, so the parity capabilities are self-evidently *one collection* (not N scattered skills). Each tool is a thin **gateway-only** client verb sharing `_gateway.py`; the gateway/broker (box-side) owns the platform creds and does the privileged Matrix ops + authoritative membership enforcement.

> Collection name `agent-room-ops` (provider-agnostic; alts: `room-participant`, `agent-chat-io`). Platform-tied names (e.g. `matrix-agent`) are avoided.

Tools

| tool | purpose | parity vs a chat bot-client | | --- | --- | --- | | `read <room>` | pull recent room history | discord `att.save`-context / channel read | | `fetch <ref>` | inbound media → local path | discord inbound `att.save`→inbox | | `send <room> <path>` | outbound file/image upload | discord outbound `[file:]` | | `say <room> <text>` | post plain text, pinging **nobody** by design — status lines, an answer to the room; never a hand-off | discord plain channel message | | `mention <handle> <text> <room>` | resolve a handle, label or display name to the one mxid (directory → directory narrowed by the room → broker → roster), refuse on ambiguity, post `<mxid> — <text>` with `mentions` — the hand-off tool | discord `<@id>` ping | | `members <room>` | who is present (mxid, display name, kind), plus `unidentified`: rows dropped for having no user_id — the roster to pick from when `mention` finds no match | discord member list | | `agents` | this account's agent registry (`/v1/agents`), each row with its `owner` | — | | `react <room> <event>` | add an `m.reaction` (ack) | discord `add_reaction` (👀/✅) | | `unreact <room> <event>` | remove the agent's reaction | discord remove-on-reply | | `join <room>` | accept the agent's own pending invite | discord guild-join on invite |

On an install connected to several servers, a verb that names a room acts through the connection serving that room's server. `rooms`, `history`, `agents`, `resolve` and `events list|pull|stream` name none, so they act through the primary connection only.

python3 skills/agent-room-ops/room_ops.py read   '!room:hs' --limit 20 --agent '@a:hs'
python3 skills/agent-room-ops/room_ops.py fetch  'mxc://hs/abc' --room '!room:hs' --agent '@a:hs'
python3 skills/agent-room-ops/room_ops.py send   '!room:hs' /tmp/pic.png --caption 'fig 1' --agent '@a:hs'
python3 skills/agent-room-ops/room_ops.py react  '!room:hs' '$evt' --ack received --agent '@a:hs'
python3 skills/agent-r
Read more
@sonichi
Ships withsutando

My AI Stand — Realtime by Day, Rewriting Itself by Night. Summon my AI superpower. Voice, vision, screen, meetings, calls when I'm engaged. Learns my patterns, ships its own code when I'm not. Runs across my Macs, interacts with people & their Stands.

Stars on GitHub

Momentum

stars in total
401
Star history of sonichi/sutando on GitHub, a chart by star-history.com

Other skills on sutando.

ag2space-voice

ag2space-voice

s.space voice surface — binds the room the s.space client announces to the voice session's origin, so work delegated by voice in…

@sonichi@sonichiInstall Skill
agent-activity

agent-activity

Streams what the agent is doing into the room, as rows the desktop client renders in an **events drawer** above the composer…

@sonichi@sonichiInstall Skill
agent-registry

agent-registry

Local Agent Registry — a standalone, dependency-free service that tracks running Claude Code (and other) agent instances. Agents…

@sonichi@sonichiInstall Skill
answer-format

answer-format

Deterministic final-answer normalizer — a last-step pass for any task that ends in a *precise* answer (a number, a short string,…

@sonichi@sonichiInstall Skill
audio-transcribe

audio-transcribe

Transcribes audio files and voice notes to text via Gemini 2.5-flash. Integrates with Slack, Discord, and Telegram bridges so…

@sonichi@sonichiInstall Skill
bee-actions

bee-actions

Act back on the owner's Bee wearable — the TOOL half of the Bee integration (channels-vs-tools split). The Bee CHANNEL…

@sonichi@sonichiInstall Skill

More skills from other plugins.

agent-builder

agent-builder

Load immediately after an Agent intent, before the first agent_builder_* call. Governs how you create, configure, test, and…

n8n12d209k
@n8n-io@n8n-ioInstall Skill
browser-use

browser-use

Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…

@browser-use@browser-useInstall Skill
agent-browser

agent-browser

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…

@vercel-labs-2@vercel-labs-2Install Skill
add-anydoc

add-anydoc

Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when…

@nanocoai@nanocoaiInstall Skill

Questions about agent-room-ops.

Which coding agents can use agent-room-ops?
agent-room-ops installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.