A Hermes Agent platform plugin that connects a Hermes to Rowboat Spaces as a member of your team. People @mention it in a space; it answers in the thread, reads the thread for context, uses the Spaces tools, and shows what it is doing while it works.
It follows Hermes's guide for adding a platform adapter through the plugin path, and needs no packages beyond what every Hermes ships with. The connection is outbound only: a WebSocket from your Hermes to your Rowboat org, so it works behind NAT and on hosted Hermes.
In Rowboat, open Agents → Add agent → Hermes. It creates the agent and shows these steps with your values filled in.
-
Save the Rowboat settings. Run these in a terminal where Hermes runs:
hermes config set ROWBOAT_URL 'https://acme.rowboatlabs.com' hermes config set ROWBOAT_AGENT_KEY 'rbk_…' hermes config set ROWBOAT_HOME_CHANNEL '01M…'
On hosted Hermes, add the same three on the dashboard's Keys page instead.
-
Send your Hermes this message:
Connect yourself to Rowboat: read https://raw.githubusercontent.com/rowboatlabs/hermes-rowboat/main/SETUP.md and follow it.It saves the rest of the settings, installs this plugin, and tells you when it's done. (SETUP.md is what it reads.)
-
Restart it: send
/restart, or press Restart Gateway on the dashboard. -
In Rowboat, add the agent to a space and mention it.
Do the same by hand, then continue from step 3.
In a terminal where Hermes runs:
hermes config set ROWBOAT_ALLOW_ALL_USERS true
hermes config set ROWBOAT_OWNER_COMMANDS true
hermes config set mcp_servers.rowboat.url '${ROWBOAT_URL}/mcp'
hermes config set mcp_servers.rowboat.headers.Authorization 'Bearer ${ROWBOAT_AGENT_KEY}'
hermes config set display.platforms.rowboat.tool_progress off
hermes config set display.platforms.rowboat.show_reasoning false
hermes config set display.platforms.rowboat.long_running_notifications false
hermes config set display.platforms.rowboat.busy_ack_detail false
hermes plugins install rowboatlabs/hermes-rowboat --enable
hermes skills install rowboatlabs/rowboat/skills/rowboat-spaces --yesOr on the Hermes dashboard:
-
Plugins → Install from GitHub:
rowboatlabs/hermes-rowboat, with Enable after install on. -
Channels → Rowboat: set
ROWBOAT_ALLOW_ALL_USERSandROWBOAT_OWNER_COMMANDStotrue, and turn the channel on. (The plugin's settings, the three from step 1 included, live on this card from now on; the Keys page hides them.) -
MCP → Add server: name
rowboat, URL<your ROWBOAT_URL>/mcp, auth Bearer token = the agent key. -
Config (YAML mode): under the existing
display:, add:platforms: rowboat: tool_progress: 'off' show_reasoning: false long_running_notifications: false busy_ack_detail: false
-
The Rowboat skill: run
hermes skills install rowboatlabs/rowboat/skills/rowboat-spaces --yeswhere Hermes runs, or ask your Hermes to run it.
Or with the setup wizard: hermes gateway setup, then choose Rowboat. It asks for the three settings and saves the rest. Then install the skill: hermes skills install rowboatlabs/rowboat/skills/rowboat-spaces --yes.
The mcp_servers.rowboat entry gives Hermes the Spaces tools (read threads, search, post, files, …) on the same key. The display.platforms.rowboat settings give Rowboat the quiet defaults Hermes uses for Slack: no tool-progress messages (Rowboat shows the current step on the thread instead), no reasoning blocks, and no long-running or busy notices. Hermes's in-between messages still post, as they do in Slack.
One Hermes profile is one Rowboat agent. The same agent can be added to any number of spaces in its org. To connect one Hermes to a second org, give that org its own Hermes profile with its own agent key; two profiles on one key are refused.
Rowboat decides when the agent is invoked (a mention), holds a queue per thread, and delivers each invocation to this plugin over its live connection, with a list every minute as the backstop. The plugin turns it into a Hermes turn:
- One thread is one Hermes session, shared by everyone in it, DMs included. The mention arrives with what the thread said since the agent last spoke there.
- People arrive as mention tokens (
[@Harsh](#member:…)), the sender and the thread's authors included, so the agent mentions someone by copying one: a bare@Harshreaches no one. A mention of itself is dropped only before a command, so@Hermes /modelarrives as/model; elsewhere it stays, and the agent is told its own token. Therowboat-spacesskill, which setup installs, teaches it the rest: when to mention, hand-offs to other agents, threads, the tools. - The answer is a message in the thread, as the agent. Hermes's edits are edits.
- Progress is Rowboat's: Hermes's 👀 and ✅/❌ land on the message as the agent's reactions, its typing shows as typing in the thread, and its status phrase ("is running the tests…") shows on the thread. The invocation ends when Hermes releases the thread's session.
- Files come as Hermes's own media. Images and files attached to the mention are fetched on the agent's key: images go to the model, other files arrive as paths Hermes reads when it needs them. Files earlier in the thread are listed with the address to fetch them.
- A DM with the agent needs no mention: every message there reaches it.
- Stop in Rowboat is Hermes's own
/stop. - Model and Effort are options on the mention. Rowboat offers Hermes's models (what its
/modelpicker lists, the configured model first, at most 100 shared across providers) and its reasoning levels. Picked, they apply to that one turn, set the way Hermes's/model --oncesets a model, so nothing is posted about them. A mention without them runs on Hermes's configuration, whatever an earlier mention picked; the owner's defaults for the agent in Rowboat come with every mention. A model Hermes no longer offers or can't reach is skipped and logged, and the turn runs on the configuration. Hermes commands take no options. The model list is read again every five minutes. - Approvals are cards in the thread. When Hermes asks before running a command, the card shows the command and why, with Hermes's choices: Allow once, Allow in this thread, Always allow, Deny (with a note back to Hermes). Any person who can see the card can decide, and the card then says who did. When Hermes's own approval timer runs out, the card says it expired.
- One key, one kind of agent. The plugin refuses a key of an agent Rowboat reaches another way (such as a Replicas agent), which would otherwise answer its mentions twice.
- Restarts don't strand a thread. A turn Hermes resumes after a restart is followed to its answer; one it can't resume is reported failed as soon as Hermes is back, so the next mention in that thread isn't held up.
Anyone allowed to talk to the agent can make your Hermes act with its tools, on the machine it runs on. Choose who with ROWBOAT_ALLOW_ALL_USERS or ROWBOAT_ALLOWED_USERS, and consider a dedicated Hermes profile with restricted platform_toolsets.rowboat for a shared space. Hermes commands (/model, /reset, …) run from Rowboat only for the agent's owner, and only with ROWBOAT_OWNER_COMMANDS on: nobody else can change your Hermes from a space. Approvals are different: any person who can see an approval card in a space can decide it, as anyone who can talk to Hermes in Slack can, so keep a Hermes that runs on your own machine out of spaces you don't trust.
Sending files back into Rowboat, and Hermes's clarify buttons (they fall back to text).
Drop the folder into ~/.hermes/plugins/rowboat-platform/, run hermes plugins enable rowboat-platform, then hermes gateway restart. Check it with hermes plugins validate ..
Tests run on Hermes's own Python against a hermes-agent checkout, with the test tools kept outside this folder (the validator scans everything in it):
uv pip install --target /tmp/rowboat-testdeps --python ~/.hermes/hermes-agent/venv/bin/python "pytest>=8,<9" "pytest-asyncio>=0.24,<1"
PYTHONPATH=/tmp/rowboat-testdeps:$HOME/.hermes/hermes-agent ~/.hermes/hermes-agent/venv/bin/python -m pytest -p no:cacheprovider testsApache-2.0.
