H繁中版
文件核心功能web dashboard
<!-- Source: https://hermesbible.com/docs/user-guide/features/web-dashboard -->

章節:Core Features · 網址:https://hermesbible.com/docs/user-guide/features/web-dashboard

Web Dashboard 是一個基於瀏覽器的 UI,用於管理你的 Hermes Agent 安裝。你可以透過簡潔的 Web 介面配置設定、管理 API 金鑰和監控 Session,而不需要編輯 YAML 檔案或執行 CLI 指令。

TIP

Hosted 模式認證使用 Nous Portal OAuth;如果你也希望 Dashboard 連接到真正的後端,hermes setup --portal 可以同時設定模型和工具閘道。請參閱 Nous Portal

快速開始

hermes dashboard

這會啟動一個本地 Web 伺服器,並在瀏覽器中開啟 http://127.0.0.1:9119。Dashboard 完全在你的機器上運行 — 不會有任何資料離開 localhost。

選項

Flag預設值說明
--port9119Web 伺服器運行的連接埠
--host127.0.0.1綁定位址
--no-open不自動開啟瀏覽器
--insecureoff允許綁定到非 localhost 的主機(危險 — 會在網路中暴露 API 金鑰;請搭配防火牆和強認證使用)
--isolatedoff從具名 Profile 啟動時(worker dashboard),運行專屬的 Profile 伺服器,而不是路由到機器級 Dashboard
# 自訂連接埠
hermes dashboard --port 8080

# 綁定到所有介面(在共享網路上請謹慎使用)
hermes dashboard --host 0.0.0.0

# 啟動但不開啟瀏覽器
hermes dashboard --no-open

管理多個 Profile

Dashboard 是一個機器級的管理介面:一個伺服器管理該機器上的所有 Profile。側邊欄中的 Profile 切換器(當存在多個 Profile 時可見)決定管理頁面讀寫哪個 Profile — Config、API Keys、Skills、MCP、Models 和 Chat 分頁都遵循此切換。當選取非 Dashboard 所屬的 Profile 時,琥珀色橫幅會顯示正在管理的 Profile 名稱,確保寫入目標永遠不會含糊。

選擇狀態記錄在 URL 中(?profile=<name>),所以像 http://127.0.0.1:9119/skills?profile=worker 這樣的深層連結會帶著預選的切換狀態,並在重新整理後保留。

從 Profile 別名啟動 Dashboard 會路由到機器級 Dashboard,而不是啟動第二個伺服器:

worker dashboard
# → 已經在執行:在 ?profile=worker 開啟瀏覽器
# → 尚未執行:   啟動機器級 Dashboard 並預選 "worker"

加上 --isolated 可以選擇退出,運行一個限定於該 Profile 的專屬伺服器(統一前的預設行為 — 適用於你想以不同認證方式暴露不同 Profile Dashboard 的情況)。

Chat 分頁也遵循切換器:有範圍限定的聊天會以選取 Profile 的 HERMES_HOME 啟動其 PTY 子程序,因此對話會使用該 Profile 的模型、技能、記憶和 Session 歷史。切換 Profile 會啟動全新的終端 Session。

以下功能維持 Profile 級別,被切換器吸收:閘道程式(透過 hermes -p <name> gateway … 管理)、每個 Profile 的 Session 資料庫,以及 Cron 排程器(Cron 頁面已透過自己的篩選器跨 Profile 聚合)。

前置需求

預設的 hermes-agent 安裝不包含 HTTP 堆疊或 PTY 輔助工具 — 這些是可選的額外套件。Web Dashboard 需要 FastAPI 和 Uvicorn(web 額外套件)。Chat 分頁還需要 ptyprocess 來在偽終端後方啟動內建 TUI(POSIX 上的 pty 額外套件)。一次安裝兩者:

pip install 'hermes-agent[web,pty]'

web 額外套件會安裝 FastAPI/Uvicorn;pty 會安裝 ptyprocess(POSIX)或 pywinpty(原生 Windows — 注意內建 TUI 本身仍需要 WSL)。pip install hermes-agent[all] 包含兩者,如果你也需要訊息/語音等功能,這是最簡單的方式。

當你執行 hermes dashboard 但缺少依賴時,它會告訴你需要安裝什麼。如果前端尚未建置且 npm 可用,首次啟動時會自動建置。

Chat 分頁是每次 hermes dashboard 啟動的一部分 — 內建的瀏覽器聊天面板(透過 PTY/WebSocket 運行 TUI)始終可用,無需額外 flag。

頁面

Status

首頁顯示安裝的即時概覽:

  • Agent 版本和發布日期
  • 閘道狀態 — 運行中/已停止、PID、已連線的平台及其狀態
  • 活躍 Session — 過去 5 分鐘內活躍的 Session 數量
  • 近期 Session — 最近 20 個 Session 的列表,包含模型、訊息數、Token 使用量和對話預覽

Status 頁面每 5 秒自動重新整理。

Chat

Chat 分頁將完整的 Hermes TUI(與 hermes --tui 相同的介面)直接嵌入瀏覽器。你在終端 TUI 中能做的一切 — 斜線指令、模型選擇器、工具呼叫卡片、Markdown 串流顯示、clarify/sudo/approval 提示、主題佈景 — 在這裡完全相同地運作,因為 Dashboard 執行的是真正的 TUI 二進位檔,並透過 xterm.js 的 WebGL 渲染器將 ANSI 輸出呈現為像素完美的格點佈局。

運作方式:

  • /api/pty 開啟一個使用 Dashboard Session Token 認證的 WebSocket
  • 伺服器在 POSIX 偽終端後方啟動 hermes --tui
  • 按鍵輸入傳送到 PTY;ANSI 輸出串流回瀏覽器
  • xterm.js 的 WebGL 渲染器將每個儲存格繪製到整數像素網格上;滑鼠追蹤(SGR 1006)、全形字元(Unicode 11)和方框繪圖字形全部原生渲染
  • 調整瀏覽器視窗大小會透過 @xterm/addon-fit 附加元件調整 TUI 大小

恢復既有 Session:Sessions 分頁,點擊任何 Session 旁的播放圖示(▶)。這會跳轉到 /chat?resume=<id> 並以 --resume 啟動 TUI,載入完整歷史記錄。

前置需求:

  • Node.js(與 hermes --tui 相同的需求;TUI 繫束在首次啟動時建置)
  • ptyprocess — 由 pty 額外套件安裝(pip install 'hermes-agent[web,pty]',或 [all] 包含兩者)
  • POSIX 核心(Linux、macOS 或 WSL2)。/chat 終端面板特別需要 POSIX PTY — 原生 Windows Python 沒有等效功能,所以在原生 Windows 安裝中,Dashboard 的其他功能(Sessions、jobs、metrics、config 編輯器)都能運作,但 /chat 分頁會顯示橫幅告知你需要使用 WSL2。

關閉瀏覽器分頁後,PTY 會在伺服器上被正常回收。重新開啟時會啟動全新的 Session。

要將 Hermes Desktop 指向在另一台機器上運行的 Dashboard 而非其內建後端,請參閱下方的遠端後端段落。

將 Hermes Desktop 連接到遠端後端

Hermes Desktop 通常會啟動自己的本地後端,但它也可以透過 Settings → Gateway → Remote gateway 連接到在遠端機器(VM、家庭伺服器等)上運行的 Dashboard。這是最常見的「Desktop 說後端已就緒但聊天永遠無法運作」報告的來源,因為 Desktop 的就緒檢查驗證的內容比實際即時聊天連接所需的還少。

INFO — 前置需求:遠端主機上必須有一個正在運行的 hermes dashboard

Desktop 連接的「遠端後端」就是在遠端機器上運行的 hermes dashboard 程序 — 與本頁面文件記載的是同一個伺服器。它必須先啟動並可達,下方的步驟才有效;Desktop 是連接到它,而不是為你啟動它。讓它在 systemd/tmux/等等下運行,以便在登出和重啟後存活。閘道(Telegram/Discord/Slack/等等)是一個獨立的長期運行程序 — 如果你依賴訊息通道,請獨立啟動它;它不是桌面應用連接的對象。

