Reach an internal service
Expose a private HTTP service through Notify Connector and the OpenTunnel relay. The public hostname reaches the service; a verified Notify pass or signed callback still determines who may use it.
Relay and connector lifecycle
The relay lives at https://api.clawchest.com; tunnel addresses are https://<id>.clawchest.com and named routes https://<route>.<id>.clawchest.com. Tunnel creation uses a Notify agent token (ntf_…), introspected at /api/relay/introspect. A public tunnel address provides reachability, not visitor authorization.
@belweave/notify-connectoruses OpenTunnel 0.5.1, declares public routes, registers web apps, and sends heartbeats. Notify retains its Cloudflare relay and AWS backend.- After five minutes without a heartbeat, the connector is marked offline. Its configured
oncallGroupIdcan receive a page. - A callback
targetcontainingconnectorId,route, andpathfollows the connector’s live address at delivery time.
Expose a local port
Run the web app and the Notify CLI on your computer. Keep both processes running, then open the registered app from Apps in Notify on your phone. This example connects a local warehouse dashboard on port 3000:
notify auth login
notify connect 3000 --name warehouse
# https://warehouse.<id>.clawchest.comOpenTunnel 0.5.1 adds optional PROXY protocol v1/v2 support. Use notify connect 3000 --name warehouse --proxy-protocol v2 only when that upstream listener explicitly accepts PROXY protocol before HTTP, or before TLS for an HTTPS upstream. Ordinary web servers should omit the flag. In the SDK, a route can be { target: "127.0.0.1:3000", proxyProtocol: "v2" }; plain string routes keep their existing behavior. The authenticated gateway remains mandatory and forwards the preamble only after authorization. Visitor addresses come from the relay connection, not caller-supplied HTTP forwarding headers.
The connector adopts the 0.5.1 client’s reconnect and transient-failure handling. Certificate and tunnel state remain in memory for the running connector; restarting does not restore a persisted tunnel identity or certificate.
The named origin is registered as a Notify web app. The connector's mandatory gateway validates a one-time Notify pass, then rechecks current access for every page, asset, API request and WebSocket. The exact origin prevents a sibling route from reusing its pass. The updated notify connect and connectors rotate-secret save the callback signing secret in a mode-0600 file and print only its path, including with NOTIFY_TOKEN; the environment token itself is not saved. The normal locations are ~/Library/Application Support/notify/connectors on macOS and ~/.config/notify/connectors on Linux, or beside NOTIFY_CONFIG when set. Older CLI releases printed the secret to stderr; update before running in an agent log. Default logins include connector read/write scopes; narrowed or older logins need connectors:write. Rotate with notify connectors rotate-secret <id>.
Return an answer to a private receiver
To return an approval to a private receiver, register its listening port as a connector route and save that route plus the receiver path on the interaction. Notify signs the answer and sends it through the fixed /.notify/callback gateway ingress. The gateway authorizes the saved target, current workspace access and durable replay receipt before forwarding; callbacks cannot bypass sign-in on ordinary app routes.
# On the laptop: a tiny receiver on port 8780, then
# notify connect 8780 --name cb
# From CI or an agent:
notify send ask "Approve the maintenance window?" --approval --stdin <<'JSON'
{
"callback": {
"target": {
"connectorId": "conn_example_warehouse",
"route": "cb",
"path": "/approve"
}
}
}
JSONVerify Notify-Signature: v1=<hex> as HMAC-SHA256 of {timestamp}.{rawBody}, using Notify-Timestamp and the connector’s callbackSecret. A classic URL/token callback instead uses the callback token as its HMAC key and also sends a bearer Authorization header. Accept timestamps only within five minutes and reject future values.
{
"type": "notification.response",
"interactionId": "int_example_pickup",
"actionDigest": "<the stored interaction actionDigest>",
"eventId": "evt_...",
"kind": "approval",
"status": "approved",
"action": "approve",
"text": null,
"respondedAt": "2026-10-09T12:00:00.000Z"
}verifyCallbackSignature for this format. Verify before acting and deduplicate by interactionId because retries can repeat answers. Legacy service receivers may also use eventId; agent-created asks can have a null event ID. Map a verified canonical action to a known operation; do not execute text from the callback as a shell command.SDK middleware for a private site
The connector registers a hosted-app origin and places its mandatory gateway in front of the private dashboard. The gateway validates ES256, exact issuer and origin audience, expiry, app/workspace claims, durable one-time replay consumption and current access. It covers static assets and WebSocket upgrades as well as application requests. Your server still authorizes access to its own data using the gateway’s verified identity, and its listener must not be publicly reachable around that gateway.
For direct integrations, the SDK also supplies honoNotifyPass, expressNotifyPass, and fastifyNotifyPass. Configure issuer https://notify.belweave.ai, the exact audience, and the required atomic durable consumeJti store; the connector README includes a database example. Missing or unavailable replay storage denies access. These raw-pass helpers are separate from the gateway’s short-lived sessions and continuous revocation checks. verifyNotifyPass alone verifies cryptography, not replay or current membership.
Agent API reference
Route inventory for scoped HTTP clients, with the canonical generated schemas. The CLI and MCP tools use this API; human consent is described in [Access and consent](#access).
Existing team administration
These operations support existing workplace teams. New team signup is unavailable. Teams share organization resources while members keep their own accounts and sign-in choices; [families](#family) have a smaller, separate feature set.