Skip to main content
Glama
kongyo2

Discord Webhook MCP

Send Discord Message

discord_send_message

Send text messages or rich embeds to Discord channels via webhook. Supports threads, TTS, and custom usernames.

Instructions

Discordチャンネルにメッセージを送信します。

content、embedsのいずれか最低1つが必要です。 環境変数DISCORD_WEBHOOK_URLに設定されたWebhookを使用します。

⚠️ レート制限: 30メッセージ/分/チャンネル

Args:

  • content (string, optional): メッセージ内容(1-2000文字)

  • username (string, optional): Webhookのユーザー名を上書き(最大80文字)

  • avatar_url (string, optional): Webhookのアバター画像をURLで指定

  • tts (boolean, optional): テキスト読み上げ(TTS)メッセージとして送信(デフォルト: false)

  • embeds (array, optional): Embedの配列(最大10個、合計6000文字以内)

  • allowed_mentions (object, optional): 許可されたメンション設定

  • thread_id (string, optional): 送信先スレッドID(指定したスレッドに送信、スレッドは自動アーカイブ解除)

  • thread_name (string, optional): 作成するスレッド名(フォーラム/メディアチャンネルのみで新しいスレッドを作成、最大100文字)

Returns: { "success": boolean, // 送信が成功したか "message_id": string, // 送信されたメッセージのID "channel_id": string, // 送信先チャンネルID "timestamp": string // 送信日時 (ISO 8601形式) }

Examples:

  • シンプルなテキスト送信: { "content": "Hello, Discord!" }

  • Embed付き送信: { "embeds": [{ "title": "タイトル", "description": "説明", "color": 0x00FF00 }] }

  • スレッドに送信: { "content": "スレッドメッセージ", "thread_id": "123456789" }

Error Handling:

  • "Validation error: content/embeds - content、embeds のうち最低1つを指定してください"

  • "Discord Webhook error: 400 Bad Request - Invalid webhook URL"

  • "Discord Webhook error: 404 Not Found - Webhook not found"

  • "Discord Webhook error: レート制限に達しました" - 429エラー時、retry-after秒後に再試行

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
contentNoメッセージ内容 (最大2000文字)
usernameNoWebhookのユーザー名を上書き
avatar_urlNoWebhookのアバターURLを上書き
ttsNoテキスト読み上げ (TTS)
embedsNoEmbedの配列 (最大10個)
allowed_mentionsNo許可されたメンション設定
thread_idNo送信先スレッドID (自動アーカイブ解除)
thread_nameNo作成するスレッド名 (フォーラム/メディアチャンネルのみ)

Implementation Reference

  • The handler function for discord_send_message tool. Validates that content or embeds is present, builds the payload, calls sendToDiscord() with wait=true and optional thread_id, and returns the response with message_id, channel_id, and timestamp.
    server.registerTool(
      "discord_send_message",
      {
        title: "Send Discord Message",
        description:
          `Discordチャンネルにメッセージを送信します。
    
    content、embedsのいずれか最低1つが必要です。
    環境変数DISCORD_WEBHOOK_URLに設定されたWebhookを使用します。
    
    ⚠️ レート制限: 30メッセージ/分/チャンネル
    
    Args:
      - content (string, optional): メッセージ内容(1-2000文字)
      - username (string, optional): Webhookのユーザー名を上書き(最大80文字)
      - avatar_url (string, optional): Webhookのアバター画像をURLで指定
      - tts (boolean, optional): テキスト読み上げ(TTS)メッセージとして送信(デフォルト: false)
      - embeds (array, optional): Embedの配列(最大10個、合計6000文字以内)
      - allowed_mentions (object, optional): 許可されたメンション設定
      - thread_id (string, optional): 送信先スレッドID(指定したスレッドに送信、スレッドは自動アーカイブ解除)
      - thread_name (string, optional): 作成するスレッド名(フォーラム/メディアチャンネルのみで新しいスレッドを作成、最大100文字)
    
    Returns:
      {
        "success": boolean,        // 送信が成功したか
        "message_id": string,      // 送信されたメッセージのID
        "channel_id": string,      // 送信先チャンネルID
        "timestamp": string        // 送信日時 (ISO 8601形式)
      }
    
    Examples:
      - シンプルなテキスト送信: { "content": "Hello, Discord!" }
      - Embed付き送信: { "embeds": [{ "title": "タイトル", "description": "説明", "color": 0x00FF00 }] }
      - スレッドに送信: { "content": "スレッドメッセージ", "thread_id": "123456789" }
    
    Error Handling:
      - "Validation error: content/embeds - content、embeds のうち最低1つを指定してください"
      - "Discord Webhook error: 400 Bad Request - Invalid webhook URL"
      - "Discord Webhook error: 404 Not Found - Webhook not found"
      - "Discord Webhook error: レート制限に達しました" - 429エラー時、retry-after秒後に再試行`,
        inputSchema: SendMessageSchema,
        annotations: {
          readOnlyHint: false,
          destructiveHint: false,
          idempotentHint: false,
          openWorldHint: true,
        },
      },
      async (params: SendMessageInput) => {
        // content, embeds のうち1つが必要
        const hasContent = params.content && params.content.length > 0;
        const hasEmbeds = params.embeds && params.embeds.length > 0;
    
        if (!hasContent && !hasEmbeds) {
          return {
            content: [
              {
                type: "text",
                text: "エラー: content、embeds のうち最低1つを指定してください",
              },
            ],
            isError: true,
          };
        }
    
        // payloadの構築
        const payload: Record<string, unknown> = {};
        if (hasContent) payload.content = params.content;
        if (params.username) payload.username = params.username;
        if (params.avatar_url) payload.avatar_url = params.avatar_url;
        if (params.tts) payload.tts = params.tts;
        if (hasEmbeds) payload.embeds = params.embeds;
        if (params.allowed_mentions) payload.allowed_mentions = params.allowed_mentions;
        if (params.thread_name) payload.thread_name = params.thread_name;
    
        // メッセージ送信(wait=trueでメッセージIDを取得)
        const { result, error } = await sendToDiscord(
          payload,
          true,
          params.thread_id
        );
    
        if (error) {
          return {
            content: [
              {
                type: "text",
                text: `エラー: ${formatError(error)}`,
              },
            ],
            isError: true,
          };
        }
    
        const messageInfo = result;
        return {
          content: [
            {
              type: "text",
              text: messageInfo
                ? `メッセージを送信しました\nID: ${messageInfo.id}\nチャンネル: ${messageInfo.channel_id}`
                : "メッセージを送信しました",
            },
          ],
          structuredContent: {
            success: true,
            message_id: messageInfo?.id,
            channel_id: messageInfo?.channel_id,
            timestamp: messageInfo?.timestamp,
          },
        };
      }
  • Zod input validation schema for discord_send_message. Defines all allowed fields: content, username, avatar_url, tts, embeds, allowed_mentions, thread_id, thread_name.
    export const SendMessageSchema = z.object({
      content: z
        .string()
        .min(1)
        .max(MAX_CONTENT_LENGTH)
        .optional()
        .describe(`メッセージ内容 (最大${MAX_CONTENT_LENGTH}文字)`),
      username: z.string().max(80).optional().describe("Webhookのユーザー名を上書き"),
      avatar_url: z.string().url().optional().describe("WebhookのアバターURLを上書き"),
      tts: z.boolean().optional().default(false).describe("テキスト読み上げ (TTS)"),
      embeds: z.array(EmbedSchema).max(MAX_EMBEDS).optional().describe(`Embedの配列 (最大${MAX_EMBEDS}個)`),
      allowed_mentions: AllowedMentionsSchema.optional().describe("許可されたメンション設定"),
      thread_id: z.string().optional().describe("送信先スレッドID (自動アーカイブ解除)"),
      thread_name: z.string().max(100).optional().describe("作成するスレッド名 (フォーラム/メディアチャンネルのみ)"),
    }).strict();
  • src/index.ts:42-89 (registration)
    Registration of discord_send_message tool via server.registerTool with tool name, metadata (title, description, inputSchema, annotations), and the handler callback.
    server.registerTool(
      "discord_send_message",
      {
        title: "Send Discord Message",
        description:
          `Discordチャンネルにメッセージを送信します。
    
    content、embedsのいずれか最低1つが必要です。
    環境変数DISCORD_WEBHOOK_URLに設定されたWebhookを使用します。
    
    ⚠️ レート制限: 30メッセージ/分/チャンネル
    
    Args:
      - content (string, optional): メッセージ内容(1-2000文字)
      - username (string, optional): Webhookのユーザー名を上書き(最大80文字)
      - avatar_url (string, optional): Webhookのアバター画像をURLで指定
      - tts (boolean, optional): テキスト読み上げ(TTS)メッセージとして送信(デフォルト: false)
      - embeds (array, optional): Embedの配列(最大10個、合計6000文字以内)
      - allowed_mentions (object, optional): 許可されたメンション設定
      - thread_id (string, optional): 送信先スレッドID(指定したスレッドに送信、スレッドは自動アーカイブ解除)
      - thread_name (string, optional): 作成するスレッド名(フォーラム/メディアチャンネルのみで新しいスレッドを作成、最大100文字)
    
    Returns:
      {
        "success": boolean,        // 送信が成功したか
        "message_id": string,      // 送信されたメッセージのID
        "channel_id": string,      // 送信先チャンネルID
        "timestamp": string        // 送信日時 (ISO 8601形式)
      }
    
    Examples:
      - シンプルなテキスト送信: { "content": "Hello, Discord!" }
      - Embed付き送信: { "embeds": [{ "title": "タイトル", "description": "説明", "color": 0x00FF00 }] }
      - スレッドに送信: { "content": "スレッドメッセージ", "thread_id": "123456789" }
    
    Error Handling:
      - "Validation error: content/embeds - content、embeds のうち最低1つを指定してください"
      - "Discord Webhook error: 400 Bad Request - Invalid webhook URL"
      - "Discord Webhook error: 404 Not Found - Webhook not found"
      - "Discord Webhook error: レート制限に達しました" - 429エラー時、retry-after秒後に再試行`,
        inputSchema: SendMessageSchema,
        annotations: {
          readOnlyHint: false,
          destructiveHint: false,
          idempotentHint: false,
          openWorldHint: true,
        },
      },
  • Helper function sendToDiscord that sends the payload to the Discord webhook URL via POST request. Handles wait parameter and thread_id query parameter.
    export async function sendToDiscord(
      payload: {
        content?: string;
        username?: string;
        avatar_url?: string;
        tts?: boolean;
        embeds?: Embed[];
        allowed_mentions?: AllowedMentions;
        thread_name?: string;
      },
      wait: boolean = true,
      threadId?: string
    ): Promise<{ result: DiscordMessageResponse | null; error?: DiscordWebhookError }> {
      const url = new URL(WEBHOOK_URL!);
      if (wait) url.searchParams.set("wait", "true");
      if (threadId) url.searchParams.set("thread_id", threadId);
    
      try {
        const result = await makeRequest<DiscordMessageResponse | null>(
          url.toString(),
          "POST",
          payload
        );
        return { result };
      } catch (error) {
        return { result: null, error: convertError(error) };
      }
    }
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses key behaviors: uses a configured webhook, rate limit of 30 messages/minute/channel, triggers thread auto-archive revoke when thread_id is provided, and thread creation only on forum/media channels. Error handling examples clarify expected responses. Annotations (readOnlyHint=false, etc.) are consistent and the description adds substantial behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-organized with sections for summary, requirements, rate limits, arguments, return value, examples, and error handling. It is concise yet comprehensive, with no superfluous content. The most critical information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (8 parameters, nested embeds, no output schema), the description covers all necessary aspects: parameter constraints, return object structure, multiple examples, and error handling. It provides enough detail for an agent to use the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds meaningful context beyond schema, such as the requirement for at least one of content/embeds, thread_id's auto-archive revoke effect, and thread_name's channel type restriction. It also explains the allowed_mentions structure and embed limits (10 max, 6000 chars total).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states 'Discordチャンネルにメッセージを送信します' (send a message to a Discord channel), clearly defining the verb and resource. It distinguishes from sibling tools discord_delete_message and discord_edit_message.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description specifies that either content or embeds is required, uses an environment variable for the webhook URL, and notes rate limits. It provides error handling guidance but does not explicitly contrast with sibling tools; however, the context makes the usage clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kongyo2/discord-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server