Skip to content

Repository files navigation

cozygateway

Chat with your self-hosted AI agent from your phone, without handing your data to anyone.

cozygateway is a single self-hosted Node process you run next to your agent. It speaks a small published wire contract to chat clients and uses its attach data plane to let an agent harness dial in over a small WebSocket protocol and answer turns live.

Install

There are two ways in. Pick the one that fits your machine.

Simple (recommended): one line, runs as a service

curl -fsSL https://cozylabs.ai/install.sh | bash

No Docker, git, or build tools. It requires an existing Hermes installation and Node 24+. The bootstrap verifies versioned release checksums for the gateway bundle, complete Hermes attach-plugin archive, and installer payload. It discovers Hermes profile homes through the Hermes CLI, installs one attach identity per selected profile, and supervises one shared gateway service. Existing Hermes profile gateway services stay Hermes-owned. The default listener is local/LAN (0.0.0.0:8787); the installer never configures Tailscale, Cloudflare, DNS, firewalls, or tunnels. See docs/install-service.md and docs/connectivity.md.

Uninstall:

bash ~/.cozygateway/bin/agent-install.sh --uninstall --gateway-dir ~/.cozygateway

This removes CozyGateway-owned service state, plugin copies, spools, and installer-written env keys; Hermes profiles and Hermes services remain.

Existing Hermes install

The installer targets Hermes profiles already on this machine. For a narrower selection, pass --profiles default,ops to the one-paste command. The command uses the installed Hermes CLI as the source of truth for profile homes and does not clone a repository or create a Docker deployment.

How push works

Self-hosted gateways use https://push.cozylabs.ai by default so the store app works without APNs setup. The gateway encrypts every notification end to end before sending it. The hosted relay sees only an opaque push ID, ciphertext, optional category and collapse ID, and the source IP transiently for rate limiting. It never sees message content or device identity. Override COZYGATEWAY_PUSH_RELAY_URL to use another relay.

A relay you host with your own APNs key cannot push to the store app because APNs keys are scoped to the publisher team. The local-push Compose profile is for developers who sign their own app with their own Apple team.

What it does

  • Pairing: scan a QR code, get a revocable device token. No accounts.
  • Threads: multiple renameable DM threads per agent, each bound to its own backend session.
  • Streaming: agent replies stream live as typed rich content blocks over one WebSocket.
  • History: SQLite-backed message history with strict per-thread ordering and gap replay.
  • Push: end-to-end encrypted notifications through the accountless CozyLabs relay by default.

Status

  • Shipped: contract v1 (frozen), conformance suite, attach-v1 data plane, hosted relay plus encrypted push origination and APNs delivery (contract/push-v0.md), TLS for the phone link (gateway-native, or a shipped Caddy sidecar example; docs/tls.md).

Repo layout

  • contract/: the human-readable, versioned wire contract spec.
  • packages/contract: TypeBox schemas and TypeScript types for the contract (publishable as cozygateway-contract).
  • packages/gateway: the gateway process, implementing contract v1.
  • packages/relay: the push relay service (opaque push ids in, ciphertext through).
  • packages/conformance: contract conformance suite that runs against any gateway implementation, validated against the reference gateway.
  • integrations/attach-plugin: the reference Python platform plugin for the durable attach-v1 data plane; see contract/attach-v1.md and docs/attach-v1-operations.md.

Privacy model

Your messages live in SQLite on your box. The gateway must read plaintext to drive your agent, and it never sends message content outside your box. TLS for the phone link ships two ways, gateway-native or a Caddy sidecar example, and the app pins the certificate on first use; see docs/tls.md. Plain HTTP remains the default, for boxes that already terminate TLS in front. Push leaves the box only as end-to-end encrypted ciphertext.

Development

Requires Node 24+ and pnpm 10.

pnpm install
pnpm check   # typecheck + test + build

License

MIT

About

Chat with your self-hosted AI agent from your phone. Frozen wire contract, reference gateway, and conformance suite.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages