Skip to content

About

Unofficial Flutter client for a self-hosted Hermes Agent dashboard. iOS, iPadOS, macOS and Android.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

987 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hermes-app

Download on the App Store Join the TestFlight beta

A Flutter client for Hermes Agent (by Nous Research)'s web dashboard. Connect to a self-hosted hermes dashboard, sign in with an OIDC provider or a username and password, and chat with your agent from iPhone, iPad, Mac and Android.

  • Chat with history, streaming replies, tool calls, and approval and question requests from the agent
  • Play voice messages from the agent inline, including OGG/Opus and MP3
  • A thread list with pinning, archive and delete, plus profiles and messaging connections
  • Bot Mode specialists with profile-backed identities, a canonical chat for each bot, and hosted group rooms on compatible Hermes dashboards
  • A Kanban board, when the server has the Kanban plugin on
  • Notifications when a reply finishes or the agent needs you
  • A share extension on iOS and a share inbox on macOS, and an Apple Watch companion
  • OpenTelemetry export, off unless you configure it

Hosted groups can run on Hermes dashboards with protocol 2 support. Clarify, sudo, and secret requests from group members cannot be answered in the room; if a member waits for one, use Stop. Direct bot chats support their own input requests.

Download

Download the app for iPhone, iPad and Apple Watch from the App Store, or join the TestFlight beta for iPhone, iPad and Mac.

The app checks for a newer version when it opens and offers to take you to it: in the App Store on iOS and macOS, on Google Play on Android, and on the GitHub release page on Linux and Windows. It finds nothing until the app is listed in a store.

You need your own Hermes Agent dashboard to sign in (see Getting started). This is an independent app and is not affiliated with Nous Research.

Windows and Linux

Both ship as release downloads (a Linux tarball and .deb, an unsigned Windows x64 zip) and run the chat, the Kanban board, schedules, memory and the settings pages as on the Mac. They get the phone and Mac extras only where a plugin and the code allow it.

Both columns are read from the code, not run: pubspec.yaml, the plugins' platform lists and the platform checks in lib/. CI builds both and packages Linux but launches neither app. The Windows column is marked "from code, not run" all the same.

Feature Windows (from code, not run) Linux Why
Sign-in (OIDC and password) Works Works The loopback and PKCE flow is plain dart:io; the page opens in the default browser through url_launcher.
Keeping you signed in Works Partly Windows encrypts the tokens with a key in Credential Manager. Linux needs a running Secret Service (GNOME Keyring or KWallet) through libsecret; without one, saving the session is expected to fail. The durable send queue keeps its key in the same store.
Chat, threads, profiles, Kanban, schedules, memory, plugins Works Works Shared Dart code and the server's API.
Attachments: drag and drop, paste Works Works desktop_drop and pasteboard; photo library and camera are phone-only.
Attachments: file picker, Save as Works Partly On Linux file_picker uses xdg-desktop-portal, which must be installed.
Voice messages: playback Works Works media_kit; on Linux it needs libmpv2 (libmpv1 on Ubuntu 22.04), which the .deb declares. CI plays Ogg/Opus, MP3 and more through libmpv on Linux (native_voice_player_test).
Voice messages: recording Works Works Same record stream as dictation; needs PulseAudio or PipeWire-pulse on Linux.
Dictation (speech to text) Works Works The microphone goes through record (16 kHz PCM stream) to the server's transcription. On Linux that is parecord and pactl from pulseaudio-utils, which the .deb declares. There is no on-device recognizer.
Voice calls Not available Not available Hands-free calls are iOS only.
Bot Screen viewer and takeover Works Works The viewer and its keyboard input have Windows and Linux paths.
Notifications Works (untested) Works (untested) Plain notifications while the app runs: a tap opens the chat, there are no answer buttons, and nothing arrives while the app is closed. Not yet run on a real desktop.
App Lock Works (untested) Not available Windows Hello or a PIN through local_auth. It has no Linux backend, and the dialog says so.
Opening hermes:// links Not available Not available The link listener only starts on iOS, macOS and Android, and neither package registers the scheme.
Receive shared files and text Not available Not available Receiving works on iOS, Android and macOS. Drag and drop and paste still work.
Drag files out Not available Not available Drag out is macOS only. Opening a file uses the system default app.
Background refresh and alerts Not available Not available workmanager has no Windows support; Linux only through an experimental, unendorsed workmanager_linux the app does not use. Nothing is announced while the app is closed.
Widgets, quick actions, Spotlight, Live Activities, Watch Not available Not available Apple and Android surfaces.
Quick panel, menu bar item, Dock menu, conversation windows Not available Not available macOS only.
Keyboard navigation (back and forward) Works Works The desktop shortcuts are enabled for both.
Update check Works Works Compares with the latest full (not pre-release) GitHub release and offers its page; the app does not update itself.
Telemetry (off unless configured) Works Works Shared Dart code.

