> ## Documentation Index
> Fetch the complete documentation index at: https://cofounder.appeeky.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Hosting a coding agent for Appeeky

> How to expose Hermes (or OpenClaw) to Appeeky with a durable public HTTPS URL.

Appeeky delegates implementation to **your** coding agent. You host the gateway; Appeeky only stores a public `baseUrl` + API key and triggers runs after you approve them.

## What Appeeky requires

| Requirement            | Why                                                                              |
| ---------------------- | -------------------------------------------------------------------------------- |
| Public `https://` URL  | Production rejects `http://` and private/loopback IPs (SSRF guard)               |
| Stable hostname        | Quick-tunnel URLs (`*.trycloudflare.com`) change on restart — break Integrations |
| Strong bearer key      | Only credential Appeeky sends (`Authorization: Bearer …`)                        |
| Gateway reachable 24/7 | Runs are triggered from Appeeky's servers, not your laptop                       |

## Recommended: small VPS + named Cloudflare Tunnel

This is the path we recommend for customers (and what we use for our own smoke tests).

### 1. Provision a VPS

Any small Linux box works — Hetzner CX22/CX32, DigitalOcean, OVH, etc. Ubuntu LTS is fine. **Do not open inbound ports** for the gateway; the tunnel dials out.

### 2. Install Hermes (example)

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
# Authenticate / configure LLM access (hermes setup / portal / API keys)
```

In `~/.hermes/.env`:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
API_SERVER_ENABLED=true
API_SERVER_KEY=$(openssl rand -hex 32)   # save this — it is your Appeeky apiKey
API_SERVER_PORT=8642
API_SERVER_HOST=127.0.0.1               # tunnel connects locally; no public bind
```

Run as a systemd service (so reboot / SSH disconnects don't kill it):

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# hermes-gateway.service → ExecStart=/usr/local/bin/hermes gateway run
sudo systemctl enable --now hermes-gateway
curl -s -H "Authorization: Bearer $API_SERVER_KEY" http://127.0.0.1:8642/health
```

### 3. Durable public URL with a **named** Cloudflare Tunnel

Quick tunnels (`cloudflared tunnel --url …`) print a random `*.trycloudflare.com` hostname that **changes every restart**. Use a named tunnel + your domain instead.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# On the VPS (or your laptop once, then copy the credentials file)
cloudflared tunnel login
cloudflared tunnel create appeeky-hermes
# Creates ~/.cloudflared/<TUNNEL_ID>.json

cloudflared tunnel route dns appeeky-hermes hermes.yourdomain.com
```

`~/.cloudflared/config.yml`:

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
tunnel: <TUNNEL_ID>
credentials-file: /root/.cloudflared/<TUNNEL_ID>.json

ingress:
  - hostname: hermes.yourdomain.com
    service: http://127.0.0.1:8642
  - service: http_status:404
```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
sudo systemctl enable --now cloudflared   # or a unit that runs: cloudflared tunnel run appeeky-hermes
curl -s -H "Authorization: Bearer $API_SERVER_KEY" https://hermes.yourdomain.com/health
```

### 4. Connect in Appeeky

**Settings → Integrations → Coding agents → Hermes**

* **Base URL:** `https://hermes.yourdomain.com`
* **API key:** the `API_SERVER_KEY` you generated

Appeeky calls `GET /v1/capabilities` before saving. On success the Co-founder can propose `engineering_delegate` actions (always approval-gated).

## OpenClaw (same VPS pattern)

OpenClaw's gateway defaults to port **18789**. Enable hooks ingress in your OpenClaw config:

```js theme={"theme":{"light":"github-light","dark":"github-dark"}}
hooks: {
  enabled: true,
  token: process.env.OPENCLAW_HOOKS_TOKEN,
  path: "/hooks",
  allowRequestSessionKey: true,
  allowedSessionKeyPrefixes: ["hook:"],
  allowedAgentIds: ["engineering", "main"],
}
```

Tunnel it the same way (quick tunnel for smoke, named tunnel for prod):

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
ingress:
  - hostname: openclaw.yourdomain.com
    service: http://127.0.0.1:18789
  - service: http_status:404
```

**Settings → Integrations → OpenClaw**

* **Gateway URL:** `https://openclaw.yourdomain.com`
* **Hook token:** your `hooks.token`

Appeeky probes `GET /healthz` and verifies the hook token before saving. OpenClaw runs are fire-and-forget — results arrive on your configured delivery channel (Slack/Telegram) if you set `deliver` + `to`.

## Alternatives

| Setup                                                | When to use                                                               |
| ---------------------------------------------------- | ------------------------------------------------------------------------- |
| **VPS + Caddy/nginx TLS** (bind `0.0.0.0`, open 443) | You prefer classic reverse proxy over Cloudflare                          |
| **Quick Cloudflare / ngrok tunnel**                  | Local smoke tests only — URL will change; not for production              |
| **Tailscale + funnel / serve**                       | Private team networks; Appeeky still needs a publicly reachable HTTPS URL |

## Security checklist

* [ ] `API_SERVER_KEY` is ≥32 random bytes (`openssl rand -hex 32`)
* [ ] Gateway listens on `127.0.0.1` when fronted by a tunnel/proxy
* [ ] Inbound firewall blocks everything except SSH (tunnel/proxy only)
* [ ] Don't paste private keys or `API_SERVER_KEY` into chat / tickets
* [ ] Rotate the key in Hermes `.env` + Appeeky Integrations if leaked
* [ ] Appeeky stores the key encrypted at rest (`COFOUNDER_CREDENTIALS_SECRET`)

## What happens after connect

1. Co-founder spots a feature gap → proposes `engineering_delegate`
2. You approve in Actions / chat
3. Appeeky `POST`s `/v1/runs` to your gateway
4. A background poller refreshes run status every \~10 minutes (and on the next briefing / manual refresh)
5. Hermes opens a **draft PR** and optionally notifies your channel
