How Hermes Turns G2 Smart Glasses Into a Safer AI Agent
TL;DR

- Hermes G2 plugins already exist; porting from OpenClaw was unnecessary.
- G2 pairing tokens effectively grant root; platform-level tool isolation is mandatory.
- Hermes
platform_toolsetscleanly isolates glasses from shell, file, and code tools. - Where and how the G2 app is served determines true “outside home” usability.
- On 1 vCPU, whisper-tiny is the only viable Korean ASR option despite accuracy issues.
- How Hermes Turns G2 Smart Glasses Into a Safer AI Agent
- TL;DR
- What is the Hermes + G2 architecture in this setup?
- Why Hermes instead of OpenClaw for G2 smart glasses?
- What does the Hermes G2 plugin actually provide?
- How do you deploy the Hermes G2 bridge on a VPS securely?
- Why is the G2 pairing token effectively root on your server?
- How does Hermes platform-level tool isolation work?
- How do you prove that tool isolation really works?
- How should you install the G2 Hermes app so it works outside your LAN?
- Why is Korean speech recognition only “half-successful” on G2?
- Which option is better for you: OpenClaw or Hermes for G2?
- What are the eight real-world pitfalls you are likely to hit?
- Frequently Asked Questions
- Q: How do you connect Even Realities G2 smart glasses to Hermes?
- Q: How can you safely restrict what the glasses are allowed to do?
- Q: Why is the G2 token considered as sensitive as a root credential?
- Q: Why does Korean speech recognition perform poorly in this setup?
- Q: How do you ensure the glasses app works over cellular networks?
- Conclusion
Even Realities G2 smart glasses can run a self-hosted AI agent without a Windows box, OpenClaw, or paid cloud speech APIs. Swap in Hermes and a small Ubuntu VPS, and the same “talk to your glasses” experience gets cheaper, more portable, and—crucially—more secure.
Related: Claude Code Channels & MCP in 2026 | Complete Guide
Related: Claude Code Channels for AI Agents | Complete Guide
Related: Claude Managed Agents just killed AI infra
Related: Paper Clip AI Agent Framework: Run a Virtual Company
This post walks through how that migration worked in practice, why token and permission handling is the genuinely scary part, and where the system still breaks down for Korean speech. When I reproduced the original “Tech with Spencer” setup but swapped in Hermes and a VPS, I hit four met goals and one unexpected win: hard, platform-level isolation of dangerous tools from the glasses.
What is the Hermes + G2 architecture in this setup?

The Hermes + G2 architecture is a self-hosted agent stack that links Even Realities G2 smart glasses to an existing Hermes agent over the internet. The key constraint was reusing an existing Hermes instance that already had Slack, Telegram, memory, and long-running sessions—rather than spawning a separate agent just for the glasses.
My target properties were explicit:
- Usable outside the home network.
- Not dependent on an always-on Mac.
- Sharing context and memory with the main Hermes “operations” agent.
- No plaintext ports exposed directly on the Mac.
The final topology looked like this:
G2 Glasses ── Bluetooth ── iPhone
(on-device ASR)
│
├─ HTTPS → https://g2app.example-vps.your-host.cloud (WebView app)
└─ WSS → wss://g2.example-vps.your-host.cloud (Hermes bridge)
│
└─ Hermes Agent (Docker on VPS)
├─ even_g2 platform
├─ Slack
└─ Telegram
The original OpenClaw + Windows architecture was entirely local; this Hermes variant pushes the bridge to a VPS and keeps the agent unified.
Keeping a single Hermes agent and introducing platform-level isolation was the only way to avoid forking memories and sessions while still treating the glasses as untrusted. For reference on Hermes itself, the primary documentation lives on GitHub:
- Hermes core: https://github.com/Hermes-AI-Platform/hermes
- Even G2 ecosystem list: https://github.com/pangoleen/awesome-even-realities-g2
Why Hermes instead of OpenClaw for G2 smart glasses?

