Gateway — subscribe to live guild state
Gateway: subscribe to live guild state
Section titled “Gateway: subscribe to live guild state”The default discord-mcp transport is REST-only — every read is a fresh HTTP
call. For dashboards, presence indicators, or any UI that should reflect the
guild as it changes, polling burns rate limits and lags. The optional
--gateway mode replaces polling with MCP resource subscriptions backed by
the Discord Gateway WebSocket.
Use case
Section titled “Use case”A dashboard agent says: “Notify me whenever someone goes voice-active in guild XYZ, or when a moderator deletes a message.”
REST polling would mean spinning a 5-second loop hitting /voice-states and
/audit-logs per guild — expensive, slow, blunt. Gateway subscriptions give
the agent push notifications instead.
Five subscribable resource URIs
Section titled “Five subscribable resource URIs”| URI | Pushed by Gateway event |
|---|---|
discord://guild/{id}/info | GUILD_UPDATE |
discord://guild/{id}/members/online | PRESENCE_UPDATE (debounced) |
discord://channel/{id}/typing | TYPING_START |
discord://voice/{guild_id}/state | VOICE_STATE_UPDATE |
discord://guild/{id}/audit-log/recent | GUILD_AUDIT_LOG_ENTRY_CREATE (polled fallback) |
Tool flow
Section titled “Tool flow”-
Start the server with gateway mode.
Terminal window pnpm add discord.jsdiscord-mcp --gatewayOn startup the server connects to the Discord Gateway, authenticates with the bot token, and registers handlers for the five event types above.
-
Discover available resources.
The MCP method is
resources/list. The server returns the URIs above plus the standard tool-discovery resources.{ "method": "resources/list" }{"resources": [{ "uri": "discord://guild/111122223333444455/info", "name": "Guild info" },{ "uri": "discord://guild/111122223333444455/members/online", "name": "Online members" },{ "uri": "discord://channel/222233334444555566/typing", "name": "Typing in channel" },{ "uri": "discord://voice/111122223333444455/state", "name": "Voice state" },{ "uri": "discord://guild/111122223333444455/audit-log/recent", "name": "Recent audit log" }]} -
Subscribe to the URIs you care about.
The MCP method is
resources/subscribe. Subscribe individually per URI; the server records intent in an in-memory registry and only forwards events for subscribed resources.{"method": "resources/subscribe","params": { "uri": "discord://voice/111122223333444455/state" }} -
Handle update notifications.
Whenever the underlying Gateway event fires, the server emits a JSON-RPC notification using the standard MCP method
notifications/resources/updated. The agent reacts by callingresources/readto fetch the latest state — or by treating the notification itself as the signal, depending on the use case.{"method": "notifications/resources/updated","params": { "uri": "discord://voice/111122223333444455/state" }} -
Unsubscribe when done.
Long-lived agents should release subscriptions to keep the registry small. The server otherwise tears them down on disconnect.
{"method": "resources/unsubscribe","params": { "uri": "discord://voice/111122223333444455/state" }}
Why this exists
Section titled “Why this exists”- REST polling → push. Replacing a 5s polling loop with an event handler cuts both latency and rate-limit burn.
- Discord Gateway events → MCP resources. The Gateway speaks WebSocket events; MCP speaks resources. The server bridges the two so MCP clients can use the standard subscription primitive.
discord.jsis optional. The Gateway path importsdiscord.jslazily. Users who only need REST tools never pay the install cost.
Debounce
Section titled “Debounce”PRESENCE_UPDATE and TYPING_START can fire dozens of times per second on a
busy guild. The server debounces notifications per resource — rapid events
within a short window coalesce into one notifications/resources/updated
emission, so the agent’s notification stream stays sane.
Client compatibility
Section titled “Client compatibility”| Client | Resource subscription support |
|---|---|
| Claude Desktop | yes |
| Claude Code | yes |
| Cursor | no (use REST polling) |
| ChatGPT | no |
| Cline, Continue, Windsurf | no |
Clients that don’t advertise the capability should stick with the REST tools
(voice_get_user_state, audit_log_get, etc.) and a polling loop.
See also
Section titled “See also”- Installation → optional gateway — how to
install
discord.jsand pass--gateway. - Architecture: gateway resources — event handlers, debounce, and the subscription registry.
audit_log_get— REST equivalent for clients without subscription support.- Recipe: pipeline — for agents that need to react to a notification with a chain of tool calls.
- Operations: client capability matrix — full feature support across all major MCP clients.