docs/architecture/windows-linux.md has the evidence for each row and the gaps that are cheap to close.

Screenshots

A chat on iPhone with tool calls, a code block and a list The thread list on iPhone, with a pinned chat A new chat on iPhone with starter prompts The same chat on iPhone in dark mode

The wide layout on iPad: navigation rail, thread list and chat

The Mac app window with the thread list and a chat

They are rendered from the app's own widgets in a test, against a stand-in dashboard that serves a few invented chats. docs/screenshots explains how to render them again.

Getting started

Run a dashboard the app can reach:

# on the machine that will host the dashboard
hermes dashboard --host 0.0.0.0 --port 9119 --no-open

Enter that machine's address (for example http://192.168.1.20:9119) on the app's first screen. The Web Dashboard docs cover the username and password or self-hosted OIDC provider.

To run the app from source:

flutter pub get
flutter run

On Linux, install libmpv2 (libmpv1 on Ubuntu 22.04) for voice-message playback. The .deb declares the runtime dependency; tarball users need to install it separately.

Ask the agent for a voice reply and tap Play on its audio attachment. A transcript button appears when Hermes includes a matching text_to_speech call: it reveals the text passed to that tool, collapsed by default. Clips without that source text remain playable without a transcript.

The iOS app embeds a watchOS app (ios/HermesWatch), so Xcode needs the watchOS platform installed (Xcode > Settings > Components) even if you only run the phone app. flutter build ios --simulator then also needs a simulator: pass one with -d <simulator id>.

Plain HTTP works against a dashboard on your network: Android allows cleartext traffic, iOS and macOS allow local networking, and the macOS sandbox has the client and server network entitlements the loopback sign-in callback needs.

Reaching your dashboard over a VPN

If the dashboard is only reachable through Tailscale or WireGuard, turn the VPN on first, then enter the address the server has on the VPN.

  • Tailscale, recommended: keep the dashboard on the server's own loopback address, which is Hermes' default, and publish it to your tailnet with tailscale serve:

    hermes dashboard --port 9119 --no-open
    tailscale serve --bg 9119

    Enter the https://<machine>.<tailnet>.ts.net address that tailscale serve prints. It carries a real certificate, it stays off the internet, and on iOS Tailscale's VPN On Demand can start the VPN when the app looks up a *.ts.net name. Hermes sees these requests as local, so it does not ask anyone to sign in: every device on your tailnet can open the dashboard. Limit that with Tailscale access rules, or use the next option.

  • Tailscale or WireGuard address: start the dashboard with --host set to the server's VPN address, for example hermes dashboard --host 100.101.102.103, and enter http://100.101.102.103:9119. Hermes refuses to bind to anything but loopback until a sign-in method is configured (a password in config.yaml, or an OAuth provider), so set that up first; the app then asks you to sign in. Do not use 0.0.0.0, which also listens on your LAN. The VPN encrypts the traffic, so plain HTTP is fine.

The VPN has to be on for the whole device, because signing in opens the system browser, which must reach the dashboard too. When the address looks like a VPN or private address and the server does not answer, the app asks whether the VPN is connected. When the network changes or you return to the app, it tries the saved server again by itself.

HTTPS with your own certificate authority

