Repository navigation
feat(mcp): optional hermes domain to read and message the owner's Hermes - #1516
Merged
Juliusolsson05 merged 5 commits intoOct 15, 2026
Merged
Conversation
Refs #1512 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r's Hermes Agents get hermes_conversations, hermes_read and hermes_send through a main-side bridge over the stored Hermes sign-in, so no credential reaches a model. Off by default and parent-held-only. An agent writes to a conversation of its own unless told otherwise. A send is queued, waits for the stored reply, and reports an approval request instead of answering it. Tests replay recorded Hermes sessions S4 and S10. Refs #1512 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round on #1516. A send now finds its own user row by id, or by text when Hermes queued it, and returns only the answer up to the next message. Waits stay under MCP clients' own 60 s timeouts (25 s default, 50 s cap). A turn that ends without text reports ended. Unknown or deleted ids are checked over REST before any socket opens, so no junk conversations are created. Map writes are serialized and corruption-safe, and the map is keyed by the identity that survives an agent reload. Hermes' tool lines are scrubbed of credentials, and every message says an agent sent it. The Telegram lookup no longer has side effects. Refs #1512 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
Final disposition (merging via batch/hermes-gaps-2026-10-15, owner-approved 2026-10-15). Tested head |
Juliusolsson05
changed the base branch from
main
to
batch/hermes-gaps-2026-10-15
October 15, 2026 00:29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1512
Problem
The owner runs a personal Hermes agent on a VPS, and Agent Code already holds the signed-in connection to it. Coding agents (Claude, Codex, OpenCode, Grok, Pi) had no way to ask Hermes something or to read what it said.
What changed
A new built-in MCP domain,
hermes:hermes_conversations: the connection, whether a Telegram thread exists, the agent's own conversation id, and recent conversations.hermes_read: the last N messages as text, with one line per tool Hermes ran.hermes_send: one queued submit, which never interrupts a running turn. By default it waits for the stored reply (5 min default, 15 max) and returns the reply plus the tools Hermes ran. Other outcomes:awaiting_approval, with the request's own words, when Hermes asks for approval. The request is left for the owner and never answered.held, when the user's phone turn is busy on the Telegram thread. Nothing is sent.still_runningon timeout.Defaults (UNCONFIRMED product calls; see the plan):
Agent Code · <its Goal>, never the Telegram thread unless asked. The agent→conversation map lives in main (hermes/agent-conversations.json), and a deleted conversation is adopted again.Design
HermesHeadless(the client the panes use) and stops it, so queued submits, lane holds and history reconciliation behave exactly as in a pane. Nothing stays connected between calls.row_id.Tests (recorded Hermes v0.22.0 sessions replayed by a fake server)
queued: true→ the stored reply "All three tools ran." and 3 tools. A new bridge instance then reads it back throughsession.resume, not a second create.awaiting_approvalcarries "delete in root path: rm -r …". The bridge never answers it.Checks:
npm run typecheck: passes.vitest src/mcp src/main/hermes: 171/171.Verification boundary
The app was not launched, and the owner's real VPS was not called.
Review round (two reviewers, one round)
All findings are fixed. The full list is in
docs/plans/2026-10-14-hermes-mcp-domain.md.hermes_sendreturns only its own reply. It finds its user row by id, or by text when Hermes queued it (recorded S20), and stops at the next message.still_running. A second send to one conversation reportsbusyafter 10 s. A turn that ends without an answer reportsended.latest-descendant) before any socket opens. That lookup also follows compression.[Sent by an Agent Code agent: …](UNCONFIRMED).Tests: 44/44 in
src/main/hermes+hermesTools. Every new guard is mutation-checked (6/6 caught). Not replay-tested: a lane hold (T4) and an interrupted turn (S7, interrupted by the client).🤖 Generated with Claude Code