registerEvent handles the subscription side of the protocol. Skybridge lists your event types, checks who is subscribing and with which arguments, verifies the callback URL, and then hands the subscription to your onSubscribe hook. Delivering the events is up to whatever already knows when they happen, usually your backend’s webhook system. deliverEvent does the delivery for you when that system runs on Node.
Example
A document app lets users subscribe to new comments on one document. Its backend already sends webhooks, soonSubscribe registers ChatGPT’s callback there.
Parameters
config
hooks
subscription carries:
Refreshes
Subscriptions are short-lived. Theevents/subscribe response tells the host to subscribe again before expiresAt, and the host keeps the subscription alive by sending the same request again. Skybridge keeps no state, so a refresh looks exactly like a first subscribe: onSubscribe runs again with the same subscription.id and a later expiresAt, and possibly a new secret.
Write onSubscribe as an upsert keyed on subscription.id: create the webhook the first time you see the id, then update its expiresAt and secret. If your webhook system can’t expire webhooks, store expiresAt next to the webhook and stop delivering once it has passed. deliverEvent already refuses to post to an expired subscription.
extra is the same as in a registerTool handler: extra.http.authInfo tells you who is subscribing.
Returns the server, so calls chain.
deliverEvent
id so the host can drop duplicates, and reuse it when retrying. Pass secret as an array to sign with several secrets during a rotation. A subscription past its expiresAt is not posted to and returns { ok: false, reason: "expired", retryable: false }. Otherwise it makes one attempt and returns { ok: true } or { ok: false, reason, retryable, status }, where status is the HTTP status when the host answered. A 410 or 413 is not retryable. Retrying is up to you.
How it works
- Subscribing requires a signed-in user: set
oauth. - Callback URLs must be
httpsand resolve to public addresses. UnlessNODE_ENVisproduction,httpand local addresses are allowed so you can test with a local receiver.skybridge startsetsNODE_ENV=production; set it yourself if you run the server another way. - Subscriptions last 30 minutes unless the host asks for another lifetime, at most 24 hours.
- Payloads are capped at 256 KiB. Send a summary and let the model fetch the rest with a tool.
- Events are not replayed: an event sent while a subscription has lapsed is lost.
registerTool
Tools the model calls, and the
extra they receiveMcpServer
Every method of the server