Desktop 的「遠端後端已就緒」探測只會呼叫 GET /api/status,這是一個公開端點 — 只要任何 Dashboard 在主機上運行,它就會回應。即時聊天連接是到 /api/ws(和 /api/pty)的獨立 WebSocket,而該 Socket 受狀態探測從未觸及的兩個額外檢查控制:

  1. 你必須已認證。 當 Dashboard 綁定到非迴環位址時,會啟用其認證閘道。用使用者名稱和密碼保護它(使用內建的 username/password provider);Desktop 登入一次後,透過一次性票券重用該 Session 進行 WebSocket 連接。如果沒有設定 Provider,非迴環的 Dashboard 會啟動時失敗關閉
  2. 綁定主機必須允許客戶端且與 Host 標頭匹配。 迴環綁定(127.0.0.1)只接受迴環客戶端,所以遠端機器會在 Socket 層被拒絕,無論憑證如何。請綁定到非迴環位址(--host 0.0.0.0),讓對端 IP 防護允許遠端客戶端通過。你在 Desktop 輸入的遠端 URL 必須透過與綁定相同的主機到達 Dashboard — DNS 重新綁定防護要求 Host 標頭匹配。

遠端 Dashboard 設定

設定使用者名稱和密碼,然後在可達的位址上啟動 Dashboard。使用 systemd 服務:

[Service]
EnvironmentFile=%h/.hermes/.env
ExecStart=/path/to/venv/bin/python -m hermes_cli.main dashboard \
    --host 0.0.0.0 --port 9119 --no-open

~/.hermes/.env 內容為:

HERMES_DASHBOARD_BASIC_AUTH_USERNAME=admin
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD=choose-a-strong-password
HERMES_DASHBOARD_BASIC_AUTH_SECRET=<32+ random bytes; openssl rand -base64 32>

然後在 Desktop 中輸入 Remote URL(例如 http://VM_IP:9119)並使用該使用者名稱和密碼登入。完整的設定選項請參閱 username/password provider 段落。

TIP — 重試 Desktop 前先驗證閘道已啟用

從任何機器檢查 Dashboard 是否宣傳 username/password provider:

curl -s http://VM_IP:9119/api/status | jq '.auth_required, .auth_providers'
# true
# ["basic"]
  • auth_required: true 且 providers 列表中有 "basic" → Desktop 的登入流程將正常運作。
  • auth_required: false → 綁定是迴環的,或閘道未啟用。請綁定到非迴環位址。
  • auth_required: true 但沒有 "basic" provider → username/password 環境變數未載入。請先修正這些設定。

如果 /api/status 顯示閘道已啟用且有 "basic" provider,但 Desktop 仍然在登入後無法連接,問題已超出基本設定範圍 — 請取得最新的 desktop.log(Settings → Gateway → Open logs)以及同一重試時間段內的 Dashboard 日誌,查找 /api/ws 的關閉代碼(4403 = 聊天 WS 被請求防護拒絕,例如 Host/對端不匹配;4401 = WS 票券未通過認證)。

Config

一個表單式的 config.yaml 編輯器。所有 150+ 個配置欄位都從 DEFAULT_CONFIG 自動發現,並組織成分頁類別:

Config 管理頁面 — 左側是分類篩選器,右側是自動發現的欄位

  • model — 預設模型、供應商、基礎 URL、推理設定
  • terminal — 後端(local/docker/ssh/modal)、逾時、shell 偏好
  • display — 佈景、工具進度、resume 顯示、spinner 設定
  • agent — 最大迭代次數、閘道逾時、服務層級
  • delegation — 子代理限制、推理努力程度
  • memory — Provider 選擇、上下文注入設定
  • approvals — 危險指令審批模式(ask/yolo/deny)
  • 以及更多 — config.yaml 的每個段落都有對應的表單欄位

具有已知有效值的欄位(terminal backend、skin、approval mode 等)渲染為下拉選單。布林值渲染為切換開關。其他所有欄位都是文字輸入。

操作:

  • Save — 立即將變更寫入 config.yaml
  • Reset to defaults — 將所有欄位還原為預設值(在你點擊 Save 之前不會儲存)
  • Export — 以 JSON 下載目前的設定
  • Import — 上傳 JSON 設定檔以替換目前的值

TIP

設定變更會在下一個 Agent Session 或閘道重啟時生效。Web Dashboard 編輯的與 hermes config set 和閘道讀取的是同一個 config.yaml 檔案。

API Keys

管理儲存 API 金鑰和憑證的 .env 檔案。金鑰按類別分組:

  • LLM Providers — OpenRouter、Anthropic、OpenAI、DeepSeek 等
  • Tool API Keys — Browserbase、Firecrawl、Tavily、ElevenLabs 等
  • Messaging Platforms — Telegram、Discord、Slack bot tokens 等
  • Agent Settings — 非機密的環境變數,如 API_SERVER_ENABLED

每個金鑰顯示:

  • 是否目前已設定(附帶遮蔽的值預覽)
  • 該金鑰的用途說明
  • 供應商註冊/金鑰頁面的連結
  • 用於設定或更新值的輸入欄位
  • 用於移除金鑰的刪除按鈕

進階/少用的金鑰預設隱藏在切換開關後方。

Sessions

瀏覽和檢查所有 Agent Session。每一列顯示 Session 標題、來源平台圖示(CLI、Telegram、Discord、Slack、cron)、模型名稱、訊息數、工具呼叫數,以及距上次活躍的時間。活躍 Session 以脈動徽章標示。

  • Search — 使用 FTS5 跨所有訊息內容進行全文搜尋。結果顯示帶有突顯的摘要片段,展開時自動捲動到第一個匹配的訊息。
  • Stats — 摘要列顯示總 Session 數、資料庫中活躍的數量、已封存數量、總訊息數,以及按來源的分布。
  • Expand — 點擊 Session 以載入其完整訊息歷史。訊息按角色著色(user、assistant、system、tool),並以帶有語法突顯的 Markdown 呈現。
  • Tool calls — 帶有工具呼叫的 assistant 訊息顯示可收合的區塊,包含函數名稱和 JSON 參數。
  • Rename — 行內設定或清除 Session 標題(鉛筆圖示)。
  • Export — 以 JSON 下載 Session(中繼資料 + 完整訊息歷史)(下載圖示)。
  • Prune — 頁首的「Prune old sessions」按鈕刪除超過 N 天的已結束 Session。
  • Delete — 使用垃圾桶圖示移除 Session 及其訊息歷史。

Sessions 管理頁面 — stats 列、prune,以及每列的 rename / export / delete

Logs

查看 Agent、閘道和錯誤日誌檔案,支援篩選和即時追蹤。

  • File — 在 agenterrorsgateway 日誌檔案間切換
  • Level — 按日誌級別篩選:ALL、DEBUG、INFO、WARNING 或 ERROR
  • Component — 按來源元件篩選:all、gateway、agent、tools、cli 或 cron
  • Lines — 選擇顯示的行數(50、100、200 或 500)
  • Auto-refresh — 切換每 5 秒輪詢新日誌行的即時追蹤
  • Color-coded — 日誌行按嚴重程度著色(紅色為錯誤、黃色為警告、暗色為除錯)

Analytics

從 Session 歷史計算的使用量和成本分析。選擇時間範圍(7、30 或 90 天)查看:

  • 摘要卡片 — 總 Token 數(輸入/輸出)、快取命中百分比、估計或實際總成本,以及總 Session 數和每日平均
  • 每日 Token 圖表 — 堆疊長條圖顯示每日輸入和輸出 Token 使用量,懸停時顯示明細和成本
  • 每日明細表 — 每日的日期、Session 數、輸入 Token、輸出 Token、快取命中率和成本
  • 各模型明細 — 顯示每個使用過的模型、其 Session 數、Token 使用量和估計成本的表格

Cron

建立和管理排程的 Cron 作業,按重複排程執行 Agent 提示。

  • Create — 填入名稱(可選)、提示、cron 表達式(例如 0 9 * * *),以及遞送目標(local、Telegram、Discord、Slack 或 email)
  • Job list — 每個作業顯示其名稱、提示預覽、排程表達式、狀態徽章(enabled/paused/error)、遞送目標、上次執行時間和下次執行時間
  • Pause / Resume — 在活躍和暫停狀態間切換作業
  • Edit — 開啟預填的對話框以變更作業的提示、排程、名稱或遞送目標
  • Trigger now — 在正常排程之外立即執行作業
  • Delete — 永久移除 Cron 作業

Profiles

建立和管理 Profiles — 擁有獨立設定、技能和 Session 的隔離 Hermes 實例。

  • Profile cards — 每個卡片顯示其模型/供應商、技能數、閘道狀態、描述和徽章(active、default、alias)
  • Create — 名稱 + 可選的 clone-from-default / clone-everything / no-bundled-skills、描述和模型;專屬的 Profile Builder 頁面(/profiles/new)提供完整流程(模型、MCP、技能)
  • Manage skills & tools — 跳轉到限定於該 Profile 的 Skills 頁面(設定側邊欄的 Profile 切換器)
  • Set as active — 翻轉固定的預設值,讓未來的 CLI/閘道執行使用(與 hermes profile use 相同)。這改變 Dashboard 管理的對象 — 那是 Profile 切換器的工作
  • Edit model / description / SOUL — 行內編輯器寫入該 Profile
  • Rename / Delete — 僅限具名 Profile

Skills

瀏覽、搜尋和切換已安裝的技能與工具組,並從 Hub 安裝新的技能。技能從 ~/.hermes/skills/ 載入並按類別分組。

  • Search — 按名稱、描述或類別篩選已安裝的技能和工具組
  • Category filter — 點擊類別藥丸縮小清單範圍(例如 MLOps、MCP、Red Teaming、AI)
  • Toggle — 用開關啟用或停用個別技能。變更在下一個 Session 生效。
  • Toolsets — 獨立視圖顯示內建工具組(檔案操作、網頁瀏覽等),包含其啟用/未啟用狀態、設定需求和包含的工具清單
  • Browse hub — 第三個視圖搜尋跨所有來源的技能 Hub(與 hermes skills search 相同),透過標識符安裝任何結果並附有即時安裝日誌,並提供「Update all」按鈕來重新整理已安裝的技能。

Skills 管理頁面 — Browse hub 視圖:搜尋、安裝和更新

MCP

無需 CLI 即可管理 MCP 伺服器。與 hermes mcp 讀取的 config.yaml 中相同的 mcp_servers 區塊。

你的 MCP 伺服器:

  • Add — 註冊 HTTP/SSE 伺服器(URL)或 stdio 伺服器(指令 + 參數),stdio 伺服器可選擇附加 KEY=VALUE 環境變數
  • Enable / disable — 在不刪除的情況下切換伺服器的開啟或關閉。已停用的伺服器保留在設定中,以便稍後重新啟用。在下一次閘道重啟時生效。
  • Test — 連接到伺服器、列出其工具並斷開連接 — 在 Agent 依賴它之前驗證連接
  • Remove — 從設定中刪除伺服器
  • 機密形態的環境變數值在清單視圖中被遮蔽

Catalog: 瀏覽 Nous 核准的 MCP 伺服器(內建的 optional-mcps/ 目錄),並一鍵安裝任何一個。需要 API 金鑰的項目會行內提示輸入;值會寫入 .env。這與 hermes mcp catalog / hermes mcp install 使用的是同一個目錄。

MCP 管理頁面 — 你的伺服器帶有 enable/disable 切換開關,加上安裝目錄

Webhooks

管理動態的 Webhook 訂閱。Webhook 平台必須先在訊息設定中啟用;頁面在未啟用時會顯示提示。

  • Create — 名稱、描述、事件篩選器、遞送目標、可選的直接遞送模式,以及 Agent 提示。建立時頁面顯示路由 URL 和一次性 HMAC 密鑰以供複製。
  • Enable / disable — 切換訂閱的開啟或關閉。已停用的路由保留在訂閱檔案中,但閘道會拒絕其傳入事件(403)。閘道會熱重新載入檔案,因此變更在下一個事件時生效 — 無需重啟。
  • List — 每個訂閱顯示其 URL、事件和遞送目標
  • Delete — 移除訂閱

Webhooks 管理頁面 — 帶有 enable/disable 切換開關的訂閱

Pairing

無需 CLI 即可核准和撤銷訊息使用者 — 這是遠端管理員將 Telegram/Discord/等等使用者加入配對閘道的方式。與 hermes pairing 完全對等。

  • Pending requests — 每個顯示平台、碼、使用者和時間,附帶 Approve 按鈕
  • Approved users — 每個顯示平台和使用者,附帶 Revoke 按鈕
  • Clear pending — 丢棄所有未完成的配對碼

Pairing 管理頁面

Channels

從瀏覽器將 Hermes 連接到任何訊息平台 — 與 hermes setup gateway 完全對等。頁面列出每個支援的通道(Telegram、Discord、Slack、Matrix、Mattermost、WhatsApp、Signal、BlueBubbles/iMessage、Email、SMS/Twilio、DingTalk、Feishu/Lark、WeCom、WeChat、QQ Bot、Yuanbao,加上 API server 和 webhook 端點)及其即時連接狀態。

  • Configure — 開啟每個平台的表單,包含該通道所需的確切欄位(bot token、app token、server URL、allowlist 等)。機密欄位以密碼輸入呈現並以遮蔽方式儲存;留空欄位保持現有值。必要欄位有標記並會驗證。「Setup guide」連結指向該平台的憑證文件。
  • Enable / disable — 切換通道的開啟或關閉。憑證保留在磁碟上;只有活躍狀態會改變。
  • Test — 檢查通道是否已設定、已啟用,並回報來自閘道的即時連接。
  • Restart gateway — 憑證寫入 ~/.hermes/.env,啟用標誌寫入 config.yaml;閘道在下一次重啟時連接每個已啟用的通道,你可以直接從頁面觸發重啟。

Channels 管理頁面 — 每個訊息平台都有狀態、enable 切換開關和平台專屬設定表單

System

一個整合的管理面板,用於安裝範圍的操作:

  • Host — 即時系統統計:OS / 核心、架構、主機名稱、Python 和 Hermes 版本、CPU 核心數 + 利用率、記憶體、Hermes 主目錄的磁碟使用量、運行時間和負載平均。(CPU/記憶體/磁碟在安裝 psutil 時提供;身分欄位始終顯示。)Hermes 版本顯示更新狀態徽章(最新 / 落後 N 個 commit)和Check for updates按鈕。當 git 或 pip 安裝有可用更新時,Update now按鈕會開啟確認對話框 — 顯示你將拉取多少 commit — 然後在背景執行 hermes update。在 Docker/Nix/Homebrew 安裝中,Dashboard 無法就地套用更新,因此會顯示正確的帶外指令。
  • Nous Portal — 登入狀態、活躍的推理供應商,以及 Tool Gateway 路由表(哪些工具透過 Portal 運行 vs. 本地運行),附帶管理訂閱的連結。hermes portal 的唯讀鏡像。
  • Skill curator — 背景技能維護狀態(active / paused、間隔、上次執行),附帶 pause/resume 和 run-now 按鈕。鏡像 hermes curator
  • Gateway — 啟動、停止和重啟訊息閘道,附帶即時狀態(running/stopped、PID、state)
  • Memory — 選擇外部記憶 Provider(或僅內建),以及重設內建的 MEMORY.md / USER.md 儲存
  • Credential pool — 新增和移除 Agent 輪替使用的旋轉 API 金鑰(按 Provider)。金鑰在清單中被遮蔽;原始值只會傳遞給 Agent。
  • Operations — 執行 doctor、安全審計、建立備份、從備份封存還原、更新技能、顯示 system-prompt 大小分析、產生支援資訊包,或為已棄用的設定遷移配置。每個操作會啟動一個背景動作,其即時日誌串流到頁面。
  • Checkpoints — 查看 /rollback shadow store 大小並修剪它
  • Shell hooks — 列出已設定的 hook 及其同意 + 可執行狀態、建立 hook(事件、指令、匹配器、逾時,附帶選擇性的同意授權),以及移除 hook。Hook 會執行任意指令,因此建立表單附帶安全警告,且 hook 只在同意授權後才會觸發。

System 管理頁面 — 主機統計和 Nous Portal 狀態

System 管理頁面 — skill curator、gateway、memory 和 credential pool

System 管理頁面 — operations、checkpoints 和 shell hooks

建立 Shell hook(注意同意勾選框和執行任意指令的警告):

New shell hook 對話框

WARNING — 安全

Web Dashboard 讀寫你的 .env 檔案,其中包含 API 金鑰和機密。它預設綁定到 127.0.0.1 — 只能從本機存取。如果你綁定到 0.0.0.0,網路上的任何人都可以查看和修改你的憑證。Dashboard 本身沒有認證機制。

/reload 斜線指令

Dashboard PR 也為互動式 CLI 新增了 /reload 斜線指令。透過 Web Dashboard 變更 API 金鑰(或直接編輯 .env)後,在活躍的 CLI Session 中使用 /reload 即可套用變更而無需重啟:

You → /reload
  Reloaded .env (3 var(s) updated)

這會將 ~/.hermes/.env 重新讀取到執行中程序的環境中。當你透過 Dashboard 新增了新的供應商金鑰並想立即使用時非常有用。

REST API

Web Dashboard 暴露一個前端使用的 REST API。你也可以直接呼叫這些端點進行自動化:

TIP — Profile 範圍限定的端點

管理端點系列 — /api/config/api/env/api/skills/api/tools/toolsets/api/mcp/api/model/{info,options,auxiliary,set} — 接受一個可選的 ?profile=<name> 查詢參數(或寫入時 JSON body 中的 "profile"),將讀寫限定到該 Profile 的 HERMES_HOME。省略 = Dashboard 自己的 Profile。未知的 Profile 名稱回傳 404/api/pty WebSocket 接受相同的參數以在選定的 Profile 下啟動聊天。

GET /api/status

回傳 Agent 版本、閘道狀態、平台狀態和活躍 Session 數量。

GET /api/sessions

回傳最近 20 個 Session 的中繼資料(模型、Token 計數、時間戳、預覽)。

GET /api/config

以 JSON 回傳目前的 config.yaml 內容。

GET /api/config/defaults

回傳預設配置值。

GET /api/config/schema

回傳描述每個配置欄位的 schema — 類型、描述、類別,以及適用時的 select 選項。前端使用此資訊為每個欄位渲染正確的輸入元件。

PUT /api/config

儲存新配置。Body:{"config": {...}}

GET /api/env

回傳所有已知的環境變數及其 set/unset 狀態、遮蔽的值、描述和類別。

PUT /api/env

設定環境變數。Body:{"key": "VAR_NAME", "value": "secret"}

DELETE /api/env

移除環境變數。Body:{"key": "VAR_NAME"}

GET /api/sessions/{session_id}

回傳單個 Session 的中繼資料。

GET /api/sessions/{session_id}/messages

回傳 Session 的完整訊息歷史,包含工具呼叫和時間戳。

GET /api/sessions/search

跨訊息內容的全文搜尋。查詢參數:q。回傳匹配的 Session ID 及帶有突顯的摘要片段。

DELETE /api/sessions/{session_id}

刪除 Session 及其訊息歷史。

GET /api/logs

回傳日誌行。查詢參數:file(agent/errors/gateway)、lines(數量)、levelcomponent

GET /api/analytics/usage

回傳 Token 使用量、成本和 Session 分析。查詢參數:days(預設 30)。回應包含每日明細和各模型聚合。

GET /api/cron/jobs

回傳所有已設定的 Cron 作業及其狀態、排程和執行歷史。

POST /api/cron/jobs

建立新的 Cron 作業。Body:{"prompt": "...", "schedule": "0 9 * * *", "name": "...", "deliver": "local"}

POST /api/cron/jobs/{job_id}/pause

暫停 Cron 作業。

POST /api/cron/jobs/{job_id}/resume

恢復已暫停的 Cron 作業。

POST /api/cron/jobs/{job_id}/trigger

在排程之外立即觸發 Cron 作業。

DELETE /api/cron/jobs/{job_id}

刪除 Cron 作業。

GET /api/skills

回傳所有技能及其名稱、描述、類別和啟用狀態。

PUT /api/skills/toggle

啟用或停用技能。Body:{"name": "skill-name", "enabled": true}

GET /api/tools/toolsets

回傳所有工具組及其標籤、描述、工具清單和活躍/已設定狀態。

Admin 端點

這些端點驅動 MCP、Channels、Webhooks、Pairing 和 System 頁面。全部位於與 /api/ 其餘部分相同的認證閘道後方。

方法與路徑用途
GET /api/mcp/servers列出已設定的 MCP 伺服器(環境變數值被遮蔽)
POST /api/mcp/servers新增伺服器。Body:{name, url?, command?, args?, env?, auth?}
POST /api/mcp/servers/{name}/test連接、列出工具、斷開連接
PUT /api/mcp/servers/{name}/enabled啟用/停用伺服器
DELETE /api/mcp/servers/{name}移除伺服器
GET /api/mcp/catalog瀏覽 Nous 核准的 MCP 目錄
POST /api/mcp/catalog/install安裝目錄項目(附帶必要環境變數)
GET /api/messaging/platforms列出每個訊息通道及其狀態 + 平台專屬設定欄位
PUT /api/messaging/platforms/{id}設定通道。Body:{enabled?, env?, clear_env?}(env 寫入 .env,enabled 寫入 config.yaml
POST /api/messaging/platforms/{id}/test回報通道是否已設定、已啟用且已連接
GET /api/pairing列出待處理和已核准的訊息使用者
POST /api/pairing/approve核准碼。Body:{platform, code}
POST /api/pairing/revoke撤銷使用者。Body:{platform, user_id}
POST /api/pairing/clear-pending丢棄所有待處理的碼
GET /api/webhooks列出訂閱 + 平台啟用狀態
POST /api/webhooks建立訂閱(回傳一次性密鑰)
DELETE /api/webhooks/{name}移除訂閱
GET /api/credentials/pool列出集中的輪替金鑰(已遮蔽)
POST /api/credentials/pool新增金鑰。Body:{provider, api_key, label?}
DELETE /api/credentials/pool/{provider}/{index}移除金鑰(1 起始索引)
GET /api/memory活躍 Provider + 可用 Providers + 內建檔案大小
PUT /api/memory/provider選擇 Provider(空值 = 僅內建)
POST /api/memory/reset重設內建記憶。Body:{target: all|memory|user}
POST /api/gateway/start · /stop · /restart閘道生命週期(背景執行)
POST /api/ops/doctor · /security-audit · /backup · /import診斷與維護(背景執行;透過 /api/actions/{name}/status 追蹤)
GET /api/ops/hooks已設定的 Shell hooks + allowlist 狀態
GET /api/ops/checkpoints · POST .../prune檢查/修剪 /rollback 儲存
POST /api/ops/hooks · DELETE /api/ops/hooks建立/移除 Shell hook(需同意授權)
GET /api/system/stats主機統計 — OS、CPU、記憶體、磁碟、運行時間
GET /api/hermes/update/check回報更新可用性(落後 commit 數、安裝方式)而不套用。對於落後的 git/pip 安裝,也回傳 commits 列表(shasummaryauthorat)顯示已變更的內容。?force=1 清除 6 小時快取
GET /api/curator · PUT .../paused · POST .../runSkill curator 狀態 + pause/resume + run
GET /api/portalNous Portal 認證 + Tool Gateway 路由(唯讀)
POST /api/ops/prompt-size · /dump · /config-migrate診斷(背景執行)
PUT /api/webhooks/{name}/enabled啟用/停用 Webhook 路由
POST /api/skills/hub/install · /uninstall · /updateSkills hub 操作(背景執行)
GET /api/skills/hub/search跨所有來源搜尋技能 Hub
GET /api/sessions/statsSession store 統計
PATCH /api/sessions/{id}重新命名/封存 Session
GET /api/sessions/{id}/export以 JSON 匯出 Session(中繼資料 + 訊息)
POST /api/sessions/prune刪除超過 N 天的已結束 Session
PUT /api/cron/jobs/{id}編輯 Cron 作業的提示/排程/名稱/遞送方式

認證(閘道模式)

當 Dashboard 綁定到公開或非迴環位址 — 任何不是 127.0.0.1 / localhost 的位址 — 時,Hermes Agent 會啟用認證閘道。每個請求都必須攜帶已驗證的 Session Cookie,否則會被導向登入頁面。有三個內建 Provider:

  • Username/password — 在自架 / 本地部署 / 家用實驗室 Dashboard 上設定認證的最簡單方式。無需外部身分提供者。僅在可信網路或 VPN 後方使用 — 不要用於公開網際網路暴露。
  • OAuth (Nous Portal) — 用於託管部署和任何可透過公開網際網路存取的 Dashboard,也是 遠端 Hermes Desktop 連接的推薦路徑。每次登入都透過你的 Nous 帳戶驗證,因此這是適合面向網際網路使用的 Provider。
  • Self-hosted OIDC — 透過標準 OpenID Connect 帶入你自己的身分提供者(Keycloak、Auth0、Okta、Google、GitHub 透過 OIDC 橋接器等)。不涉及 Nous Portal;在符合標準的 OIDC 伺服器前面時,適合用於公開網際網路暴露。

綁定到迴環位址的 Operator 管理的 Dashboard 不受影響 — 無認證、無登入頁面。

閘道何時啟用

Flags認證閘道使用情境
hermes dashboard(預設 — 綁定到 127.0.0.1OFF本地開發
hermes dashboard --host 0.0.0.0ON遠端/生產 — 以 username/password provider 或 OAuth 保護

閘道在且僅在以下情況啟用:

  1. 綁定主機不是 127.0.0.1::1localhost0.0.0.0
  2. 未設定 --insecure flag。

DANGER — --insecure 完全禁用認證

--insecure 跳過閘道,提供一個未認證的 Dashboard,可讀寫你的 .env(API 金鑰、機密)並可執行 Agent 指令。不要用於遠端連接。 要將 Dashboard 暴露給另一台機器,請設定 username/password provider(或 OAuth)並保持 --insecure 關閉。此 flag 僅作為完全可信、有防火牆的單主機網路上的最後手段逃生艙。

失敗關閉語義

如果閘道應該啟用但註冊任何 DashboardAuthProvider(無 Nous 外掛、無自訂外掛),hermes dashboard 會拒絕綁定並顯示明確的錯誤訊息。不存在「預設拒絕但接受一切」的退路 — 配置錯誤的閘道 Dashboard 永遠不會啟動。

預設 Provider:Nous Research

內建的 plugins/dashboard_auth/nous 外掛始終已安裝並自動載入。當設定客戶端 ID 時,它會自動註冊一個名為 nousDashboardAuthProvider

由於每次登入都透過 Nous Portal 驗證並受你的 Nous 帳戶保護,Nous Provider 是適合將 Dashboard 暴露給公開網際網路的選擇。

註冊 Dashboard

要使用 Nous Provider,你需要一個 OAuth 客戶端 ID(格式為 agent:{id})。有兩種取得方式:

  • CLI — hermes dashboard register 在 Dashboard 所在的主機上執行。它會解析你現有的 Nous 登入(如果尚未登入,先執行 hermes setup),向 Portal 註冊一個自架 OAuth 客戶端,並將 HERMES_DASHBOARD_OAUTH_CLIENT_ID 寫入 ~/.hermes/.env。可選 flag:--name(人類可讀標籤,否則自動生成)和 --redirect-uri(面向網際網路主機的公開 HTTPS 回呼 URL)。

    hermes dashboard register
    # ✓ Registered dashboard "swift_falcon"
    # …writes HERMES_DASHBOARD_OAUTH_CLIENT_ID to ~/.hermes/.env
    
  • GUI — Local Dashboards 頁面。 在 Nous Portal 開啟 /local-dashboards,從瀏覽器註冊、命名、管理和撤銷自架 Dashboard。將產生的 agent:{id} 客戶端 ID 複製到 HERMES_DASHBOARD_OAUTH_CLIENT_ID(env)或 dashboard.oauth.client_id(config.yaml)。這裡也是你撤銷透過 CLI 註冊的 Dashboard 的地方。

設定

外掛從兩個介面讀取,當環境變數設定為非空值時環境變數優先:

config.yaml — 規範介面:

dashboard:
  oauth:
    client_id: agent:01HXYZ…             # 閘道啟用所需

環境變數 — Operator 覆蓋:

環境變數覆蓋格式提供方式
HERMES_DASHBOARD_OAUTH_CLIENT_IDdashboard.oauth.client_idagent:{instance_id}hermes dashboard register

根據 Hermes Agent 約定(~/.hermes/.env 僅用於 API 金鑰/機密),config.yaml 是為本地開發、本地部署和你直接控制的任何部署設定這些值的推薦位置。 環境變數路徑存在是為了讓託管平台的密鑰注入能推送每次部署的 client_id,而無需有人在映像內部編輯 config.yaml — 這是其主要目的。

空的環境變數值視為未設定,因此已 provisioned 但未填充的平台密鑰不會意外遮蔽有效的 config.yaml 條目。

如果兩個來源都未提供 client_id,外掛會報告具體原因,Dashboard 的失敗關閉綁定錯誤會確切告訴你該修正什麼:

Refusing to bind dashboard to 0.0.0.0 — the OAuth auth gate engages on
non-loopback binds, but no auth providers are registered.

Bundled providers reported these issues:
  • nous: HERMES_DASHBOARD_OAUTH_CLIENT_ID is not set (and
    dashboard.oauth.client_id in config.yaml is empty). The Nous Portal
    provisions this env var (shape 'agent:{instance_id}') when it
    deploys a Hermes Agent instance — set it to your provisioned
    client id (either as an env var or under dashboard.oauth.client_id
    in config.yaml), or pass --insecure to skip the OAuth gate entirely.

Or pass --insecure to skip the auth gate (NOT recommended on untrusted
networks).

實作範例:Nous Research

從已登入的 Hermes 安裝到 Nous 認證的 Dashboard,三個步驟。

1. 登入並註冊 Dashboard。 hermes dashboard register 使用你現有的 provisioning Nous 登入來設置 OAuth 客戶端,並將 HERMES_DASHBOARD_OAUTH_CLIENT_ID 寫入 ~/.hermes/.env

hermes setup            # 如果你尚未登入 Nous Portal
hermes dashboard register
# ✓ Registered dashboard "swift_falcon"
# …writes HERMES_DASHBOARD_OAUTH_CLIENT_ID to ~/.hermes/.env

2. 在可達的位址上執行 Dashboard。 未加 --insecure 的非迴環綁定會啟用 OAuth 閘道,剛寫入的 client_id 會啟用 nous provider:

hermes dashboard --host 0.0.0.0 --port 9119 --no-open

3. 登入。 開啟 http://<host>:9119/,你會被導向到 /login。點擊 Sign in with Nous Research → 在 Portal 認證 → 回到已認證的 Dashboard。從任何機器驗證閘道:

curl -s http://<host>:9119/api/status | jq '.auth_required, .auth_providers'
# true
# ["nous"]

GET /api/auth/me 然後回傳已驗證的 Session(provider: nous)。對於面向網際網路的主機,使用 --redirect-uri https://hermes.example.com/auth/callback 註冊,並設定 HERMES_DASHBOARD_PUBLIC_URL 使 OAuth 回呼解析到你的公開 URL(參閱 Public URL override)。

Username/password Provider(無 OAuth IDP)

如果你不想設定 OAuth 身分提供者 — 一個自架的「只要給我的 Dashboard 加個密碼」部署 — 內建的 plugins/dashboard_auth/basic 外掛會註冊一個名為 basicDashboardAuthProvider,使用使用者名稱和密碼進行認證,而非 OAuth 重定向。

它插入與 OAuth Provider 相同的閘道:在沒有 --insecure 的非迴環綁定時啟用閘道,登入頁面為此 Provider 呈現憑證表單(而非「使用 X 登入」按鈕),登入後的所有下游功能 — Session Cookie、透明重新整理、WS 票券、登出、稽核日誌 — 與 OAuth 路徑完全相同。Session 是 Provider 自行鑄造的無狀態 HMAC 簽章 Token,因此無資料庫、無外部 IDP。密碼雜湊使用 stdlib scrypt(無第三方依賴)。

WARNING — 僅在可信網路上使用 — 不要用於公開網際網路

Username/password Provider 適用於可信網路上的自架 / 本地部署 / 家用實驗室 Dashboard,或僅透過 VPN 可達。它以單一共用憑證保護,無外部身分提供者、MFA 或背後的個別使用者帳戶,因此不適合直接暴露 Dashboard 到公開網際網路。對於面向網際網路的 Dashboard,請使用 Nous Research provider(或你自己的 self-hosted OIDC / custom OAuth provider)。

設定

與 Nous Provider 相同,它從 config.yaml(規範介面)讀取,當環境變數設定為非空值時環境變數優先。它僅在設定 username 加上 password_hash(推薦)或 password 時啟用 — 否則為無操作,因此 OAuth 使用者和迴環/--insecure Operator 不受影響。

config.yaml

dashboard:
  basic_auth:
    username: admin
    # 推薦 — 儲存時無明文。使用以下指令計算:
    #   python -c "from plugins.dashboard_auth.basic import hash_password; print(hash_password('PW'))"
    password_hash: "scrypt$16384$8$1$…$…"
    # ...或明文密碼(載入時在記憶體中雜湊;儲存時安全性較低):
    # password: "s3cret"
    secret: "<32+ random bytes, base64 or hex>"  # Token 簽章密鑰
    session_ttl_seconds: 43200                    # 可選;存取 Token 生命週期(預設 12 小時)

環境變數覆蓋:

環境變數覆蓋備註
HERMES_DASHBOARD_BASIC_AUTH_USERNAMEdashboard.basic_auth.username啟用所需
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD_HASHdashboard.basic_auth.password_hash推薦(儲存時無明文)
HERMES_DASHBOARD_BASIC_AUTH_PASSWORDdashboard.basic_auth.password明文;優先於設定中的 password_hash,因此你可以透過環境變數輪替
HERMES_DASHBOARD_BASIC_AUTH_SECRETdashboard.basic_auth.secretToken 簽章密鑰
HERMES_DASHBOARD_BASIC_AUTH_TTL_SECONDSdashboard.basic_auth.session_ttl_seconds存取 Token 生命週期

CAUTION — 為穩定 Session 設定明確的 secret

secret 為空時,會為每個程序生成隨機的簽章密鑰。對單個程序來說這沒問題,但這意味著每次重啟都會使所有 Session 失效,且 Session 無法跨多個 Worker。為重啟存活 / 多 Worker 部署設定明確的 secret

/auth/password-login 端點按客戶端 IP 限流(預設每分鐘 10 次嘗試 → HTTP 429),對未知使用者和錯誤密碼都回傳單一通用的 401 Invalid credentials,因此無法用作使用者名稱列舉預言機。

實作範例:username/password

從零開始在可信網路上建立密碼認證的 Dashboard,三個步驟。

1. 在 ~/.hermes/.env 中設定憑證。 雜湊密碼使儲存時無明文,並設定穩定的簽章密鑰使 Session 在重啟後存活:

# 計算你選擇的密碼的 scrypt 雜湊:
HASH=$(python -c "from plugins.dashboard_auth.basic import hash_password; print(hash_password('choose-a-strong-password'))")

cat >> ~/.hermes/.env <<EOF
HERMES_DASHBOARD_BASIC_AUTH_USERNAME=admin
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD_HASH=$HASH
HERMES_DASHBOARD_BASIC_AUTH_SECRET=$(openssl rand -base64 32)
EOF
chmod 600 ~/.hermes/.env

2. 在可達的位址上執行 Dashboard。 未加 --insecure 的非迴環綁定會啟用閘道,使用者名稱 + 雜湊會啟用 basic provider:

hermes dashboard --host 0.0.0.0 --port 9119 --no-open

3. 登入。 開啟 http://<host>:9119/,你會被導向到 /login — 一個憑證表單(不是「使用 X 登入」按鈕)。輸入 admin / 你的密碼 → 到達已認證的 Dashboard。從任何機器驗證閘道:

curl -s http://<host>:9119/api/status | jq '.auth_required, .auth_providers'
# true
# ["basic"]

GET /api/auth/me 然後回傳已驗證的 Session(provider: basic)。請將此放在 VPN 後方 — 參閱上方的警告;對於公開主機,請改用 Nous Researchself-hosted OIDC provider。

編寫你自己的密碼 Provider

basic 只是延伸點的一個實作。任何外掛都可以註冊密碼 Provider:在你的 DashboardAuthProvider 子類別上設定 supports_password = True,並實作 complete_password_login(*, username, password) -> Session(拒絕時拋出 InvalidCredentialsError,當你的儲存後端當機時拋出 ProviderError)。OAuth 的 start_login / complete_login 方法可以留為 NotImplementedError 骨架。這是 LDAP 綁定、憑證資料庫或任何其他非重定向認證方案的路徑 — 框架為你處理表單、路由、Cookie 和重新整理。

Self-hosted OIDC Provider

如果你運行自己的身分提供者,內建的 plugins/dashboard_auth/self_hosted 外掛使用標準 OpenID Connect 對 Dashboard 進行認證 — 無需針對特定 IDP 的程式碼,不涉及 Nous Portal。它已驗證並可與任何符合標準的 OIDC 伺服器一起使用:

Authentik · Keycloak · Zitadel · Authelia · Auth0 · Okta · Google · …

與 Nous Provider 相同,它會自動載入,且僅在設定完成後才註冊自己,因此對迴環/--insecure 的 Dashboard 來說是無操作的。

設定

設定一個 issuer 和一個 client_id(公開 PKCE 客戶端 — 無客戶端密鑰)。外掛從 {issuer}/.well-known/openid-configuration 取得 IDP 的 authorization_endpointtoken_endpointjwks_uri,因此你永遠不需要硬編碼端點 URL。

config.yaml — 規範介面:

dashboard:
  oauth:
    provider: self-hosted
    self_hosted:
      issuer: https://auth.example.com/application/o/hermes/   # 必要
      client_id: hermes-dashboard                              # 必要
      scopes: "openid profile email"                           # 可選(這是預設值)

環境變數 — Operator 覆蓋(當設定為非空值時環境變數優先於 config.yaml;空值視為未設定):

環境變數覆蓋備註
HERMES_DASHBOARD_OIDC_ISSUBERdashboard.oauth.self_hosted.issuerOIDC issuer URL — 必要
HERMES_DASHBOARD_OIDC_CLIENT_IDdashboard.oauth.self_hosted.client_id公開客戶端 ID — 必要
HERMES_DASHBOARD_OIDC_SCOPESdashboard.oauth.self_hosted.scopes預設為 openid profile email

在你的 IDP 中,註冊一個公開應用/客戶端,使用 authorization-code + PKCE(S256)grant,並將 Dashboard 的回呼加入允許的重定向 URI。回呼是 <dashboard public URL>/auth/callback(參閱 Public URL override 了解 Dashboard 在代理後方如何取得其公開 URL)。

它驗證什麼

Provider 根據已發現的 jwks_uri 驗證 OpenID Connect ID Token(RS256/ES256),issaud claims 固定到你設定的 issuerclient_id。標準 OIDC claims 映射到 Dashboard Session:

Session 欄位Claim(s)
user_idsub(必要)
emailemail
display_namenamepreferred_usernamenicknameemail
org_idorg_id / organization,否則為連接的 groups

ID Token 是建立身分的依據 — Access Token 被視為不透明的(OIDC 規範不要求它是 JWT)。端點 URL 必須是 HTTPS(迴環 http:// 允許用於本地開發 IDP),且發現文件宣傳的 issuer 必須與你設定的一致(允許尾部斜線差異)。Refresh Token(當 IDP 發行時)用於透過標準 refresh_token grant 進行靜默重新認證;登出會在 IDP 宣傳時呼叫其 RFC 7009 revocation_endpoint

Confidential clients(帶有 client_secret 的)尚未支援 — 請設定公開 + PKCE 客戶端,這是瀏覽器前端 Dashboard 的典型選擇。

實作範例:Keycloak

Keycloak 是最容易架設用於本地測試的自架 OIDC 伺服器之一 — 它以單一容器在開發模式下運行(記憶體資料庫),並暴露教科書級的 OIDC 發現功能。本教學讓你在幾分鐘內從零開始到運作的 Dashboard 登入。

1. 使用預設設定的 realm 執行 Keycloak。 將此 realm 匯出儲存為 realm-hermes.json — 它定義了一個 hermes realm、一個公開 PKCE 客戶端hermes-dashboard)和一個測試使用者,全部在啟動時匯入,因此在管理 UI 中無需點擊任何東西:

{
  "realm": "hermes",
  "enabled": true,
  "clients": [
    {
      "clientId": "hermes-dashboard",
      "name": "Hermes Agent Dashboard",
      "enabled": true,
      "publicClient": true,
      "standardFlowEnabled": true,
      "protocol": "openid-connect",
      "redirectUris": ["http://localhost:9119/auth/callback"],
      "webOrigins": ["http://localhost:9119"],
      "attributes": { "pkce.code.challenge.method": "S256" }
    }
  ],
  "users": [
    {
      "username": "testuser",
      "enabled": true,
      "emailVerified": true,
      "email": "testuser@example.com",
      "firstName": "Test",
      "lastName": "User",
      "credentials": [
        { "type": "password", "value": "testpassword", "temporary": false }
      ]
    }
  ]
}

啟動它(Keycloak 26+),將該檔案掛載到匯入目錄:

docker run --rm -p 8080:8080 \
  -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
  -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
  -v "$PWD/realm-hermes.json:/opt/keycloak/data/import/realm-hermes.json:ro" \
  quay.io/keycloak/keycloak:26.0 \
  start-dev --import-realm

啟動後,realm 在 http://localhost:8080/realms/hermes/.well-known/openid-configuration 宣傳標準 OIDC 發現(issuer http://localhost:8080/realms/hermes)。管理控制台位於 http://localhost:8080/admin / admin)。

2. 將 Dashboard 指向它。 Self-hosted 外掛允許迴環 http:// issuer(任何非迴環 issuer 需要 HTTPS),因此本地 Keycloak 可以原樣使用:

export HERMES_DASHBOARD_OIDC_ISSUER="http://localhost:8080/realms/hermes"
export HERMES_DASHBOARD_OIDC_CLIENT_ID="hermes-dashboard"
export HERMES_DASHBOARD_PUBLIC_URL="http://localhost:9119"
hermes dashboard --host 0.0.0.0 --port 9119 --no-open

HERMES_DASHBOARD_PUBLIC_URL 告訴 Dashboard 其 OAuth 回呼是 http://localhost:9119/auth/callback — 即 realm 上方註冊的重定向 URI。綁定到 0.0.0.0(非迴環綁定)且不加 --insecure 就是啟用 OAuth 閘道的方式。

3. 登入。 開啟 http://localhost:9119/,你會被導向到 /login。點擊 Sign in with Self-Hosted OIDC → 在 Keycloak 以 testuser / testpassword 認證 → 回到已認證的 Dashboard。側邊欄顯示 Logged in as Test User via self-hostedGET /api/auth/me 回傳已驗證的 Session(provider: self-hostedemail: testuser@example.com)。

如果你在不同的主機/連接埠綁定或瀏覽,請在 Keycloak 管理控制台(Clients → hermes-dashboard → Settings)的Valid redirect URIs中加入該來源的 …/auth/callback。相同的模式適用於 Authentik、Zitadel、Authelia 和其他 OIDC 伺服器 — 只有 issuer URL 和客戶端註冊 UI 不同。

Public URL Override

預設情況下,Dashboard 從請求中重建 OAuth 回呼 URL — X-Forwarded-Host + X-Forwarded-Proto + X-Forwarded-Prefix(當 uvicorn 配置了 proxy_headers=True 時,start_server 在閘道下會啟用此選項)。這在正確設定所有三個標頭的反向代理後方可以開箱即用。

對於無法可靠轉發這些標頭的反向代理後方的部署(手動 nginx 設定、本地 ingress、帶有部分代理鏈的自訂網域部署),請設定 dashboard.public_url(或 HERMES_DASHBOARD_PUBLIC_URL)為你到達 Dashboard 的完整公開 URL

dashboard:
  public_url: "https://dashboard.example.com/hermes"

設定後,OAuth 回呼 URL 就是 <public_url>/auth/callback 的原文 — 該程式碼路徑上 X-Forwarded-Prefix 被忽略,因為 Operator 已明確宣告了公開 URL。這是故意的:在前綴已嵌入 public_url 的常見情況下,疊加前綴會導致雙重前綴。

與其他 Dashboard 設定相同的優先順序 — 環境變數優先於 config.yaml

介面覆蓋路徑使用時機
config.yaml 中的 dashboard.public_urlHERMES_DASHBOARD_PUBLIC_URL本地開發/本地部署(規範介面)
HERMES_DASHBOARD_PUBLIC_URL 環境變數託管平台密鑰 / CI
(未設定)預設 — 從 X-Forwarded-* 標頭重建

驗證會拒絕不含 http:// / https:// scheme、不含主機或包含引號/尖括號/空白字元/控制字元的值。格式不正確的值會靜默降級到標頭重建,使登入流程保持運作而不是將使用者導向惡意 URL。

注意: public_url 只覆蓋 OAuth 回呼 URL。Secure Cookie 標誌仍由 request.url.scheme 控制(在 proxy_headers 下為 X-Forwarded-Proto),因此在 TLS 終止的公開部署上使用 http:// public_url 會產生非 Secure 的 Cookie。這是 Operator 的常見陷阱 — 請在上游搭配正確的 TLS 終止。

OAuth 流程

Provider 實作了 Nous Portal OAuth contract v1 — 帶有 PKCE(S256)的 authorization-code grant:

  1. 使用者在沒有 Session Cookie 的情況下存取 / → 閘道重定向到 /login
  2. 登入頁面顯示「Continue with Nous Research」按鈕 → /auth/login?provider=nous
  3. 伺服器將 PKCE state 存入短期 Cookie,將使用者重定向到 https://portal.nousresearch.com/oauth/authorize?…
  4. 使用者在 Portal 認證,到達 /auth/callback?code=…&state=…
  5. 伺服器在 POST /api/oauth/token 用授權碼換取 Access Token,根據 Portal 的 JWKS(/.well-known/jwks.json)驗證 JWT 簽章,並設定 hermes_session_at Cookie。
  6. 使用者被重定向到 /(或透過 next= 查詢參數到達原始深層連結路徑)。

Access Token 有 15 分鐘的 TTL。contract v1 中沒有 Refresh Token — 當 Token 過期時,SPA 的 fetch wrapper 檢測到 401 信封並進行整頁導航回到 /login 以重新執行流程。

設定的 Cookies

名稱生命週期備註
hermes_session_atToken TTL(15 分鐘)HttpOnly、SameSite=Lax、HTTPS 時 Secure
hermes_session_pkce10 分鐘HttpOnly;在來回行程中保存 PKCE verifier + provider 提示
hermes_session_rtv1 中未使用為前向相容保留;當 refresh_token 為空時不寫入

三者的 Path=/SameSite=LaxSecure 標誌在透過 HTTPS 到達 Dashboard 時設定(透過請求 URL scheme 偵測 — 在 proxy_headers=True 下遵守上游 TLS 終止的 X-Forwarded-Proto)。

登出

側邊欄小部件顯示 Logged in as <user_id…> via nous 及登出圖示。點擊它會 POST /auth/logout,清除所有 Dashboard 認證 Cookie 並重定向回 /login

稽核日誌

每次登入開始、成功、失敗和 Session 驗證失敗都以 JSON 行寫入 $HERMES_HOME/logs/dashboard-auth.log。敏感欄位(access_tokenrefresh_tokencodecode_verifierstateAuthorization 標頭)在記錄前被遮蔽。

自訂 Providers

要插入非 Nous 的 OAuth Provider(例如 Google、GitHub、自訂 OIDC),建立一個註冊 DashboardAuthProvider 的外掛:

# ~/.hermes/plugins/dashboard-auth-myidp/__init__.py
from hermes_cli.dashboard_auth import DashboardAuthProvider, Session, LoginStart

class MyIdPProvider(DashboardAuthProvider):
    name = "myidp"
    display_name = "My Identity Provider"

    def start_login(self, *, redirect_uri): ...
    def complete_login(self, *, code, state, code_verifier, redirect_uri): ...
    def verify_session(self, *, access_token): ...
    def refresh_session(self, *, refresh_token): ...
    def revoke_session(self, *, refresh_token): ...

def register(ctx):
    ctx.register_dashboard_auth_provider(MyIdPProvider())

登入頁面列出所有已註冊的 Provider;多個 Provider 可以疊加,使用者在 /login 選擇其中一個。

驗證閘道已啟用

# 快速環境變數路徑。
HERMES_DASHBOARD_OAUTH_CLIENT_ID=agent:test \
  hermes dashboard --host 0.0.0.0

# 或透過 config.yaml 的等效方式(推薦用於本地開發/本地部署):
#
#   dashboard:
#     oauth:
#       client_id: agent:test
#
# 然後只需:
hermes dashboard --host 0.0.0.0

# 呼叫 /api/status 查看閘道狀態:
curl -s http://127.0.0.1:9119/api/status | jq '.auth_required, .auth_providers'
# true
# ["nous"]

Dashboard 的 React StatusPage 在「Web server」下方顯示相同的欄位。側邊欄的 AuthWidget 在你登入後呈現目前的身分。

將 Hermes Desktop 連接到遠端後端

Hermes Desktop 可以驅動在另一台機器上運行的 Hermes 後端(VPS、家庭伺服器、Tailscale 後方的 Mini)。在應用中位於 Settings → Gateway → Remote gateway,需要輸入 Remote URL登入方式。(桌面應用本身 — 安裝、設定、聊天 — 請參閱 Hermes Desktop 頁面。)

你使用其中一個內建的認證 Provider 保護遠端 Dashboard,桌面應用會根據後端宣傳的 Provider 進行登入。對於超出你自己機器的後端 — VPS、公開主機、任何面向網際網路的 — 推薦的 Provider 是 OAuth (Nous Portal)(使用 hermes dashboard register 註冊,並使用 Sign in with Nous Research 登入)。內建的 username/password provider 是後端在可信 LAN 或僅透過 VPN 可達時最快的選項,但不適合直接公開網際網路暴露。將 Dashboard 綁定到非迴環位址會啟用其認證閘道;一旦登入,Desktop 會自動重用 Session 進行聊天 WebSocket — 無需複製或貼上 Token。

以下配方使用 username/password 路徑,因為它是在可信網路上最快架設的方式;OAuth 路徑請參閱 Default provider: Nous Research

在後端(遠端機器上)

# 1. 在 ~/.hermes/.env 中設定 Dashboard 登入憑證(機密檔案,0600)。
cat >> ~/.hermes/.env <<'EOF'
HERMES_DASHBOARD_BASIC_AUTH_USERNAME=admin
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD=choose-a-strong-password
# 推薦:穩定的簽章密鑰使 Session 在重啟後存活。
HERMES_DASHBOARD_BASIC_AUTH_SECRET=$(openssl rand -base64 32)
EOF
chmod 600 ~/.hermes/.env

# 2. 在可達的位址上執行 Dashboard。非迴環綁定會啟用認證閘道;
#    username/password provider 處理登入。
hermes dashboard --no-open --host 0.0.0.0 --port 9119

偏好儲存時無明文?使用 HERMES_DASHBOARD_BASIC_AUTH_PASSWORD_HASH 搭配 scrypt 雜湊 — 完整選項請參閱 Username/password provider

如果你以 systemd 服務執行 Dashboard,當 unit 設有 EnvironmentFile=%h/.hermes/.env 時,~/.hermes/.env 會在啟動時自動載入,因此憑證在開機時就在環境中。

WARNING

Dashboard 讀寫你的 .env(API 金鑰、機密)並可執行 Agent 指令。此處展示的 username/password 設定用於可信網路 — 永遠不要將密碼保護的 Dashboard 直接暴露到公開網際網路。將它放在 VPN 後方。Tailscale 是乾淨的選項:綁定到機器的 tailscale IP(--host <tailscale-ip>),並使用 http://<tailscale-ip>:9119 作為 Remote URL。只有你 tailnet 上的裝置才能到達它。要透過公開網際網路到達後端,請改用 OAuth (Nous Portal) provider。

在 Hermes Desktop 中

Settings → Gateway → Remote gateway:

  • Remote URLhttp://<backend-host>:9119(如果你在反向代理前面,路徑前綴如 /hermes 受支援)
  • Sign in — 應用偵測到 username/password 閘道並顯示 Sign in 按鈕;點擊它並輸入步驟 1 的憑證
  • Save and reconnect — 將桌面 Shell 切換到遠端後端

Session 會自動重新整理,當後端設定了 HERMES_DASHBOARD_BASIC_AUTH_SECRET 時會在重啟後存活。

環境變數覆蓋

除了應用內設定,你也可以在啟動前用環境變數將桌面指向後端。當 HERMES_DESKTOP_REMOTE_URL 設定時,它會覆蓋已儲存的應用內 URL(Gateway 設定面板顯示「env override」徽章並停用編輯);你仍然從面板用使用者名稱和密碼登入

環境變數
HERMES_DESKTOP_REMOTE_URLhttp://<backend-host>:9119

疑難排解

  • 「Remote gateway incomplete」 — 你尚未輸入遠端 URL。
  • 登入失敗 401 / 「Invalid credentials」 — 使用者名稱或密碼與後端的 HERMES_DASHBOARD_BASIC_AUTH_USERNAME / HERMES_DASHBOARD_BASIC_AUTH_PASSWORD 不匹配。後端對未知使用者和錯誤密碼回傳相同的通用錯誤,因此兩者都要檢查。使用 curl -s http://<host>:9119/api/status | jq '.auth_required, .auth_providers' 確認閘道 — 應回報 true 且包含 "basic"
  • 沒有「Sign in」按鈕 — 改為要求 Session Token — username/password provider 未啟用(/api/status 不會列出 "basic")。確保使用者名稱和密碼(或密碼雜湊)已設定且 Dashboard 程序已載入它們。
  • 每次重啟都登出 — 將 HERMES_DASHBOARD_BASIC_AUTH_SECRET 設為穩定值;否則簽章密鑰會在每次啟動時重新生成。
  • 連接被拒絕 / 逾時 — 後端綁定到 127.0.0.1(預設值)而非可達的位址,或防火牆/VPN 正在封鎖連接埠。綁定到 0.0.0.0 或 tailscale IP,並對你的可信網路開放連接埠。

CORS

Web 伺服器將 CORS 限制為僅允許 localhost 來源:

  • http://localhost:9119 / http://127.0.0.1:9119(生產環境)
  • http://localhost:3000 / http://127.0.0.1:3000
  • http://localhost:5173 / http://127.0.0.1:5173(Vite 開發伺服器)

如果你在自訂連接埠上執行伺服器,該來源會自動新增。

開發

如果你要貢獻 Web Dashboard 前端:

# 終端 1:啟動後端 API
hermes dashboard --no-open

# 終端 2:啟動帶有 HMR 的 Vite 開發伺服器
cd web/
npm install
npm run dev

http://localhost:5173 上的 Vite 開發伺服器將 /api 請求代理到 http://127.0.0.1:9119 上的 FastAPI 後端。

前端使用 React 19、TypeScript、Tailwind CSS v4 和 shadcn/ui 風格的元件構建。生產建置輸出到 hermes_cli/web_dist/,FastAPI 伺服器將其作為靜態 SPA 伺服。

更新時自動建置

當你執行 hermes update 時,如果 npm 可用,Web 前端會自動重新建置。這使 Dashboard 與程式碼更新保持同步。如果未安裝 npm,更新會跳過前端建置,hermes dashboard 會在首次啟動時建置它。

主題與外掛

Dashboard 內建六個主題,並可透過使用者自訂主題、外掛分頁和後端 API 路由進行擴展 — 全部即插即用,無需複製 repo。

即時切換主題 — 從頁首列點擊語言切換器旁的調色盤圖示。選擇會持久化到 config.yamldashboard.theme,並在頁面載入時還原。

獨立更改字型 — 從相同的選擇器中 — 主題清單下方的 Font 區段覆蓋任何活躍主題的 UI 字型。選擇會跨主題切換持久化(config.yamldashboard.font);選擇 Theme default 可清除它並回到活躍主題自己的字型。

內建主題:

主題特色
Hermes Teal (default)深藍綠 + 奶油色、系統字型、舒適間距
Hermes Teal (Large) (default-large)與 default 相同,18px 文字和更寬鬆的間距
Midnight (midnight)深藍紫、Inter + JetBrains Mono
Ember (ember)暖紅 + 青銅色、Spectral serif + IBM Plex Mono
Mono (mono)灰階、IBM Plex、緊湊
Cyberpunk (cyberpunk)黑底霓虹綠、Share Tech Mono
Rosé (rose)粉紅 + 象牙色、Fraunces serif、寬敞

要建立你自己的主題、新增外掛分頁、注入 Shell Slots 或暴露外掛專屬 REST 端點,請參閱 Extending the Dashboard — 完整指南涵蓋:

  • 主題 YAML schema — 調色盤、字型排版、佈局、資源、componentStyles、colorOverrides、customCSS
  • 佈局變體 — standardcockpittiled
  • 外掛 manifest、SDK、Shell slots、頁面範圍限定的 slots(將小部件注入內建頁面而不覆蓋它們)、後端 FastAPI 路由
  • 完整的主題加外掛教學(Strike Freedom cockpit 示範)
  • 發現、重新整理和疑難排解


Web Search & Extract