Security Model
Security Goals #
- Prevent cross-tenant token misuse
- Restrict upstream Discord scope per request
- Reduce abuse impact from invalid tokens and hostile traffic
- Keep policy decisions explicit and observable
Authentication and Identity Anchoring #
Authorization: Bot <token>is required on protected API routes.APP_IDis extracted from the token's first base64url segment.- Signature validation is not required by design, so identity is anchored with
Discord verification (
GET /applications/@me) plus token hash checks.
Header-Based Policy Controls #
Request-time controls:
X-Allowed-MethodsX-Allowed-PathsX-Target-GuildsX-Target-ChannelsX-Target-UsersX-Permission-BitsX-Privileged-IntentsX-Allowed-MentionsX-Current-UserX-Current-GuildX-Current-ChannelX-Current-MessageX-Image-ModelX-Owner-AccessX-Privileged-Call
Detailed formats and examples are documented in headers.md.
Important X-Target-* notes:
- accepted values are CSV snowflakes,
*, or0 0is a valid deny-all sentinel (never matches Discord snowflakes)- for defense in depth, combine target restrictions with narrow
X-Allowed-Paths/X-Allowed-Methods X-Target-Users: 0can hide DM-only tools entirely- explicit
X-Target-Usersvalues can still narrow DM-oriented tools to a fixed user allowlist - if
X-Privileged-Intentsomitsserver_members, member-name resolution falls back to user-name resolution (ID-based targeting still enforced)
X-Allowed-Methods also applies to Discord MCP-local tools:
- read Discord MCP tools:
GETorPOST - write Discord MCP tools:
POST
X-Allowed-Mentions gives the integrator final control over how outgoing
message mentions are handled.
X-Current-User lets the Discord MCP reuse the current user as the default
user scope for user-targeted tools and DM-capable message flows.
X-Current-Guild lets the Discord MCP reuse the current guild as the default
guild scope for many guild-scoped tools.
X-Current-Channel helps stop redundant message-sending flows when the model is
already replying in the right place, and it can also act as the default channel
scope for many channel-scoped tools.
X-Current-Message gives the Discord MCP an exact message anchor. When guild
and channel context are also present, the Discord MCP can use it to build a
more precise DM attribution link. It remains contextual metadata even if the
message was ephemeral or has already been deleted.
App-level defaults are applied when request headers are omitted:
default_allowed_methodsdefault_allowed_pathsdefault_target_usersdefault_target_guildsdefault_target_channelsdefault_permission_bitsdefault_cache_max_ttl
These defaults are managed by the service operator.
Owner and Privileged Paths #
mcp_*tools requireX-Owner-Access.- Operator-only administrative tools require explicit owner/privileged headers and privileged app configuration.
This prevents accidental exposure of high-impact administrative tools.
Abuse Controls #
Abuse protection behavior:
- repeated invalid tokens from one IP hash increase counter
- IP can be blocked when threshold is reached
- token markers and counters expire automatically (TTL-driven)
Fail-Closed Behavior #
- if the backing store is unavailable, the Discord MCP returns an error and blocks processing
- invalid headers are rejected early
- policy mismatch returns
403before Discord call - oversized API payloads are blocked before request handling
For routes where scope is not directly visible in path IDs, the Discord MCP uses resolved-scope safeguards:
delete_invitecan resolve invite metadata first and enforceX-Target-Guilds/X-Target-Channelson the resolved payloadedit_webhook/delete_webhookcan resolve webhook metadata first and enforce target checks before mutationget_webhookenforces target checks from the returned payload when target headers are restrictive- extra lookups are skipped when target headers are absent or unrestricted
Trusted Proxy Handling #
Source IP extraction uses an operator-configured forwarded-IP header
(default: X-Forwarded-For).
That header is used only when source proxy IP is inside configured
trusted_proxy_cidrs.
If trusted_proxy_cidrs is empty, the Discord MCP ignores forwarded headers and
uses the remote socket address.
If not trusted, remote socket address is used instead.
Operator Checklist #
- Keep
X-Allowed-Pathsnarrow. - Use
X-Target-*for all user-influenced workflows. - Use minimal
X-Permission-Bits. - Use
X-Allowed-Mentionswhen mention scope matters. - Use
X-Current-User,X-Current-Guild, andX-Current-Channelwhen your client already knows the active Discord context. - Avoid exposing owner or privileged headers to untrusted callers.
- Monitor repeated
403and token verification failures. - Rotate compromised bot tokens immediately.