Hermes CLI agent + autonomous Gmail/SMS responder - #1
Draft
hatcheric950 wants to merge 9 commits into
Draft
Conversation
Multi-provider chat CLI (Anthropic / OpenRouter / Nous) with interactive and single-query modes, session persistence with continue/resume, skill preloading, and git worktree isolation. https://claude.ai/code/session_01KDyqQtRNmWt1JfGAWLyNLW
Loads server definitions from ~/.hermes/mcp.json (or repo-local
./.hermes/mcp.json), spawns each enabled server over stdio, and exposes
its tools to the Anthropic provider via a tool_use loop. ${input:id}
placeholders resolve via HERMES_INPUT_<ID> env vars or an interactive
prompt, enabling drop-in use of configs like hostinger-api-mcp.
https://claude.ai/code/session_01KDyqQtRNmWt1JfGAWLyNLW
Add .claude SessionStart hook that installs the project (editable + dev extras) and reports readiness, written to never fail a session. Add dev extra and pytest config to pyproject, a minimal offline test suite (session round-trip, provider routing, mcp.json parsing), and document the full install/test flow in the README. https://claude.ai/code/session_01KDyqQtRNmWt1JfGAWLyNLW
Publish hermes to PyPI on v* tags via a GitHub Actions workflow using trusted publishing (OIDC, no stored token). Build and publish run as separate jobs so the id-token scope stays off the build step. The package version is now single-sourced from hermes.__version__ via setuptools dynamic metadata, and the workflow fails fast if the pushed tag disagrees with it. https://claude.ai/code/session_01KDyqQtRNmWt1JfGAWLyNLW
Introduces a long-running daemon under `hermes watch` that listens for inbound Gmail (IMAP IDLE) and Twilio SMS (signed webhook) and uses the existing Hermes Agent to draft and send personalised replies. Hardened by an allowlist, denylist patterns, hourly/per-sender rate caps, daily SMS budget, dedup, and a kill-switch file. Ships in shadow mode by default — the pipeline drafts replies but does not send until HERMES_MODE=live is set. Includes systemd unit + Traefik route + env.example for the Hostinger VPS deploy, plus tests for policy gating, shadow-mode behavior, and Twilio signature verification.
- hermes audit reads /var/lib/hermes/state.db and prints decisions, senders, sent/cost, and (with --show-drafts) the LLM's drafted reply. Filters: --since-hours, --decision, --sender. - README: new 'Autonomous responder' section covering safety rails, the one-shot deploy command, and the shadow-review workflow.
- 'hermes watch --check' validates /etc/hermes/env and allowlist.yaml before starting listeners, with a per-field PASS/WARN/FAIL report. Catches missing/malformed secrets, empty allowlist, present PAUSE file, etc. — the first thing to run after editing env on the VPS. - .github/workflows/tests.yml runs pytest on PRs and main pushes.
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.
Summary
Two layers on this branch:
1. Original Hermes CLI agent — multi-provider (Anthropic, OpenRouter, Nous), session-backed (
-c/-r), MCP toolsets, skills, optional git worktree. Entry:hermes chat.2. Autonomous read-and-reply daemon (
hermes watch) — new insrc/hermes/watcher/. Listens for inbound Gmail via IMAP IDLE and Twilio SMS via signed webhook, runs each message through a policy gate → classifier → the existingAgent, then sends a reply via SMTP / Twilio REST. Ships in shadow mode by default: full pipeline runs and drafts are logged, but no replies are sent untilHERMES_MODE=live.Safety rails (all wired in, not optional)
/etc/hermes/allowlist.yaml(emails — incl.*@domainglobs — and E.164 phones) get replies.noreply@*,mailer-daemon@*, short-code numbers, etc. are always dropped.seen(message_id)— never reply twice to the same Gmail Message-ID or Twilio MessageSid.touch /etc/hermes/PAUSEblocks all sends instantly.Layout
src/hermes/watcher/{settings,state,policy,classifier,responder,pipeline,gmail,smtp,twilio_webhook,twilio_sender,types,__main__}.pysrc/hermes/cli.py— addswatchsubcommanddeploy/bootstrap.sh— one-shot installer for the VPS (apt deps, venv, systemd unit, cloudflared, dir scaffold)deploy/hermes-watcher.service,deploy/traefik/hermes-watcher.yml,deploy/allowlist.example.yaml,deploy/env.exampletests/test_policy.py,tests/test_pipeline_shadow.py,tests/test_twilio_verify.py— 21 tests, all greenDeploy
Ubuntu 24.04 VPS, SSH'd in as root:
curl -fsSL https://raw.githubusercontent.com/hatcheric950/T/claude/setup-hermes-agent-emVQB/deploy/bootstrap.sh | bashThe installer prints the post-install checklist (fill
/etc/hermes/env,cloudflared tunnel login, point Twilio webhook, run for 24h in shadow, flip to live). Cloudflare Tunnel terminates TLS — no Let's Encrypt or A-record juggling required.Test plan
pytest— 21 tests pass (policy gating, shadow-mode no-send, Twilio signature verify, dedup)hermes watchstarts under systemd;curl https://<host>/healthzreturns{"status":"ok","mode":"shadow"}journalctlshowsdrop_not_allowlisted, no sendshadow_would_sendwith drafted body in audit log, still no sendtouch /etc/hermes/PAUSE→ next inbound isdrop_pausedHERMES_MODE=live, restart, confirm one real replyhttps://claude.ai/code/session_01KDyqQtRNmWt1JfGAWLyNLW
Generated by Claude Code