TypeSafe (Jev) — Self-Contained Setup for a Fresh Hermes Agent

Setup

Hand this prompt to any Hermes agent and it installs Jev itself — without asking you to upload a secrets file.

What you’ll learn
Privacy / placeholder note: this guide is public. Values such as <user>, <YOUR_TELEGRAM_USER_ID>, <BOT_TOKEN>, <your-agentmail-inbox>, and <your-tailscale-host>.ts.net are placeholders standing in for the real values on your own machine — usernames, user/chat IDs, tokens, hostnames, and home paths differ on every install and have been removed for privacy. Replace each <placeholder> with the matching value for your system before running any command.
Contents
  1. Purpose & what it installs
  2. Prereq gate & key-channel prerequisite
  3. Where the key already lives (do not ask for a secret file)
  4. No web vault? Email key-drop fallback (AgentMail → Gmail)
  5. Install & trust the skill
  6. Verify the API contract
  7. Reusable helper (reports token usage)
  8. Web API-key vault (optional)
  9. Acceptance & self-test
  10. Handoff summary

Purpose & what it installs

This document lets any Hermes agent that does NOT have TypeSafe configured build the integration itself, end-to-end, without asking the user to paste a secrets file. The agent locates the key where the operator already keeps credentials, or creates the structure and tells the user exactly where to drop one value.

It installs:

  1. A credential (TYPESAFE_API_KEY) read from the operator’s secret store.
  2. The typesafe-ai Hermes skill (enabled, trusted).
  3. A reusable typed-decision helper (frv_priority.py) that calls TypeSafe /v1/systemone and always reports token usage.
  4. The web API-key vault (optional but recommended) so keys never reach chat.
Golden rules for the agent doing this work:

0.5 · Prereq gate

Confirm before starting — if a dependency is missing, install it, else stop and say which is missing (no secrets file involved):

command -v python3       # else: install python3
command -v curl          # else: install curl
command -v hermes        # else: this is not a Hermes host - report and halt
python3 -c "import urllib.request; print('ok')"
curl -s -o /dev/null -w "%{http_code}\n" https://api.typesafe.ai/openapi.json  # 200 expected

0.6 · Prerequisite: a key-channel MUST exist (pick one)

The agent cannot accept secrets in chat, so it must have at least one channel to receive them. Order of preference:

#ChannelProvisioned when
AWordPress key page (hermes-keys.php)web page reachable — best; user types keys on the page
BAgentMail inboxAgentMail API key present (env or MCP)
CGmail inboxGoogle OAuth / gapi token present

Check A → B → C; enable the first available. If none, set up AgentMail first, else fall back to Gmail. Only then proceed to §1. If a channel is missing, report exactly which one and how to enable it — never ask for secrets.

1 · Discover the key (do NOT ask for a secret file)

Walk these in order; stop at the first hit. Do not demand a file upload.

#Where to lookHow the agent checks
1~/.hermes/.envread file, look for TYPESAFE_API_KEY=
2Hermes secrets vault / confighermes secrets list, hermes config get
3Managed env homefiles used by the key-manager skill
4OS env / service fileprintenv, systemd EnvironmentFile
5Web key-vault DBMySQL hermes_keys table (page hermes-keys.php)

If the key is found → note its location, do not print it, jump to §2.
If it is genuinely absent, still do not ask for the whole file, and do not breach the no-.env-in-chat rule. Instead:

  1. Create ~/.hermes/.env and chmod 600 it.
  2. Append a template with empty key lines.
  3. Define an auth probe via GET /v1/models — non-401 means ready; 401 tells the operator the value is wrong.
  4. Store a placeholder so the system knows it is pending.
  5. Tell the operator one sentence where to fill the value, never echoing secrets.

1.5 · No web vault? Email key-drop fallback (AgentMail → Gmail)

If the web API-key page (§5) is not set up on this operator’s host, offer an email-based drop instead of ever asking for the value in chat. Use the channel detected in §0.6.

