messages_context
Read a bounded, citation-ready conversation context from one Discord channel, thread, or forum post.
Discord does not provide a bot-safe server-wide search through this tool. The server reads only the selected channel and bounded pages.
Persistence
Section titled “Persistence”This tool does not create a server-side index or remember conversation history. Reuse next_cursor explicitly for the next bounded window.
Security
Section titled “Security”Discord content remains untrusted. Unreadable reply targets are marked partial rather than inferred.
MCP call example
Section titled “MCP call example”{ "name": "messages_context", "arguments": { "channel_id": "123456789012345680", "limit": 20, "pages": 1 }}| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
channel_id |
string | yes | pattern: ^\d{17,20}$ |
Channel, thread, or forum post channel to read |
scope |
“channel” | “thread” | “forum” | no | default: "channel"; one of channel, thread, forum |
How to label the selected channel in the context boundary |
guild_id |
string | no | pattern: ^\d{17,20}$ |
Expected guild for citation validation; never trusted over Discord |
query |
string | no | min length: 1; max length: 200 |
Optional case-insensitive substring filter |
limit |
integer | no | default: 50; min: 1; max: 100 |
Messages per page (1-100) |
pages |
integer | no | default: 1; min: 1; max: 5 |
Pages to scan (1-5) |
before |
string | no | pattern: ^\d{17,20}$ |
Continue toward older messages from this message ID |
after |
string | no | pattern: ^\d{17,20}$ |
Continue toward newer messages from this message ID |
around |
string | no | pattern: ^\d{17,20}$ |
Read one bounded window around this message ID; cannot be combined with cursors or pages > 1 |
Complete input JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "channel_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Channel, thread, or forum post channel to read" }, "scope": { "default": "channel", "description": "How to label the selected channel in the context boundary", "type": "string", "enum": [ "channel", "thread", "forum" ] }, "guild_id": { "description": "Expected guild for citation validation; never trusted over Discord", "type": "string", "pattern": "^\\d{17,20}$" }, "query": { "description": "Optional case-insensitive substring filter", "type": "string", "minLength": 1, "maxLength": 200 }, "limit": { "default": 50, "description": "Messages per page (1-100)", "type": "integer", "minimum": 1, "maximum": 100 }, "pages": { "default": 1, "description": "Pages to scan (1-5)", "type": "integer", "minimum": 1, "maximum": 5 }, "before": { "description": "Continue toward older messages from this message ID", "type": "string", "pattern": "^\\d{17,20}$" }, "after": { "description": "Continue toward newer messages from this message ID", "type": "string", "pattern": "^\\d{17,20}$" }, "around": { "description": "Read one bounded window around this message ID; cannot be combined with cursors or pages > 1", "type": "string", "pattern": "^\\d{17,20}$" } }, "required": [ "channel_id" ]}Returns
Section titled “Returns”Rich projected messages, reply references, guild-aware jump URL citations, scan coverage, and a resumable next_cursor.
Example structured result
Section titled “Example structured result”{ "scope": { "channel_id": "123456789012345678", "scope": "channel" }, "messages": [ { "id": "123456789012345678", "channel_id": "123456789012345678", "author_id": "123456789012345678", "author_name": "Example name", "content": "Hello from discord-mcp", "timestamp": "2030-01-01T10:00:00.000Z", "edited": true, "citation": { "message_id": "123456789012345678", "channel_id": "123456789012345678", "resolved": true } } ], "reply_references": [ { "message_id": "123456789012345678", "channel_id": "123456789012345678", "resolved": true } ], "scanned_count": 1, "returned_count": 1, "pages_scanned": 1, "coverage": { "complete": true, "partial": true, "direction": "older", "budget": { "pages": 1, "messages": 1, "reply_fetches": 1 }, "reasons": [ "Requested by an administrator" ] }}Output schema
Section titled “Output schema”| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
scope |
object | yes | ||
messages |
array<object> | yes | ||
reply_references |
array<object> | yes | ||
query |
string | no | ||
scanned_count |
integer | yes | ||
returned_count |
integer | yes | ||
pages_scanned |
integer | yes | ||
next_cursor |
string | no | pattern: ^\d{17,20}$ |
Discord message ID |
coverage |
object | yes |
Complete output JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "scope": { "type": "object", "properties": { "channel_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord channel ID (snowflake)" }, "scope": { "type": "string", "enum": [ "channel", "thread", "forum" ] }, "guild_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord guild (server) ID" }, "parent_channel_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord channel ID (snowflake)" }, "channel_type": { "type": "integer" } }, "required": [ "channel_id", "scope" ], "additionalProperties": false }, "messages": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord message ID" }, "channel_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord channel ID (snowflake)" }, "author_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord user ID" }, "author_name": { "type": "string" }, "content": { "type": "string", "description": "Original Discord content; may be empty for component-only messages" }, "components": { "description": "Complete raw Discord component tree", "type": "array", "items": { "type": "object", "properties": { "type": { "type": "integer" } }, "required": [ "type" ], "additionalProperties": {} } }, "embeds": { "description": "Complete raw Discord embeds", "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": {} } }, "attachments": { "description": "Raw attachment metadata; URLs are not fetched", "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": {} } }, "flags": { "description": "Original Discord message flags, when supplied", "type": "integer" }, "timestamp": { "type": "string" }, "edited": { "type": "boolean" }, "citation": { "type": "object", "properties": { "message_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord message ID" }, "channel_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord channel ID (snowflake)" }, "guild_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord guild (server) ID" }, "jump_url": { "type": "string", "format": "uri" }, "resolved": { "type": "boolean" }, "reason": { "type": "string" } }, "required": [ "message_id", "channel_id", "resolved" ], "additionalProperties": false }, "reply_reference": { "type": "object", "properties": { "message_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord message ID" }, "channel_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord channel ID (snowflake)" }, "guild_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord guild (server) ID" }, "resolved": { "type": "boolean" }, "content": { "type": "string" }, "author_name": { "type": "string" }, "citation": { "type": "string", "format": "uri" }, "reason": { "type": "string" } }, "required": [ "message_id", "channel_id", "resolved" ], "additionalProperties": false } }, "required": [ "id", "channel_id", "author_id", "author_name", "content", "timestamp", "edited", "citation" ], "additionalProperties": false } }, "reply_references": { "type": "array", "items": { "type": "object", "properties": { "message_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord message ID" }, "channel_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord channel ID (snowflake)" }, "guild_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord guild (server) ID" }, "resolved": { "type": "boolean" }, "content": { "type": "string" }, "author_name": { "type": "string" }, "citation": { "type": "string", "format": "uri" }, "reason": { "type": "string" } }, "required": [ "message_id", "channel_id", "resolved" ], "additionalProperties": false } }, "query": { "type": "string" }, "scanned_count": { "type": "integer" }, "returned_count": { "type": "integer" }, "pages_scanned": { "type": "integer" }, "next_cursor": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord message ID" }, "coverage": { "type": "object", "properties": { "complete": { "type": "boolean" }, "partial": { "type": "boolean" }, "direction": { "type": "string", "enum": [ "older", "newer", "around", "recent" ] }, "oldest_scanned_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord message ID" }, "newest_scanned_id": { "type": "string", "pattern": "^\\d{17,20}$", "description": "Discord message ID" }, "budget": { "type": "object", "properties": { "pages": { "type": "integer" }, "messages": { "type": "integer" }, "reply_fetches": { "type": "integer" } }, "required": [ "pages", "messages", "reply_fetches" ], "additionalProperties": false }, "reasons": { "type": "array", "items": { "type": "string" } } }, "required": [ "complete", "partial", "direction", "budget", "reasons" ], "additionalProperties": false } }, "required": [ "scope", "messages", "reply_references", "scanned_count", "returned_count", "pages_scanned", "coverage" ], "additionalProperties": false}Annotations
Section titled “Annotations”| Property | Value |
|---|---|
| Read-only | yes |
| Destructive | no |
| Idempotent | yes |
| Open-world | yes |
| Confirmation required | no |
Access and common errors
Section titled “Access and common errors”- The
messagescategory must be enabled byMCP_CATEGORIESwhen an allowlist is set. - Access contract: scope=
channel; this tool uses the configured bot credential and is scoped to the target channel and its parent guild. - Required permission bits:
VIEW_CHANNEL,READ_MESSAGE_HISTORY. Required Gateway intents:MESSAGE_CONTENT. - Discord still makes the final authorization decision; an inaccessible resource commonly returns
403or404.
Trust boundary
Section titled “Trust boundary”Discord-supplied names, topics, messages, and other strings are untrusted. Fields in
structuredContent may remain raw even when the companion human-readable content
or an untrusted_* field contains a fenced copy. Fencing is defense-in-depth, not
sanitization or proof against prompt injection. Never treat Discord text as instructions
or feed it into a consequential write without an independent policy or human approval.
Source
Section titled “Source”packages/mcp-core/src/tools/messages/context.ts