Hermes is a multi-platform agent runtime I was already using with Slack and Telegram. OpenClaw, in the original video, was a separate agent stack tied to a Windows PC. Starting from Tech with Spencer’s 25-minute walkthrough, the original design was:
- Windows PC running OpenClaw.
- ClawHub skill
OcuClawfor G2 integration. - Tailscale relay.
- Soniox cloud speech recognition.
Porting that stack as-is would have created a second, completely separate agent—new memory, new sessions, new tool permissions—solely for the glasses. That makes “ask with glasses, continue on Slack” impossible.
The goals were:
- Preserve the single Hermes agent as the source of truth.
- Reuse existing Slack and Telegram integrations.
- Avoid opening a plaintext port on a Mac just to serve the glasses.
- Remove all paid cloud STT (speech-to-text) from the chain.
When I reframed the problem from “bring OcuClaw into Hermes” to “is there already a G2 plugin for Hermes?”, the answer appeared in three minutes via the G2 ecosystem list.
The existing projects were:
huntsyea/hermes-evenhub-bridge– Hermes platform plugin that registerseven_g2as a gateway platform.huntsyea/hermes-even-hub-app– WebView client for G2, talking to that bridge.wingk1314/even-g2-hermes– An integrated triple-mode project (AI-proxy, Terminal Mode, Even Hub plugin).
All three were discoverable in pangoleen/awesome-even-realities-g2. The practical lesson is simple:
Before doing a port, always search for a native alternative in the ecosystem. In fast-moving stacks, “search first” is cheaper than “port first.”
A side effect of these Hermes plugins: ASR runs on-device, which eliminates the Soniox onboarding and API keys entirely.
What does the Hermes G2 plugin actually provide?

The Hermes G2 plugin is a platform extension that exposes Even Realities G2 as a Hermes platform named even_g2, plus a corresponding WebView app for the glasses. Concretely:
hermes-evenhub-bridge: runs a WebSocket endpoint, understands the Even Hub protocol, and bridges to Hermes.hermes-even-hub-app: a WebView client that runs on G2 via Even Hub, connecting to that WebSocket endpoint.- Optional integrated forks like
even-g2-hermesthat package multiple modes.
On macOS, the “hello world” for this integration was three shell commands:
hermes plugins install huntsyea/hermes-evenhub-bridge
hermes even-g2 setup
hermes pairing approve even_g2 <code>
After that, the minimum viable path was:
G2 → on-device ASR → ws://192.168.1.100:8766 → Hermes on Mac → LLM
This confirmed the plugin worked but didn’t meet any of the real goals:
- Only reachable from the home LAN.
- Dependent on the Mac being awake.
- Unencrypted WebSocket.
- Different Hermes profile from the production agent, so no shared memory.
Doing this local “line-of-sight” test on the Mac first was invaluable. It cleanly separated plugin issues from deployment and network issues: if it fails here, the bug is in the plugin; if it works here but fails later, the bug is in networking or deployment.
How do you deploy the Hermes G2 bridge on a VPS securely?
The Hermes G2 bridge deployment is a public WebSocket and WebView endpoint on a VPS, fronted by Traefik with HTTPS, rate limits, and explicit service binding. Traefik was already in place with wildcard DNS and Let’s Encrypt, so exposing the bridge required only labels.
A minimal Traefik configuration for the bridge service:
- traefik.http.routers.hermes-g2.rule=Host(`g2.example-vps.your-host.cloud`)
- traefik.http.routers.hermes-g2.entrypoints=websecure
- traefik.http.routers.hermes-g2.tls.certresolver=letsencrypt
- traefik.http.routers.hermes-g2.service=hermes-g2
- traefik.http.routers.hermes-g2.middlewares=g2-ratelimit
- traefik.http.services.hermes-g2.loadbalancer.server.port=8765
- traefik.http.middlewares.g2-ratelimit.ratelimit.average=30
- traefik.http.middlewares.g2-ratelimit.ratelimit.burst=60
The service= label is not cosmetic. Without it, Traefik tries to auto-bind routers to services—and once multiple services exist for a router, auto-binding fails:
ERR Router xxx cannot be linked automatically with multiple Services
I actually took down an unrelated dashboard this way. The fix was adding explicit service= bindings to existing routers as well, not just the new one.
To verify WebSocket connectivity over HTTPS:
curl -s -i --http1.1 \
-H "Connection: Upgrade" \
-H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
https://g2.example-vps.your-host.cloud
HTTP/1.1 101 Switching Protocols confirms the upgrade works. If you omit --http1.1, curl negotiates HTTP/2 and the Connection: Upgrade header becomes invalid, producing a 426—not a real failure, just a protocol mismatch. The G2 WebView client uses HTTP/1.1, so this divergence is purely a diagnostic gotcha.
For reference on Traefik routing and services: https://doc.traefik.io/traefik/routing/routers/
Why is the G2 pairing token effectively root on your server?
The G2 pairing token is a bearer credential that allows anyone who holds it to drive the Hermes agent with the same tool permissions as the glasses’ platform. The plugin’s SECURITY.md is explicit: anyone with the token and a paired client can fully control the Hermes agent within that platform’s toolset.
In a typical Hermes setup, those tool permissions include:
- Shell execution (
terminal). - File read/write.
- Code execution.
computer_use(desktop automation / remote control).
On a self-hosted VPS, these capabilities are functionally equivalent to root access. A leaked token is as bad as leaking SSH root keys.
The critical difference from the original tutorial is that a public WebSocket endpoint plus uncontrolled tools turns a wearable UX experiment into a production security boundary.
My production Hermes profile had all of these tools enabled for Slack and Telegram. I couldn’t accept the glasses inheriting those permissions unchanged.
How does Hermes platform-level tool isolation work?
Hermes platform-level tool isolation is a configuration mechanism that assigns different toolsets to each platform—Slack, Telegram, even_g2, etc.—via platform_toolsets. Hermes’ runtime supports plugin platforms transparently; the friction was with the CLI.
When I tried to configure tools for even_g2 via CLI, Hermes rejected it:
✗ Unknown platform 'even_g2'. Valid: cli, telegram, discord, slack, whatsapp, ...
But reading the source made the picture clearer:
plat_info = PLATFORMS.get(platform)
if plat_info:
default_ts = plat_info["default_toolset"]
else:
# plugin platform
default_ts = f"hermes-{platform}"
Plugin platforms are first-class at runtime and derive a default toolset name (hermes-even_g2), but the CLI hardcodes built-in platforms only.
The solution was to bypass the CLI and edit config.yaml directly:
platform_toolsets:
even_g2:
- web
- memory
- session_search
- clarify
This keeps the full 17-tool profile for Slack and Telegram while restricting G2 to a safe subset:
- Allowed: web browsing, memory access, session search, clarification questions.
- Denied:
terminal, file tools,code_execution,computer_use, and any other high-risk tools.
One subtle discovery: hermes-even_g2 wasn’t registered in the toolset registry, so the default toolset for G2 was effectively an empty list. Until platform_toolsets.even_g2 is defined, the platform’s permissions are undefined—but not necessarily safe.
Explicitly setting
platform_toolsetsis both a lockdown and a normalization step. It removes ambiguity about what the glasses can or can’t do.
This kind of platform-scoped tool policy is broadly similar to role-based agent permissions in other frameworks—for example, OpenAI Assistants’ tool configuration at https://platform.openai.com/docs/assistants/tools/.
How do you prove that tool isolation really works?
Tool isolation is validated by correlating Hermes logs—specifically the api_calls count—with expected tool invocations. The heuristic: a tool-using turn requires at least two LLM calls, one to decide on the tool and one to synthesize the final answer with tool results.
In my logs:
| Question from glasses | api_calls |
Interpretation |
|---|---|---|
| “Tell me current disk usage” | 1 | No tool round-trip → terminal blocked |
| “What is my project codename?” | 2 | Tool round-trip → memory used |
| “How’s the weather?” | 3 | Tool round-trip → web used (and follow-up) |
A single
api_callsentry for a tool-suspect question is empirical proof that the model answered directly without executing tools.
Asking for disk usage via G2 produced a safe, instructional answer (“You can run this command on the server to check…”). The same question via Slack triggered real shell execution. That difference shows three things:
- The agent still understands the question.
- Dangerous tools are truly unavailable to the G2 platform only.
- Benign tools like
memoryandwebcontinue to work normally.
This log-level validation is mandatory any time platform-scoped security is configured. Configuration syntax alone isn’t an assurance boundary.
How should you install the G2 Hermes app so it works outside your LAN?
The G2 Hermes app installation is the step that decides whether the system actually works over cellular and public networks, rather than just at home. Even’s developer QR mechanism is fundamentally “open this URL in G2’s WebView.”
If that URL points to a local dev server like http://192.168.1.100:5173, then:
- The app loads on home Wi-Fi when the dev server is reachable.
- The app silently fails to load on cellular or external networks.
- The Hermes bridge logs nothing, because it’s never reached.
I hit exactly this: switching to cellular killed the experience even though the VPS bridge was reachable. The WebView never booted, so there was nothing to debug.
Two viable solutions:
- Serve the built app from the VPS.
- Build the app, upload the
dist/bundle behind nginx or another HTTP server on the VPS, and generate a developer QR pointing to that URL. - This removes any dependency on the Mac dev server.
-
The app still requires scanning a QR every time you want to open it.
-
Use Even Hub Beta Testing for persistent install.
- Package the app as
.ehpkvia the Even CLI (pack), then upload it in the Even developer console. - Add your account to the testing group, and the app appears in the phone’s Developer hub with a persistent Open button.
- No further scanning required.
The Even CLI exposes init, login, qr, self-check, and pack, but does not upload—that must be done via the web console. Keeping the build as Private ensures it never reaches the public store.
Treat the app hosting decision as a first-class architecture choice. It literally decides whether “works on the street with 5G” is real or a local demo mirage.
Why is Korean speech recognition only “half-successful” on G2?
Korean speech recognition on the G2 Hermes stack is constrained by both Even’s SDK and the VPS compute budget, making whisper-tiny the only viable option on 1 vCPU. The problem isn’t just accuracy—it’s about what happens when accuracy breaks down.
My observations:
- Even SDK transcription API is missing.
- The Even SDK type definitions have ~1,292 lines, but zero occurrences of
transcri,speech, orasr. -
Only raw PCM is exposed. There’s no native transcription API to tap into.
-
WebView-level speech APIs are blocked.
webkitSpeechRecognitionexists in the environment but throwsnot-allowedwhen called.- A diagnostic page confirmed that even with iOS-level speech permissions enabled for the app, the WebView can’t use the Web Speech API.
-
This matches the SDK design: voice permissions are reserved for native features, not arbitrary web code.
-
Alternative models are constrained by platform support.
- The
parakeetmultilingual model backend is macOS-only in practice and can’t be deployed on a Linux VPS.
The remaining axis is Whisper model size versus latency on 1 vCPU, measured on a 1.9-second Korean utterance:
| Model | Measured time | Extrapolated for 4s speech |
|---|---|---|
| tiny | 1.84 s | ~4 s |
| base | 3.03 s | ~6 s |
| small | 6.22 s | ~13 s |
For interactive G2 use, small is unusable. Combined with LLM response time, total latency would exceed 20 seconds.
Under noise (SNR ~5 dB), failure patterns diverged sharply:
| Model | Noisy output example |
|---|---|
| tiny | Chỉ cần thịt tuyền nhanh lại là do (collapsed to Vietnamese) |
| base | 지금 디스틱 육면 날려줘 (garbled but Korean) |
| small | 지금 비스 용량 알려줘 (near-correct Korean) |
This is where things get genuinely tricky. An LLM can often infer intent from garbled Korean. It cannot repair a switch into another language. That makes tiny’s failure mode dangerous even if it seems fast and light on paper.
Despite that, the resource ceiling forces whisper-tiny on 1 vCPU. I registered whisper-small in the agent registry but pinned the runtime to tiny via environment variable. With more CPU (4 vCPU minimum, 8 vCPU comfortable, 8GB RAM), switching up is a one-line config change.
Setting
compute_type="int8"yields identical transcription with roughly 30% lower latency—an automatic win for any Whisper model in this stack.
For deeper background on Whisper behavior across languages and noise: https://github.com/openai/whisper
Which option is better for you: OpenClaw or Hermes for G2?
| Option | Best for | Pros | Cons |
|---|---|---|---|
| OpenClaw + Windows (original video) | Local-only experiments on a Windows box |
– Turnkey tutorial path – Tailscale-based remote access – Soniox ASR quality for supported languages |
– Requires Windows PC always on – Adds paid cloud STT vendor – Separate agent from existing Slack/Telegram stack |
| Hermes + VPS + G2 plugin (this setup) | Existing Hermes users wanting unified context |
– Reuses production Hermes agent – On-device ASR, no STT fees – Fine-grained platform tool isolation |
– Requires VPS ops and reverse proxy – Korean ASR limited by CPU and Whisper size – Plugin maintenance largely unattended as of late June |
Hermes becomes the obvious choice once you already have a Hermes agent in production with accumulated memory and multi-platform channels. The incremental complexity of the VPS bridge is smaller than the cognitive and operational cost of running a parallel agent just for the glasses.
What are the eight real-world pitfalls you are likely to hit?
These are concrete failure modes I actually encountered while building and deploying the Hermes + G2 setup, ordered by likelihood.
- Profile selection uses
HERMES_HOME, notHERMES_PROFILE. - Hermes chooses profiles by pointing
HERMES_HOMEatprofiles/<name>. - If misconfigured, Hermes silently falls back to the root profile, making it appear as if config changes “do nothing.”
-
I hit this three times in a single day.
-
Pairing is per server, not global.
- Even’s
package_iddoesn’t carry pairing approvals across servers. - Approvals granted on a Mac don’t apply when the bridge moves to a VPS.
-
Every new server requires a fresh pairing approval.
-
Authentication failures leave no server logs.
- When the token is wrong, the bridge closes the WebSocket with code 1008 and no body.
- Hermes never sees the connection; empty logs are normal here.
-
The only reliable diagnostic is to reproduce the failure in a client and check its logs.
-
hermes toolsCLI rejects plugin platforms but runtime honors them. - The CLI gives an “Unknown platform” error for
even_g2. - Runtime logic uses the default toolset name
hermes-even_g2and supports it fully viaplatform_toolsets. -
Don’t treat CLI validation as an ultimate gate for plugin platforms.
-
Adding a service to a container can silently break existing Traefik routers.
- Without explicit
service=on routers, Traefik’s auto-linking becomes ambiguous when multiple services are declared. - The result is HTTP 404s and errors like
cannot be linked automatically with multiple Services. -
Fix this by adding explicit
service=to all affected routers, not just the new one. -
.ehpkis a custom format, not a simple ZIP. - File signatures start with
EHPK; there’s nounpackcommand in the CLI. - Content can’t be easily inspected or validated locally.
-
The only realistic verification is “install it on the phone and see if it works.”
-
Reusing the same Telegram bot token on multiple Hermes instances causes polling conflicts.
- Running Hermes on both Mac and VPS with the same
TELEGRAM_BOT_TOKENtriggers:
Conflict: terminated by other getUpdates request - After several retries, one side gives up.
-
The fix is ensuring only the production instance keeps the token.
-
The Hermes dashboard Host/Port inputs for the plugin are cosmetic.
- As documented in plugin issue #24, the adapter reads environment variables, not
config.yaml. - The dashboard UI updates the YAML only, giving a false sense of applied changes.
- All meaningful configuration must go through environment variables.
These pitfalls illustrate that “it compiles” is nowhere close to “it works over 5G with real users and proper security boundaries.”
Frequently Asked Questions
Q: How do you connect Even Realities G2 smart glasses to Hermes?
A: The connection uses the hermes-evenhub-bridge plugin as a WebSocket gateway and the hermes-even-hub-app as a WebView client on G2. After installing the plugin with hermes plugins install, you run hermes even-g2 setup and approve pairing, then host the WebView app on a publicly reachable URL so the G2 can load it via Even Hub.
Q: How can you safely restrict what the glasses are allowed to do?
A: Configure platform_toolsets in config.yaml for the even_g2 platform. Assign only benign tools like web, memory, session_search, and clarify, and omit high-risk tools like terminal, file, or code_execution. The glasses can then access information without being able to execute commands or modify the system.
Q: Why is the G2 token considered as sensitive as a root credential?
A: The G2 token is a bearer credential that gives full control over the Hermes agent within the platform’s toolset—including shell and file operations if those tools are enabled. In a self-hosted environment, that’s effectively root-equivalent, since an attacker could execute arbitrary commands and write files on the server.
Q: Why does Korean speech recognition perform poorly in this setup?
A: Korean ASR quality is limited by both the lack of a native transcription API in Even’s SDK and the VPS compute budget. On 1 vCPU, only whisper-tiny offers acceptable latency, but it often breaks under noise—sometimes collapsing into another language entirely. Larger Whisper models improve robustness but introduce 10–20 second latencies per utterance, which doesn’t work for interactive smart glasses.
Q: How do you ensure the glasses app works over cellular networks?
A: The G2 WebView app must be served from a public URL on the VPS, not from a local dev server on the Mac. Either host the built app bundle on the VPS and generate a developer QR pointing there, or package it as .ehpk and distribute it via Even Hub Beta Testing so it persists in the Developer hub with an Open button.
Conclusion
The combination of Hermes and Even Realities G2 turns the glasses into a first-class client of a production agent rather than a toy hanging off a Windows PC. By leaning on existing Hermes infrastructure and plugins, the real work shifted from “can it run” to “can it run safely and everywhere.”
The biggest gain over the original OpenClaw setup is platform-level isolation: the glasses share all the memory and context of the main agent while being denied shell, file, and code execution. The logs confirm that dangerous tools genuinely don’t fire, even when asked.
The costs are real though. Plugin maintenance is effectively frozen as of late June, .ehpk is a black box without tooling, and Korean ASR is capped by hardware until more CPU gets provisioned. But for many self-hosters, this path offers something off-the-shelf stacks rarely deliver: a wearable interface to an agent already woven into Slack, Telegram, and server operations—without handing root rights to a pair of glasses.
This is the first article in a two-part series. How the work actually went — three reversed verdicts in a single day — is in AI agents and smart glasses: why process wins.
Found this article helpful?
Get more tech insights delivered to you.


Leave a Reply