doc/HERMES_GATEWAY_ONBOARDING.md
Use this guide when a Hermes runtime should join Paperclip as an external
hermes_gateway employee. This mirrors the OpenClaw gateway invite path, but
Hermes uses the generic agent invite/onboarding flow instead of the
OpenClaw-specific invite prompt endpoint.
Paperclip ships both Hermes adapters as built-ins:
hermes_local runs the local hermes CLI as a child process on the
Paperclip host.hermes_gateway calls an already-running Hermes API server over HTTP/SSE.No Adapter manager installation is required for normal use. Adapter manager is
only needed when you intentionally install an external
@paperclipai/hermes-paperclip-adapter package to override or shadow a built-in
adapter while developing the Hermes package. If the external override is paused
or removed, Paperclip restores the built-in hermes_local / hermes_gateway
adapter.
Keep these credentials distinct:
OPENROUTER_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY,
GEMINI_API_KEY, GOOGLE_API_KEY, or MISTRAL_API_KEY.API_SERVER_KEY before starting Hermes. Paperclip
stores the same value as agentDefaultsPayload.apiKey so it can call Hermes.PAPERCLIP_API_KEY when it calls Paperclip.Do not reuse the Hermes gateway key as the Paperclip agent key. The Hermes gateway key authenticates Paperclip-to-Hermes traffic; the claimed Paperclip key authenticates Hermes-to-Paperclip traffic.
Install and configure Hermes first:
pip install hermes-agent
export OPENROUTER_API_KEY='<provider-key>'
export API_SERVER_KEY='<random-gateway-key>'
API_SERVER_ENABLED=true hermes gateway run --replace --accept-hooks
The default Hermes API server port is 8642. For local loopback testing,
Paperclip can usually store http://127.0.0.1:8642 as the gateway URL. For
Docker, LAN, tailnet, or reverse-proxy setups, use a URL reachable by the
Paperclip server process.
Plain HTTP is accepted for loopback. Non-loopback HTTP is denied by default in
the join flow; use HTTPS for real remote gateways. For private local
development only, the join payload can set
dangerouslyAllowInsecureRemoteHttp: true, and the smoke scripts expose the
same escape hatch as HERMES_GATEWAY_ALLOW_INSECURE_HTTP=1.
In the board UI:
The UI prompt points Hermes at the same machine-readable onboarding endpoints:
GET /api/invites/:tokenGET /api/invites/:token/onboardingGET /api/invites/:token/onboarding.txtGET /api/skills/indexGET /api/skills/paperclipFor CLI-driven setup, create and inspect the invite directly:
pnpm paperclipai invite create --company-id <company-id> --payload-json '{"requestType":"agent"}'
pnpm paperclipai invite show <token>
pnpm paperclipai invite onboarding:text <token>
Hermes should submit a join request with requestType: "agent" and
adapterType: "hermes_gateway":
{
"requestType": "agent",
"agentName": "Hermes Gateway Engineer",
"adapterType": "hermes_gateway",
"capabilities": "Hermes gateway agent with code, browser, web, and file tools.",
"agentDefaultsPayload": {
"apiBaseUrl": "http://127.0.0.1:8642",
"apiKey": "<same-value-as-API_SERVER_KEY>",
"paperclipApiUrl": "http://127.0.0.1:3100",
"sessionKeyStrategy": "issue"
}
}
Important URL roles:
agentDefaultsPayload.apiBaseUrl is the Hermes gateway URL that Paperclip
calls.agentDefaultsPayload.paperclipApiUrl is the Paperclip base URL that Hermes
can call after approval and key claim.PAPERCLIP_API_URL / PAPERCLIP_API_KEY are injected runtime values for
Hermes-originated Paperclip API calls after the agent is approved.After Hermes submits the join request:
In Paperclip, review the pending agent join request.
Approve it from the board UI, or use:
pnpm paperclipai join list --company-id <company-id> --status pending_approval
pnpm paperclipai join approve <request-id> --company-id <company-id>
Hermes claims the one-time agent API key:
pnpm paperclipai join claim-key <request-id> --claim-secret <secret>
Store the claimed Paperclip key in Hermes runtime state or secrets. The claim secret and claimed key are sensitive and should not be pasted into issue comments, logs, or prompt text.
Once the key is claimed, create an issue assigned to the new Hermes gateway agent and wake it through the normal Paperclip heartbeat path.
For a fresh Docker-backed Hermes gateway and end-to-end Paperclip join/run verification, use:
PAPERCLIP_API_URL=http://127.0.0.1:3100 \
PAPERCLIP_AUTH_HEADER='Bearer <board-token>' \
pnpm smoke:hermes-gateway-e2e
The E2E smoke:
/health, /v1/capabilities, /v1/runs, SSE, and stophermes_gatewayIf a Hermes gateway is already running and you only need to validate the invite and stored adapter config, use the join-only helper:
API_SERVER_ENABLED=true API_SERVER_KEY='<gateway-key>' hermes gateway run --replace --accept-hooks
PAPERCLIP_API_URL=http://127.0.0.1:3100 \
PAPERCLIP_AUTH_HEADER='Bearer <board-token>' \
HERMES_GATEWAY_API_BASE_URL=http://127.0.0.1:8642 \
HERMES_GATEWAY_API_KEY='<gateway-key>' \
pnpm smoke:hermes-gateway-join
See HERMES_GATEWAY_SMOKE.md for Docker Desktop, Linux, same-network Docker, LAN/private-network, and reverse-proxy/TLS examples.
Use these entry points depending on who is driving setup:
GET /api/invites/:token/onboarding.txt for the generated
llm.txt-style setup instructions.pnpm paperclipai invite create, invite show,
invite onboarding:text, join approve, and join claim-key.pnpm smoke:hermes-gateway-e2e for fresh-state Docker
verification and pnpm smoke:hermes-gateway-join for an already-running
gateway.@paperclipai/hermes-paperclip-adapter as an external override, but normal
operators should use the built-in hermes_local and hermes_gateway
adapters.