A reverse proxy with a certificate from its own authority, such as Caddy's tls internal, works once the device trusts that authority's root certificate. The system browser that signs you in needs it too. Caddy keeps the root at /data/caddy/pki/authorities/local/root.crt in its container.

  • iOS: open the root certificate on the device to install it as a profile, then turn on full trust for it in Settings > General > About > Certificate Trust Settings.
  • macOS: add it to the System keychain in Keychain Access and set it to Always Trust.
  • Android: install it as a CA certificate in Settings (search Settings for "CA certificate"). The app reads the CA certificates you installed when it starts and when you return to it. One you remove stays trusted until the app is closed and started again.

Until then the app says that this device doesn't trust the server's certificate. A certificate from a public authority, such as the one tailscale serve provides or one from Let's Encrypt, needs none of this.

How sign-in works

The app uses the native-app OAuth flow (RFC 8252) that the dashboard exposes, for OIDC and for password sign-in alike. It opens the system browser with a PKCE challenge and a loopback redirect, redeems the returned code for a bearer token pair kept in the OS keychain, and refreshes the token before it expires and again on any 401. When /api/status reports auth_required: false (the dashboard's loopback dev mode), sign-in is skipped. The flow mirrors the one in Hermes Desktop; the code is in lib/src/auth/.

Continue a chat with Apple Handoff

On iPhone, iPad, and Mac, Handoff can reopen a saved chat on another device. Sign into the same Apple Account on both devices, enable Wi-Fi, Bluetooth, and Handoff, and install Hermes on each device. Open a saved chat, then select Hermes from the receiving device's Handoff suggestion. Both devices must be able to reach the dashboard. Each device signs into Hermes independently.

If the receiving device uses another dashboard, Hermes asks before connecting to the incoming address. Changing dashboards clears the current session and local queued messages. App lock still requires an unlock before continuation. Handoff transfers the dashboard address, profile, and chat ID. Drafts, attachments, queued messages, and unsaved chats remain on their source device. Hosted group rooms and browser continuation are not supported.

Receive messages from Hermes

The optional Hermes App messenger plugin registers the app as a Hermes messaging destination. Install it on your Hermes server to let the agent and scheduled jobs send text into new, saved chats you can open and reply to. Delivery works while the app is disconnected. The app announces new messages with a notification on Android, iOS, macOS, Windows and Linux: within about a minute while it is open, and on iOS and Android when the system lets it check in the background. A closed or suspended app is not woken at once. The plugin guide covers setup and testing.

The API client

Most REST calls go through packages/hermes_api, a client generated from openapi/hermes-agent.openapi.json. Don't edit it by hand. Regenerate it with ./scripts/generate_hermes_api_client.sh (needs a JDK and the Dart SDK); CI fails if the client drifts from the spec. openapi/README.md has the details.

Development

CLAUDE.md covers the commands and an architecture map; docs/architecture/ has each area in full. The repo uses dart_pre_commit to run the same dart format and dart analyze checks CI does, on staged Dart files:

flutter pub get
dart run tool/setup_git_hooks.dart

The hook is installed once per clone and is shared by all its git worktrees.

OpenSpec

OpenSpec changes live in openspec/. Its six core workflow skills are available to Codex in .agents/skills/ and to Claude Code in .claude/skills/. In Codex, use $openspec-propose to plan a change and $openspec-apply-change to implement it; the desktop app also offers them in the Skills selector. Claude Code uses /opsx:propose and /opsx:apply.

Refresh both integrations with the version used to generate them:

npm exec --yes --package @fission-ai/openspec@1.14.0 -- openspec init --tools claude,codex --profile core --no-animation

Component catalog

Every widget and screen is shown in each of its states, in light and dark, on phone and desktop widths, in a Widgetbook catalog. It is published at https://cedricziel.github.io/hermes-app/ and needs no server. Run it locally with:

flutter run -d macos -t widgetbook/main.dart

Contributing

The project uses the oss plugin from cedricziel/claude-plugins (commit discipline, stacked PRs, tests) for anyone working on it with Claude Code:

/plugin marketplace add cedricziel/claude-plugins
/plugin install oss@cedricziel

License

Apache License 2.0. See LICENSE.

About

Unofficial Flutter client for a self-hosted Hermes Agent dashboard. iOS, iPadOS, macOS and Android.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages