Skip to content

drvova/discord-mcp

Repository files navigation

Discord MCP Server

⚠️ Security Notice: This project handles Discord credentials and privileged Discord operations. Treat all tokens and secrets as sensitive.

Discord MCP Server exposes Discord runtime packages through one MCP tool with a unified metadata/execution protocol.

Current Architecture

This repository now uses the Discord runtime vNext protocol:

  • MCP tool: discord_manage
  • HTTP runtime: Hono (@hono/node-server)
  • Read operations (automation.read):
    • discord.meta.packages
    • discord.meta.symbols
    • discord.meta.preflight
    • discord.meta.refresh
  • Write operations (automation.write):
    • discord.exec.invoke
    • discord.exec.batch

Tool Contract

discord_manage uses the contract below:

  • mode: bot or user
  • identityId: identity record (for example default-bot)
  • method: optional override (automation.read or automation.write)
  • operation: one of
    • discord.meta.packages
    • discord.meta.symbols
    • discord.meta.preflight
    • discord.meta.refresh
    • discord.exec.invoke
    • discord.exec.batch
  • params or args

Runtime symbol coverage:

  • class, function, enum, interface, type, and variable are discovered.
  • interface, type, namespace, and variable can be sourced from package declaration files (.d.ts) when missing at runtime.
  • discord.meta.symbols can include an operational matrix per symbol for preflight/execution readiness.
  • Catalog responses include catalogFingerprint, catalogBuiltAt, and isFresh metadata for agent-side cache control.

Branch Model

  • Canonical branch: new-architecture-main
  • Repository default branch: new-architecture-main

Quick Start

Prerequisites

  • Node.js 18+
  • npm
  • Discord bot token

Install

git clone https://github.com/drvova/discord-mcp.git
cd discord-mcp
npm install
npm run build

Run

# stdio mode (default)
npm start

# dev mode
npm run dev

# HTTP/SSE mode
npm run web

Configuration

Create .env:

DISCORD_TOKEN=your_bot_token_here
DISCORD_GUILD_ID=your_guild_id_here

# Optional user-mode token
# DISCORD_USER_TOKEN=your_discord_user_token

# Optional encrypted identity store
# DISCORD_MCP_MASTER_KEY=your_32_byte_key_material
# DISCORD_MCP_IDENTITY_STORE_PATH=./.discord-mcp-identities.enc

# Optional risk policy override
# DISCORD_MCP_BLOCK_HIGH_RISK=true

# Optional audit log file
# DISCORD_MCP_AUDIT_LOG_PATH=./data/discord-mcp-audit.log

# Optional logging
# LOG_LEVEL=INFO
# LOG_STYLE=pretty
# LOG_COLOR=true
# ENABLE_LOGGING=true

# Optional OpenTelemetry
# OTEL_ENABLED=true
# OTEL_SERVICE_NAME=discord-mcp
# OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces
# OTEL_EXPORTER_OTLP_HEADERS=authorization=Bearer token
# OTEL_PROMETHEUS_PORT=9464
# OTEL_PROMETHEUS_ENDPOINT=/metrics

# Optional OAuth (HTTP mode)
# DISCORD_CLIENT_ID=...
# DISCORD_CLIENT_SECRET=...
# DISCORD_OAUTH_REDIRECT_URI=http://localhost:1455/oauth/discord/callback

HTTP Endpoints

When MCP_HTTP_PORT (or PORT) is set:

  • GET /sse
  • POST /message
  • GET /health
  • GET /oauth/discord/start
  • GET /oauth/discord/callback

Logging

Server logs use a shared Pino logger with compact one-line output (no ISO timestamp clutter in pretty mode).

  • LOG_LEVEL controls verbosity: ERROR, WARN, INFO, DEBUG (default INFO)
  • LOG_STYLE controls output shape: pretty or json (when unset, auto mode uses pretty for interactive terminals and dev scripts, otherwise json)
  • LOG_COLOR enables/disables ANSI colors (default true)
  • ENABLE_LOGGING disables all logs when set to false (default true)

For stdio MCP mode, logs are written to stderr so protocol output on stdout remains clean.

OpenTelemetry

  • Traces are exported using OTLP HTTP (OTEL_EXPORTER_OTLP_TRACES_ENDPOINT).
  • Metrics are exposed via Prometheus exporter at http://localhost:${OTEL_PROMETHEUS_PORT:-9464}${OTEL_PROMETHEUS_ENDPOINT:-/metrics}.
  • Service metadata is controlled by OTEL_SERVICE_NAME.

Typed HTTP Client (hc)

You can use the generated typed client from Hono route types:

import { createHttpClient } from "./src/http-client.js";

const client = createHttpClient("http://localhost:1455");
const healthResponse = await client.health.$get();
const health = await healthResponse.json();

const rpcResponse = await client.index.$post({
  json: {
    id: 1,
    method: "tools/list"
  }
});
const rpc = await rpcResponse.json();

The MCP JSON-RPC contract on POST / is unchanged (initialize, tools/list, tools/call).

Usage Examples

1) List Runtime Packages

{
  "mode": "bot",
  "identityId": "default-bot",
  "method": "automation.read",
  "operation": "discord.meta.packages",
  "params": {
    "packages": ["discordjs", "discordjs_voice"]
  }
}

2) Discover Symbols + Operational Matrix

{
  "mode": "bot",
  "identityId": "default-bot",
  "method": "automation.read",
  "operation": "discord.meta.symbols",
  "params": {
    "packageAlias": "discordjs",
    "kinds": ["class", "function", "enum", "interface", "type", "variable"],
    "query": "TextChannel#send",
    "includeAliases": true,
    "includeKindCounts": true,
    "includeOperationalMatrix": true
  }
}

3) Preflight Before Execution

{
  "mode": "bot",
  "identityId": "default-bot",
  "method": "automation.read",
  "operation": "discord.meta.preflight",
  "params": {
    "packageAlias": "discordjs",
    "symbol": "TextChannel#send",
    "kind": "function",
    "target": "channel",
    "context": {
      "channelId": "123456789012345678"
    },
    "policyMode": "strict",
    "strictContextCheck": true,
    "strictArgCheck": false
  }
}

4) Refresh Package + Symbol Catalog

{
  "mode": "bot",
  "identityId": "default-bot",
  "method": "automation.read",
  "operation": "discord.meta.refresh",
  "params": {
    "force": true,
    "includeDiff": true
  }
}

5) Execute Invocation (Safe by Default)

{
  "mode": "bot",
  "identityId": "default-bot",
  "method": "automation.write",
  "operation": "discord.exec.invoke",
  "params": {
    "packageAlias": "discordjs",
    "symbol": "TextChannel#send",
    "kind": "function",
    "args": ["hello from invoke"],
    "target": "channel",
    "context": {
      "channelId": "123456789012345678"
    },
    "dryRun": false,
    "requirePreflightPass": true,
    "allowWrite": true
  }
}

6) Batch Invocation

{
  "mode": "bot",
  "identityId": "default-bot",
  "method": "automation.write",
  "operation": "discord.exec.batch",
  "params": {
    "mode": "best_effort",
    "haltOnPolicyBlock": false,
    "maxParallelism": 4,
    "dryRun": true,
    "items": [
      {
        "packageAlias": "discordjs",
        "symbol": "TextChannel#send",
        "kind": "function",
        "target": "channel",
        "context": {
          "channelId": "123456789012345678"
        },
        "args": ["hello from batch"]
      }
    ]
  }
}

Legacy Dynamic Compatibility

Legacy operation strings are not supported. Use only vNext operations:

  • discord.meta.packages
  • discord.meta.symbols
  • discord.meta.preflight
  • discord.meta.refresh
  • discord.exec.invoke
  • discord.exec.batch

Notes on Operation Counts

If you expect thousands of discovered symbols, this is by design:

  • The MCP registry exposes a small, fixed operation surface.
  • Package discovery is exposed through discord.meta.packages.
  • Symbol discovery is exposed through discord.meta.symbols.
  • Execution preflight is exposed through discord.meta.preflight.
  • Catalog invalidation/refresh is exposed through discord.meta.refresh.
  • Single and batch execution are exposed through discord.exec.invoke and discord.exec.batch.
  • Runtime discovery includes enum exports (for example ChannelType, ActivityType).
  • Startup logs print loaded package aliases and versions.

Security Guidance

  • Keep tokens private and rotate regularly.
  • Use minimum Discord permissions required.
  • Prefer dryRun for risky operations.
  • Use allowWrite only when intended.
  • Enable audit logging in production.

Scripts

  • npm run build - compile TypeScript
  • npm run dev (or bun run dev) - build once, then run tsc -w + node --watch with forced pretty logs
  • npm start - run compiled stdio server
  • npm run web - run compiled Hono HTTP/SSE server on port 1455

Codex + GH CLI Notes

Use gh to track upstream Codex MCP interface updates and keep this server aligned:

  • gh api repos/openai/codex
  • gh api repos/openai/codex/contents/codex-rs/docs/codex_mcp_interface.md
  • gh api "search/code?q=repo:openai/codex+mcp_tool_call.rs"

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors