MCP Header Reference (X-*)

This document describes all supported X-* headers, their formats, edge-cases, and the effective security behavior in the Discord MCP.

Request Headers #

X-Target-Users #

  • Purpose: restrict actions targeting specific users.
  • Format: CSV of user snowflakes.
  • Special values:
  • *: unrestricted.
  • 0: explicit deny-all for user-targeted routes.
  • Examples:
  • X-Target-Users: 123456789012345678
  • X-Target-Users: 123456789012345678,234567890123456789
  • X-Target-Users: *
  • X-Target-Users: 0
  • Notes:
  • 0 disables DM-targeted tools such as send_direct_message.
  • When omitted or set to *, the Discord MCP leaves user targeting unrestricted.
  • When it names one or more explicit users, those IDs become the DM allowlist.

X-Target-Guilds #

  • Purpose: restrict actions targeting specific guilds.
  • Format: CSV of guild snowflakes.
  • Special values:
  • *: unrestricted.
  • 0: explicit deny-all for guild-targeted routes.
  • Examples:
  • X-Target-Guilds: 345678901234567890
  • X-Target-Guilds: 345678901234567890,456789012345678901
  • X-Target-Guilds: *
  • X-Target-Guilds: 0

X-Target-Channels #

  • Purpose: restrict actions targeting specific channels.
  • Format: CSV of channel snowflakes.
  • Special values:
  • *: unrestricted.
  • 0: explicit deny-all for channel-targeted routes.
  • Examples:
  • X-Target-Channels: 567890123456789012
  • X-Target-Channels: 567890123456789012,678901234567890123
  • X-Target-Channels: *
  • X-Target-Channels: 0
  • Notes:
  • If this header locks the Discord MCP to exactly one channel, send_message is hidden.
  • In that situation, replying normally is usually the better fit.

X-Current-User #

  • Purpose: tell the Discord MCP which user is already in scope for the current request.
  • Format: one user snowflake.
  • Examples:
  • X-Current-User: 123456789012345678
  • Rules:
  • Many user-scoped tools can use this as the default user when no user_id or user_name is provided.
  • DM-capable message tools can use it as the default DM target.
  • If the Discord MCP cannot resolve this user to a visible Discord account, the request is rejected.

X-Current-Channel #

  • Purpose: tell the Discord MCP which channel is already handling the current reply.
  • Format: one channel snowflake.
  • Examples:
  • X-Current-Channel: 567890123456789012
  • Rules:
  • Many channel-scoped tools can use this as the default channel when no channel_id or channel_name is provided.
  • If send_message targets this same channel, the Discord MCP rejects the call.
  • The error explains that the model should reply normally instead of using a second send tool.
  • If the Discord MCP cannot resolve this channel to a visible Discord channel, the request is rejected.
  • Invalid values are rejected with 400.

X-Current-Guild #

  • Purpose: tell the Discord MCP which guild is already in scope for the current request.
  • Format: one guild snowflake.
  • Examples:
  • X-Current-Guild: 345678901234567890
  • Rules:
  • Many guild-scoped tools can use this as the default guild when no guild_id or guild_name is provided.
  • If the Discord MCP cannot resolve this guild to a visible Discord guild, the request is rejected.
  • Invalid values are rejected with 400.

X-Current-Message #

  • Purpose: give the Discord MCP the current message ID when your client knows the exact message that triggered the request.
  • Format: one message snowflake.
  • Examples:
  • X-Current-Message: 678901234567890123
  • Rules:
  • On its own, this header is only extra context.
  • When X-Current-Guild and X-Current-Channel are also present, the Discord MCP can build a precise message link for DM attribution.
  • The value is treated as contextual metadata only. It can still be useful even if the original message was ephemeral or already gone.
  • Invalid values are rejected with 400.

X-Allowed-Mentions #

  • Purpose: enforce mention rules for message-sending tools.
  • Format: serialized JSON object.
  • Examples:
  • X-Allowed-Mentions: {"parse":[]}
  • X-Allowed-Mentions: {"parse":["users"],"replied_user":false}
  • Rules:
  • The Discord MCP applies this header to message send tools instead of accepting an allowed_mentions payload argument.
  • The value must be a JSON object.
  • Invalid JSON or non-object values are rejected with 400.

X-Allowed-Methods #

  • Purpose: allow-list methods at the Discord MCP preflight stage.
  • Format: CSV of exact method names, normalized to uppercase.
  • Special value:
  • *: unrestricted.
  • Examples:
  • X-Allowed-Methods: GET,POST
  • X-Allowed-Methods: PATCH
  • X-Allowed-Methods: *
  • Rules:
  • No globbing is supported.
  • If set and method is not allowed, the Discord MCP returns 403.
  • Applies to Discord tools and Discord MCP-local tools.
  • Discord MCP-local policy:
    • read tools require GET or POST.
    • write tools require POST.

X-Allowed-Paths #

  • Purpose: allow-list upstream Discord paths.
  • Format: CSV of glob patterns, each starting with /.
  • Examples:
  • X-Allowed-Paths: /guilds/*,/channels/*/messages/*
  • X-Allowed-Paths: /guilds/123456789012345678/*
  • X-Allowed-Paths: /users/@me/guilds
  • Rules:
  • Globbing is supported.
  • This is path-level filtering, not semantic entity filtering.

X-Permission-Bits #

  • Purpose: local Discord MCP pre-filter for tool execution and listing.
  • Format: one decimal integer bitmask.
  • Examples:
  • X-Permission-Bits: 8
  • X-Permission-Bits: 8192
  • X-Permission-Bits: 536870920
  • Rules:
  • Must be a single decimal integer.
  • * is not supported.
  • If omitted, no Discord MCP-side permission prefilter is applied.
  • ADMINISTRATOR (8) bypasses the Discord MCP permission filtering.
  • Discord still enforces real upstream permissions.

X-Privileged-Intents #

  • Purpose: declare which privileged Discord intents are available to the calling bot context.
  • Format: CSV values from:
  • presence
  • server_members
  • message_content
  • *
  • Examples:
  • X-Privileged-Intents: server_members
  • X-Privileged-Intents: presence,message_content
  • X-Privileged-Intents: *
  • Rules:
  • If omitted, the Discord MCP assumes no privileged intent (deny-by-default).
  • The Discord MCP hides and blocks tools that require privileged intents:
    • list_guild_members requires server_members.
    • resolve_id requires server_members only when type=member.
    • fetch_messages requires at least one of message_content or server_members.
  • Blocked execution returns 403 with code privileged_intents_not_authorized.
  • For member-name resolution, if server_members is not present (or *), the Discord MCP falls back from member lookup to user lookup.
  • This fallback only affects ID resolution behavior and does not bypass downstream Discord permission checks.

X-Image-Model #

  • Purpose: override the model used by util_generate_image for one request.
  • Format: non-empty string.
  • Examples:
  • X-Image-Model: image-model-a
  • X-Image-Model: image-model-b
  • Rules:
  • When present, this header takes priority over the configured default model for that request.
  • The selected image provider must still accept that model.
  • If the effective model is invalid for the selected provider, util_generate_image is hidden from tool listings and rejected at execution.
  • Empty values are rejected with 400.

X-Cache-Max-TTL #

  • Purpose: cap acceptable cache age for Discord MCP reads.
  • Format: integer seconds, >= 0.
  • Examples:
  • X-Cache-Max-TTL: 0
  • X-Cache-Max-TTL: 30
  • X-Cache-Max-TTL: 300
  • Rules:
  • 0 bypasses cache for cache-backed reads.

X-Owner-Access #

  • Purpose: explicit owner-mode gate for sensitive controls.
  • Format: boolean (1|true|0|false, case-insensitive).
  • Examples:
  • X-Owner-Access: 1
  • X-Owner-Access: true
  • X-Owner-Access: false
  • Rules:
  • Required by owner-gated tools (mcp_*, except mcp_get_access_context) and operator-only admin tools.
  • Required for non-GET /users/@me* routes.
  • Invalid values are rejected with 400.

X-Privileged-Call #

  • Purpose: explicit operator confirmation for admin-only operations.
  • Format: boolean (1|true|0|false, case-insensitive).
  • Examples:
  • X-Privileged-Call: 1
  • X-Privileged-Call: true
  • X-Privileged-Call: false
  • Rules:
  • Used only for operator-only admin tools.
  • Admin tool list/execute requires:
    • X-Owner-Access truthy.
    • app flagged as privileged by operator configuration.
    • X-Privileged-Call truthy.

X-Debug-Mode #

  • Purpose: return introspection payloads for JSON-RPC success responses.
  • Format: boolean (1|true|0|false, case-insensitive).
  • Examples:
  • X-Debug-Mode: 1
  • X-Debug-Mode: true
  • Rules:
  • When false, _debug is absent.
  • When true, successful JSON-RPC responses include result._debug.
  • If the original result is not an object, the Discord MCP wraps it as: { "data": <original>, "_debug": { ... } }.
  • Notifications are unchanged (204, no response body).

Source IP Header (default: X-Forwarded-For#

  • Purpose: source-IP extraction for invalid-auth abuse counters.
  • Header name: configurable by the service operator.
  • Rules:
  • Used only if trusted proxy CIDRs are configured and requester socket IP is in that trusted range.
  • If trusted CIDRs are empty, header is ignored and remote socket IP is used.
  • The Discord MCP parses the CSV chain from right to left, skipping trusted hops and selecting first non-trusted hop as client IP.

X-Target-* Enforcement Semantics #

The Discord MCP enforces target restrictions by route path params (guild_id, channel_id, user_id) and method:

  • If guild_id is present:
  • guild is always checked.
  • if user_id is also present:
    • GET: only guild is checked.
    • non-GET: guild and user are both checked.
  • Else if channel_id is present:
  • channel is checked.
  • Else if user_id is present:
  • user is checked.

Additional resolved-scope guards:

  • delete_invite resolves invite first and enforces guild/channel targets from resolved payload when restrictive target headers are set.
  • get_webhook / edit_webhook / delete_webhook enforce resolved guild/channel targets from webhook payload when restrictive target headers are set.

Name Resolution Behavior (*_name, resolve_id#

Many tools accept *_name as an alternative to *_id.

  • Precedence: *_id always wins when both are provided.
  • Resolution is case-insensitive and normalized.
  • Supported core entity types: user, guild, channel, role, thread, member.
  • For non-guild/user types, guild_id or guild_name is required.
  • guild_name resolution is checked against X-Target-Guilds.
  • Ambiguous names return explicit candidate lists (*_name_ambiguous).
  • No match returns explicit *_not_found.

Tool Listing Metadata #

tools/list and /v1/tools/list include per-tool metadata:

  • requiredAccess:
  • minimum owner/permission/service requirements.
  • riskLevel, riskTypes:
  • coarse risk profile for models and integrators.
  • annotations.readOnlyHint:
  • present on read-oriented tools only.