#+title: emacs-hermes

[[https://elpa.nongnu.org/nongnu/hermes.svg]]

An Emacs front-end for Hermes Agent, driven over the dashboard/TUI gateway.

+ =M-x hermes= dashboard with =keymap-popup= actions
+ ERC/emacs-jabber-style chat buffer with streaming replies
+ Slash commands, approvals, clarify/sudo/secret prompts, interrupts, and steering
+ Markdown-rendered replies; diffs open as =[View Diff]= in =diff-mode=
+ *Kanban*, sessions, profiles, MCP, cron, inventory, and rollback browsers
+ Configurable desktop notifications with click-to-open actions
+ Provider onboarding (API keys and provider accounts) from Emacs
+ /Optional/ local eval endpoint (=hermes-exec=) for the Hermes Emacs MCP bridge

* Installation

Hermes Agent with dashboard/TUI gateway support is required.
  - See the [[https://hermes-agent.nousresearch.com/docs/getting-started/quickstart][Hermes Agent quickstart]] for installation and initial setup.

** NonGNU ELPA

=hermes= is available via [[https://elpa.nongnu.org/nongnu/hermes.html][NonGNU ELPA]].

Install it with =M-x package-install RET hermes=.

** package-vc (Emacs 30+)

#+begin_src emacs-lisp
  (use-package hermes
    :vc (:url "https://git.thanosapollo.org/emacs-hermes" :lisp-dir "lisp")
    :custom (hermes-dashboard-transport-url "http://127.0.0.1:9119"))
#+end_src

* Usage

=M-x hermes= opens the dashboard and =M-x hermes-chat= opens a chat buffer:
- =RET= to send.
- =/= for slash commands.
- =C-c C-o= for the actions menu.
- =M-x hermes-close= closes local connections and Hermes buffers for restart.

Point =hermes-dashboard-transport-url= at your running dashboard:

#+begin_src sh
  hermes dashboard --no-open --tui --host 127.0.0.1 --port 9119
#+end_src

* Dashboard authentication

=hermes-dashboard-transport-remote-auth-method= defaults to =auto=:

- Loopback dashboards (=127.0.0.1= / =localhost=) can spawn or attach without extra credentials when the dashboard is not gated.
- Remote or gated dashboards probe =/api/status= and choose one of the supported attach paths below.

Supported gated attach paths:

1. *Native PKCE OAuth* — when =/api/status= advertises =native_pkce=, Emacs opens the system browser, completes the official =/auth/native/*= loopback flow, stores access/refresh tokens in auth-source under login/port =hermes-dashboard-native=, authenticates REST with =Authorization: Bearer=, and mints a short-lived WebSocket ticket. Failed or cancelled login does not overwrite prior stored tokens.
2. *Basic/password* — auth-source entry with port =hermes-dashboard-basic=, login =username=, and password secret. Emacs posts password-login cookies and mints a WebSocket ticket.
3. *Legacy session token* — auth-source entry with login/port =hermes-dashboard-token= and the token as secret, or environment variable =HERMES_DASHBOARD_SESSION_TOKEN=. Used for ungated dashboards and forced =token= mode.

Force a path with:

#+begin_src emacs-lisp
  (setq hermes-dashboard-transport-remote-auth-method 'native) ; or 'basic / 'token / 'auto
#+end_src

Generic auth-source examples (replace host/port/values; never commit real secrets):

#+begin_src conf
  machine https://dashboard.example.org:9119 login hermes-dashboard-native password {"access_token":"…","refresh_token":"…","expires_at":0,"provider":"oauth","user_id":""}
  machine https://dashboard.example.org:9119 login admin password s3cret port hermes-dashboard-basic
  machine https://dashboard.example.org:9119 login hermes-dashboard-token password SESSIONTOKEN port hermes-dashboard-token
#+end_src

If a gated dashboard advertises neither =native_pkce= nor a basic provider, Emacs refuses attach with an actionable error. Cookie-only browser OAuth without =native_pkce= remains unsupported.

* Optional Emacs bridges

The dashboard/TUI connection above drives chat and management.  Two separate,
optional paths let Hermes call into Emacs:

- =hermes-capabilities= is the native dashboard capability-provider path.
- =hermes-exec= is the HTTP eval endpoint used by the external stdio MCP bridge,
  [[https://git.thanosapollo.org/hermes-emacs-plugin][hermes-emacs-plugin]].

To use the stdio MCP bridge, install it from Git, enable the endpoint, then copy
its registration command:

#+begin_src sh
  pipx install git+https://git.thanosapollo.org/hermes-emacs-plugin
#+end_src

#+begin_src emacs-lisp
  (require 'hermes-exec)
  (setq hermes-exec-enabled t
        hermes-exec-host "127.0.0.1"
        hermes-exec-require-approval t)
  (hermes-exec-start)
  ;; M-x hermes-exec-show-bridge-command
#+end_src

The generated command registers the packaged =hermes-emacs-mcp= entry point.
For a non-loopback private address, also set the same =EMACS_EXEC_TOKEN= for
Emacs and the bridge.  Do not expose the eval endpoint on a public interface.

Desktop notifications default to completed chat replies, terminal chat errors,
input requests, background-task results, and Kanban states that need attention.
Cron failures use the same policy when cron failure monitoring is enabled.
They are suppressed when the target buffer is already visible on the focused
frame. Customize the event set, or set it to =nil= to disable notifications:

#+begin_src emacs-lisp
  (setq hermes-notifications-events
        '(chat-reply chat-error prompt background
          kanban-attention cron-failure kanban-done))
#+end_src
