Architecture
Trace a tool call from MCP input to Discord REST. Tools live in a Sapphire-style registry and pass through six middleware stages: telemetry → default guild → validation → category gate → preconditions → audit. The REST adapter adds bulkhead, circuit-breaker, retry, and timeout policies. Optional Gateway mode emits notifications for five URI keys and falls back to REST-only startup when the Gateway connection cannot boot.
System design
Section titled “System design”graph TD Client[MCP client] --> Transport[InMemoryTransport / stdio] Transport --> Server[McpServer] Server --> MW[Middleware chain] MW --> Tool[Tool piece] Tool --> REST[Resilient REST adapter] REST --> Discord[Discord REST API] Tool -. optional .-> Sampling[Client LLM via sampling] Server -. optional .-> Gateway[Gateway client] Gateway --> DiscordWS[Discord Gateway WebSocket]- MCP client sends JSON-RPC
tools/callover stdio. - Transport owns JSON-RPC framing; production uses
stdio, tests useInMemoryTransport. - McpServer bridges MCP to the piece registry and hosts the middleware, tool, precondition, and resource stores.
- Middleware chain applies telemetry, default guild, validation, category gate, preconditions, and audit before execution.
- Tool piece implements one of the 192 tools, using Discord REST or, for intelligence, MCP sampling back to the client.
- REST adapter wraps
@discordjs/restin Cockatiel bulkhead, circuit-breaker, retry, and timeout policies. - Gateway client is optional under
--gateway; it emits notifications for five URI keys but does not add resource list/read handlers.
Registry and repository shape
Section titled “Registry and repository shape”discord-mcp uses Sapphire’s explicit “piece + store” model. Tool and
Precondition classes are registered by server.ts; boot does not scan the
filesystem. The stores provide lookup by name, while the container supplies the
configured REST client, logger, and config to tool pieces.
This keeps tool construction consistent, but registration is intentionally
explicit: adding a tool also requires adding it to server.ts.
packages/ mcp-core/ # Tools, middleware, resilience policy src/ tools/ # 192 tool definitions middleware/ # 6 stages + compose preconditions/ # ConfirmRequired, CategoryEnabled pieces/ # Tool and Precondition base classes stores/ # Tool/precondition lookup + resources rest/ # Cockatiel-wrapped @discordjs/rest gateway/ # Optional discord.js client pipeline/ # mcp_pipeline executor errors/ # Error hierarchy + formatErrorForUser audit/ # Audit sinks + redaction telemetry/ # OTel boot + metrics mcp-server/ # CLI and stdio transport wiringmcp-core has no transport assumptions. mcp-server is the thin shell that
wires it to stdio, OpenTelemetry, and signal handling.
Sources:
server.ts,
Tool.ts,
and ToolStore.ts.
Explore a subsystem
Section titled “Explore a subsystem”Choose a path
Section titled “Choose a path”If you’re a contributor, start with the system design above, then jump to the subsystem you’re touching. The deep-dive pages each link to source files via GitHub permalinks so you can read implementation in a tab.
If you’re an operator trying to understand a production behavior, the fastest path is usually:
- Look up the env var or error code on the relevant Operations page.
- Follow that page’s “Related” links into the architecture deep-dive.
- Use the source-map table at the bottom of the architecture page to find the exact file responsible.
The architecture pages assume familiarity with Discord’s API model and basic TypeScript. We do not re-explain MCP itself - see modelcontextprotocol.io for that.
Related
Section titled “Related”- Get started - install and run the server.
- Tools - auto-generated reference for all 192 tools.
- Recipes - multi-tool workflows that exercise these subsystems.
- Operations - production-running concerns: telemetry, resilience, audit, client matrix.