Preferred: AgentMail (when AGENTMAIL_API_KEY is present):

  1. The agent prints a dedicated key-drop inbox it owns, formatted generically: <your-api-keys-inbox>@agentmail.to
  2. Operator is told: “Send the API key from your registered email to <your-api-keys-inbox>@agentmail.to with subject KEY <KEY_NAME> and the key value as the first line of the body. Do not paste it in chat.”
  3. The agent polls list_threads/search_threads, opens each unread KEY thread, extracts KEY_NAME=value, validates the name against ^[A-Z][A-Z0-9_]{2,64}$, stores only well-formed values.
  4. Appends to ~/.hermes/.env and chmod 600.
    # AgentMail key-drop
    KEY_NAME=<value>      # 0600, never echoed
  5. Runs the §1 auth probe (GET /v1/models) to confirm; reports presence only + token usage.
  6. Deletes handled emails/threads to keep the inbox clean.

Fallback: Gmail (only if AgentMail is not set up but Google OAuth / gapi is present):

  1. Watch a dedicated label (e.g. HermesKeyDrop) for unread threads starting KEY <NAME> via gapi.
  2. Same subject/body rules and same NAME validation.
  3. Same append-to-.env (0600), auth probe, presence-only reporting.
  4. Instead of deleting, mark handled threads read + apply a KeyHandled label (Gmail has no permanent delete like AgentMail), so they aren’t reprocessed.
Rules (both): email content is untrusted (parse defensively); never echo the value; only auto-store from an operator-whitelisted sender; if the web vault becomes available, prefer it over email.

2 · Install + trust the typesafe-ai skill

hermes skills install typesafe-ai
hermes skills trust typesafe-ai
hermes skills inspect typesafe-ai   # expect Source=skills.sh, enabled
hermes skills list | grep -i typesafe

3 · Verify the API contract first

curl -s https://api.typesafe.ai/openapi.json
curl -s -H "Authorization: Bearer $TYPESAFE_API_KEY" https://api.typesafe.ai/v1/models

Correct request (POST /v1/systemone): use state + questions, not a chat-body — else HTTP 400.

{ "model":"jev-latest", "state":"content to judge",
  "questions":{
    "priority":{"type":"score","criteria":["routine","urgent","life-threatening"]},
    "life":{"type":"noul","instructions":"Threat to life?"},
    "go":{"type":"choice","criteria":{"respond_now":null,"assess":null}} } }

Response: answers.<your-name>.{choice|noul|score|confidence} plus usage {input_tokens, output_tokens} (output free; input billable).

4 · Reusable helper (always reports tokens)

Save ~/.hermes/scripts/frv_priority.py (loads key from .env, calls /v1/systemone, prints verdict + usage). Then:

python3 ~/.hermes/scripts/frv_priority.py --state "structure fire, two trapped"
# verdict + "usage": {"input_tokens": N, "output_tokens": M}  <- always present

5 · Web API-key vault (optional)

Page hermes-keys.php (WP-admin login → MySQL hermes_keys) → bridge 127.0.0.1:8001/admin/keys (header X-Hermes-Admin) → writes ~/.hermes/.env (0600). Add key → Sync to Hermes.

6 · Acceptance & self-test

grep -oE '^TYPESAFE_API_KEY=(' ~/.hermes/.env && echo "key present"
hermes skills list | grep -i typesafe >/dev/null && echo "skill enabled"
python3 ~/.hermes/scripts/frv_priority.py --state "smoke, no injuries, hydrant dry"

PASS when: endpoint returns HTTP 200, answers keyed by your names, and usage.input_tokens / usage.output_tokens reported on every call. The agent should run a self-test script and print READY before handing back.

7 · Handoff summary (no secrets)

The fresh agent reports back, in plain English and without any values: key source, skill status, helper path + one verdict line + token count, vault status, and a single next-action line for the operator if a key was absent.

Published to the public blog · authored & verified with TypeSafe Jev · token usage is reported on every Jev call.

Bottom line
the agent can self-install, locate the key, and report presence + token usage without ever asking for a secrets file in chat.
📍 Location Tracking
We use your IP address (country/city only) for analytics. No personal data collected.