Hermes Android · 2026

Android client for a self-hosted agent

In progress

Role
Independent engineer
Stack
Kotlin, Jetpack Compose, WebSocket
Status
In progress

Problem

A self-hosted agent is only as usable as the client you carry. A browser tab on a phone is a compromise: no lock worthy of the session, no PTY, and two streams fighting the same page.

Constraint

The agent stays on infrastructure you operate. The phone is a client, not a place to park keys in a web origin. Interface captures will wait until they exist.

Architecture

  1. Compose UI
  2. JSON-RPC socket
  3. Agent
  1. Keystore lock
  2. PTY socket
  3. Host
The phone holds a Compose client. Two WebSockets reach the self-hosted agent: one for chat, one for the terminal. Unlock is Keystore.

Decisions

  • Kotlin and Compose

    Native Material 3, sized for a phone, not a squeezed desktop UI.

  • Two WebSockets, one process

    JSON-RPC chat on one socket, a PTY on the other, without racing the UI. MVVM, Hilt, six Gradle modules.

  • Keystore for the lock

    PIN or biometric unlock through Android Keystore. The session is not "remember me" in a cookie.

This is a companion to the host stack, not a chatbot skin. If you already run an agent and need a phone that does not treat the session as a website, that is the brief.

Outcome

In progress. Pair with the agent infrastructure case if you need both the runtime and a phone client.

What was handed over

  1. Module map and how the two sockets are owned
  2. How the client is pointed at a host
  3. What the Keystore lock does and does not protect

hire@scrocle.cloud

Next project PwnLink Android companion for field hardware