@kongyo2/discord-webhook-mcp 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +12 -0
- package/dist/constants.js.map +1 -0
- package/dist/discord-api.d.ts +32 -0
- package/dist/discord-api.d.ts.map +1 -0
- package/dist/discord-api.js +126 -0
- package/dist/discord-api.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +293 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas.d.ts +567 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +84 -0
- package/dist/schemas.js.map +1 -0
- package/dist/types.d.ts +79 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 kongyo2
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 定数定義
|
|
3
|
+
*/
|
|
4
|
+
export declare const CHARACTER_LIMIT = 25000;
|
|
5
|
+
export declare const MAX_CONTENT_LENGTH = 2000;
|
|
6
|
+
export declare const MAX_EMBEDS = 10;
|
|
7
|
+
export declare const MAX_FIELDS = 25;
|
|
8
|
+
export declare const MAX_EMBED_TOTAL_CHARS = 6000;
|
|
9
|
+
export declare const RATE_LIMIT_PER_MINUTE = 30;
|
|
10
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,eAAe,QAAQ,CAAC;AAErC,eAAO,MAAM,kBAAkB,OAAO,CAAC;AACvC,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,UAAU,KAAK,CAAC;AAG7B,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAG1C,eAAO,MAAM,qBAAqB,KAAK,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 定数定義
|
|
3
|
+
*/
|
|
4
|
+
export const CHARACTER_LIMIT = 25000;
|
|
5
|
+
export const MAX_CONTENT_LENGTH = 2000;
|
|
6
|
+
export const MAX_EMBEDS = 10;
|
|
7
|
+
export const MAX_FIELDS = 25;
|
|
8
|
+
// Discord API制限: すべてのEmbed合計で6000文字
|
|
9
|
+
export const MAX_EMBED_TOTAL_CHARS = 6000;
|
|
10
|
+
// レート制限: 30メッセージ/分/チャンネル
|
|
11
|
+
export const RATE_LIMIT_PER_MINUTE = 30;
|
|
12
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC;AAErC,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AACvC,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAC7B,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAE7B,oCAAoC;AACpC,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C,yBAAyB;AACzB,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discord Webhook API クライアント
|
|
3
|
+
*/
|
|
4
|
+
import type { DiscordMessageResponse, DiscordWebhookError, Embed, AllowedMentions } from "./types.js";
|
|
5
|
+
export declare function isWebhookError(error: DiscordWebhookError): error is Extract<DiscordWebhookError, {
|
|
6
|
+
type: "webhook_error";
|
|
7
|
+
}>;
|
|
8
|
+
export declare function formatError(error: DiscordWebhookError): string;
|
|
9
|
+
export declare function sendToDiscord(payload: {
|
|
10
|
+
content?: string;
|
|
11
|
+
username?: string;
|
|
12
|
+
avatar_url?: string;
|
|
13
|
+
tts?: boolean;
|
|
14
|
+
embeds?: Embed[];
|
|
15
|
+
allowed_mentions?: AllowedMentions;
|
|
16
|
+
thread_name?: string;
|
|
17
|
+
}, wait?: boolean, threadId?: string): Promise<{
|
|
18
|
+
result: DiscordMessageResponse | null;
|
|
19
|
+
error?: DiscordWebhookError;
|
|
20
|
+
}>;
|
|
21
|
+
export declare function editDiscordMessage(messageId: string, payload: {
|
|
22
|
+
content?: string;
|
|
23
|
+
embeds?: Embed[];
|
|
24
|
+
allowed_mentions?: AllowedMentions;
|
|
25
|
+
}): Promise<{
|
|
26
|
+
result: DiscordMessageResponse | null;
|
|
27
|
+
error?: DiscordWebhookError;
|
|
28
|
+
}>;
|
|
29
|
+
export declare function deleteDiscordMessage(messageId: string): Promise<{
|
|
30
|
+
error?: DiscordWebhookError;
|
|
31
|
+
}>;
|
|
32
|
+
//# sourceMappingURL=discord-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord-api.d.ts","sourceRoot":"","sources":["../src/discord-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,KAAK,EACL,eAAe,EAChB,MAAM,YAAY,CAAC;AAYpB,wBAAgB,cAAc,CAC5B,KAAK,EAAE,mBAAmB,GACzB,KAAK,IAAI,OAAO,CAAC,mBAAmB,EAAE;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,CAAC,CAElE;AAGD,wBAAgB,WAAW,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAe9D;AAgFD,wBAAsB,aAAa,CACjC,OAAO,EAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,gBAAgB,CAAC,EAAE,eAAe,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,EACD,IAAI,GAAE,OAAc,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAejF;AAGD,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB,gBAAgB,CAAC,EAAE,eAAe,CAAC;CACpC,GACA,OAAO,CAAC;IAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,mBAAmB,CAAA;CAAE,CAAC,CASjF;AAGD,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,KAAK,CAAC,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAS1C"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discord Webhook API クライアント
|
|
3
|
+
*/
|
|
4
|
+
// 環境変数からWebhook URLを取得
|
|
5
|
+
const WEBHOOK_URL = process.env.DISCORD_WEBHOOK_URL;
|
|
6
|
+
if (!WEBHOOK_URL) {
|
|
7
|
+
process.stderr.write("DISCORD_WEBHOOK_URL environment variable is not set\n");
|
|
8
|
+
process.stderr.write("Please set DISCORD_WEBHOOK_URL before running this server\n");
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
// 型ガード関数
|
|
12
|
+
export function isWebhookError(error) {
|
|
13
|
+
return error.type === "webhook_error";
|
|
14
|
+
}
|
|
15
|
+
// エラーメッセージを整形
|
|
16
|
+
export function formatError(error) {
|
|
17
|
+
switch (error.type) {
|
|
18
|
+
case "webhook_error":
|
|
19
|
+
if (error.status === 429) {
|
|
20
|
+
const retryMsg = error.retryAfter
|
|
21
|
+
? `\n${error.retryAfter}秒後に再試行してください。`
|
|
22
|
+
: "\nしばらく待ってから再試行してください。";
|
|
23
|
+
return `Discord Webhook error: レート制限に達しました (30メッセージ/分/チャンネル)${retryMsg}`;
|
|
24
|
+
}
|
|
25
|
+
return `Discord Webhook error: ${error.status} ${error.statusText}\n${error.body}`;
|
|
26
|
+
case "validation_error":
|
|
27
|
+
return `Validation error: ${error.field} - ${error.message}`;
|
|
28
|
+
case "unknown_error":
|
|
29
|
+
return `Unknown error: ${error.message}`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// APIリクエスト用のヘルパー関数
|
|
33
|
+
async function makeRequest(url, method, body) {
|
|
34
|
+
const options = {
|
|
35
|
+
method,
|
|
36
|
+
headers: { "Content-Type": "application/json" },
|
|
37
|
+
};
|
|
38
|
+
if (body) {
|
|
39
|
+
options.body = JSON.stringify(body);
|
|
40
|
+
}
|
|
41
|
+
const response = await fetch(url, options);
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
const errorText = await response.text();
|
|
44
|
+
const errorInfo = {
|
|
45
|
+
status: response.status,
|
|
46
|
+
statusText: response.statusText,
|
|
47
|
+
body: errorText,
|
|
48
|
+
};
|
|
49
|
+
// レート制限の場合、retry-afterヘッダーを取得
|
|
50
|
+
if (response.status === 429) {
|
|
51
|
+
const retryAfter = response.headers.get("retry-after");
|
|
52
|
+
if (retryAfter) {
|
|
53
|
+
errorInfo.retryAfter = parseInt(retryAfter, 10);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
throw new Error(JSON.stringify(errorInfo));
|
|
57
|
+
}
|
|
58
|
+
// DELETE の場合はレスポンスボディがない場合がある
|
|
59
|
+
if (method === "DELETE") {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
return response.json();
|
|
63
|
+
}
|
|
64
|
+
// エラーを変換
|
|
65
|
+
function convertError(error) {
|
|
66
|
+
if (error instanceof Error && error.message.startsWith("{")) {
|
|
67
|
+
try {
|
|
68
|
+
const parsed = JSON.parse(error.message);
|
|
69
|
+
return {
|
|
70
|
+
type: "webhook_error",
|
|
71
|
+
status: parsed.status,
|
|
72
|
+
statusText: parsed.statusText,
|
|
73
|
+
body: parsed.body,
|
|
74
|
+
retryAfter: parsed.retryAfter,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return {
|
|
79
|
+
type: "unknown_error",
|
|
80
|
+
message: error.message,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
type: "unknown_error",
|
|
86
|
+
message: error instanceof Error ? error.message : String(error),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
// メッセージを送信
|
|
90
|
+
export async function sendToDiscord(payload, wait = true, threadId) {
|
|
91
|
+
const url = new URL(WEBHOOK_URL);
|
|
92
|
+
if (wait)
|
|
93
|
+
url.searchParams.set("wait", "true");
|
|
94
|
+
if (threadId)
|
|
95
|
+
url.searchParams.set("thread_id", threadId);
|
|
96
|
+
try {
|
|
97
|
+
const result = await makeRequest(url.toString(), "POST", payload);
|
|
98
|
+
return { result };
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
return { result: null, error: convertError(error) };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// メッセージを編集
|
|
105
|
+
export async function editDiscordMessage(messageId, payload) {
|
|
106
|
+
const url = new URL(`${WEBHOOK_URL}/messages/${messageId}`);
|
|
107
|
+
try {
|
|
108
|
+
const result = await makeRequest(url.toString(), "PATCH", payload);
|
|
109
|
+
return { result };
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
return { result: null, error: convertError(error) };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// メッセージを削除
|
|
116
|
+
export async function deleteDiscordMessage(messageId) {
|
|
117
|
+
const url = new URL(`${WEBHOOK_URL}/messages/${messageId}`);
|
|
118
|
+
try {
|
|
119
|
+
await makeRequest(url.toString(), "DELETE");
|
|
120
|
+
return {};
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
return { error: convertError(error) };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=discord-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord-api.js","sourceRoot":"","sources":["../src/discord-api.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Discord Webhook MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Discord Webhook を使用してメッセージの送信、編集、削除を行うMCPサーバーです。
|
|
6
|
+
*
|
|
7
|
+
* 環境変数:
|
|
8
|
+
* - DISCORD_WEBHOOK_URL: Discord Webhook URL (必須)
|
|
9
|
+
*
|
|
10
|
+
* 使用例:
|
|
11
|
+
* - メッセージ送信: discord_send_message
|
|
12
|
+
* - メッセージ編集: discord_edit_message
|
|
13
|
+
* - メッセージ削除: discord_delete_message
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Discord Webhook MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Discord Webhook を使用してメッセージの送信、編集、削除を行うMCPサーバーです。
|
|
6
|
+
*
|
|
7
|
+
* 環境変数:
|
|
8
|
+
* - DISCORD_WEBHOOK_URL: Discord Webhook URL (必須)
|
|
9
|
+
*
|
|
10
|
+
* 使用例:
|
|
11
|
+
* - メッセージ送信: discord_send_message
|
|
12
|
+
* - メッセージ編集: discord_edit_message
|
|
13
|
+
* - メッセージ削除: discord_delete_message
|
|
14
|
+
*/
|
|
15
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
16
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
17
|
+
import { SendMessageSchema, EditMessageSchema, DeleteMessageSchema, } from "./schemas.js";
|
|
18
|
+
import { sendToDiscord, editDiscordMessage, deleteDiscordMessage, formatError, } from "./discord-api.js";
|
|
19
|
+
// MCPサーバーインスタンスを作成
|
|
20
|
+
const server = new McpServer({
|
|
21
|
+
name: "discord-webhook-mcp-server",
|
|
22
|
+
version: "1.0.0",
|
|
23
|
+
});
|
|
24
|
+
// ============ ツール登録 ============
|
|
25
|
+
// メッセージ送信ツール
|
|
26
|
+
server.registerTool("discord_send_message", {
|
|
27
|
+
title: "Send Discord Message",
|
|
28
|
+
description: `Discordチャンネルにメッセージを送信します。
|
|
29
|
+
|
|
30
|
+
content、embedsのいずれか最低1つが必要です。
|
|
31
|
+
環境変数DISCORD_WEBHOOK_URLに設定されたWebhookを使用します。
|
|
32
|
+
|
|
33
|
+
⚠️ レート制限: 30メッセージ/分/チャンネル
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
- content (string, optional): メッセージ内容(1-2000文字)
|
|
37
|
+
- username (string, optional): Webhookのユーザー名を上書き(最大80文字)
|
|
38
|
+
- avatar_url (string, optional): Webhookのアバター画像をURLで指定
|
|
39
|
+
- tts (boolean, optional): テキスト読み上げ(TTS)メッセージとして送信(デフォルト: false)
|
|
40
|
+
- embeds (array, optional): Embedの配列(最大10個、合計6000文字以内)
|
|
41
|
+
- allowed_mentions (object, optional): 許可されたメンション設定
|
|
42
|
+
- thread_id (string, optional): 送信先スレッドID(指定したスレッドに送信、スレッドは自動アーカイブ解除)
|
|
43
|
+
- thread_name (string, optional): 作成するスレッド名(フォーラム/メディアチャンネルのみで新しいスレッドを作成、最大100文字)
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
{
|
|
47
|
+
"success": boolean, // 送信が成功したか
|
|
48
|
+
"message_id": string, // 送信されたメッセージのID
|
|
49
|
+
"channel_id": string, // 送信先チャンネルID
|
|
50
|
+
"timestamp": string // 送信日時 (ISO 8601形式)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
Examples:
|
|
54
|
+
- シンプルなテキスト送信: { "content": "Hello, Discord!" }
|
|
55
|
+
- Embed付き送信: { "embeds": [{ "title": "タイトル", "description": "説明", "color": 0x00FF00 }] }
|
|
56
|
+
- スレッドに送信: { "content": "スレッドメッセージ", "thread_id": "123456789" }
|
|
57
|
+
|
|
58
|
+
Error Handling:
|
|
59
|
+
- "Validation error: content/embeds - content、embeds のうち最低1つを指定してください"
|
|
60
|
+
- "Discord Webhook error: 400 Bad Request - Invalid webhook URL"
|
|
61
|
+
- "Discord Webhook error: 404 Not Found - Webhook not found"
|
|
62
|
+
- "Discord Webhook error: レート制限に達しました" - 429エラー時、retry-after秒後に再試行`,
|
|
63
|
+
inputSchema: SendMessageSchema,
|
|
64
|
+
annotations: {
|
|
65
|
+
readOnlyHint: false,
|
|
66
|
+
destructiveHint: false,
|
|
67
|
+
idempotentHint: false,
|
|
68
|
+
openWorldHint: true,
|
|
69
|
+
},
|
|
70
|
+
}, async (params) => {
|
|
71
|
+
// content, embeds のうち1つが必要
|
|
72
|
+
const hasContent = params.content && params.content.length > 0;
|
|
73
|
+
const hasEmbeds = params.embeds && params.embeds.length > 0;
|
|
74
|
+
if (!hasContent && !hasEmbeds) {
|
|
75
|
+
return {
|
|
76
|
+
content: [
|
|
77
|
+
{
|
|
78
|
+
type: "text",
|
|
79
|
+
text: "エラー: content、embeds のうち最低1つを指定してください",
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
isError: true,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// payloadの構築
|
|
86
|
+
const payload = {};
|
|
87
|
+
if (hasContent)
|
|
88
|
+
payload.content = params.content;
|
|
89
|
+
if (params.username)
|
|
90
|
+
payload.username = params.username;
|
|
91
|
+
if (params.avatar_url)
|
|
92
|
+
payload.avatar_url = params.avatar_url;
|
|
93
|
+
if (params.tts)
|
|
94
|
+
payload.tts = params.tts;
|
|
95
|
+
if (hasEmbeds)
|
|
96
|
+
payload.embeds = params.embeds;
|
|
97
|
+
if (params.allowed_mentions)
|
|
98
|
+
payload.allowed_mentions = params.allowed_mentions;
|
|
99
|
+
if (params.thread_name)
|
|
100
|
+
payload.thread_name = params.thread_name;
|
|
101
|
+
// メッセージ送信(wait=trueでメッセージIDを取得)
|
|
102
|
+
const { result, error } = await sendToDiscord(payload, true, params.thread_id);
|
|
103
|
+
if (error) {
|
|
104
|
+
return {
|
|
105
|
+
content: [
|
|
106
|
+
{
|
|
107
|
+
type: "text",
|
|
108
|
+
text: `エラー: ${formatError(error)}`,
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
isError: true,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
const messageInfo = result;
|
|
115
|
+
return {
|
|
116
|
+
content: [
|
|
117
|
+
{
|
|
118
|
+
type: "text",
|
|
119
|
+
text: messageInfo
|
|
120
|
+
? `メッセージを送信しました\nID: ${messageInfo.id}\nチャンネル: ${messageInfo.channel_id}`
|
|
121
|
+
: "メッセージを送信しました",
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
structuredContent: {
|
|
125
|
+
success: true,
|
|
126
|
+
message_id: messageInfo?.id,
|
|
127
|
+
channel_id: messageInfo?.channel_id,
|
|
128
|
+
timestamp: messageInfo?.timestamp,
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
// メッセージ編集ツール
|
|
133
|
+
server.registerTool("discord_edit_message", {
|
|
134
|
+
title: "Edit Discord Message",
|
|
135
|
+
description: `Webhookで送信したメッセージを編集します。
|
|
136
|
+
|
|
137
|
+
content、embedsのいずれか最低1つが必要です。
|
|
138
|
+
環境変数DISCORD_WEBHOOK_URLに設定されたWebhookを使用します。
|
|
139
|
+
|
|
140
|
+
⚠️ レート制限: 30リクエスト/分/チャンネル
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
- message_id (string, required): 編集するメッセージID
|
|
144
|
+
- content (string, optional): 新しいメッセージ内容(1-2000文字)
|
|
145
|
+
- embeds (array, optional): 新しいEmbedの配列(最大10個、合計6000文字以内)
|
|
146
|
+
- allowed_mentions (object, optional): 許可されたメンション設定
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
{
|
|
150
|
+
"success": boolean, // 編集が成功したか
|
|
151
|
+
"message_id": string, // 編集されたメッセージのID
|
|
152
|
+
"timestamp": string // 編集日時 (ISO 8601形式)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
Examples:
|
|
156
|
+
- テキストを編集: { "message_id": "123456789", "content": "更新後のメッセージ" }
|
|
157
|
+
- Embedを編集: { "message_id": "123456789", "embeds": [{ "title": "新しいタイトル", "color": 0xFF0000 }] }
|
|
158
|
+
|
|
159
|
+
Error Handling:
|
|
160
|
+
- "Validation error: content/embeds - content、embeds のうち最低1つを指定してください"
|
|
161
|
+
- "Discord Webhook error: 404 Not Found - Message not found"
|
|
162
|
+
- "Discord Webhook error: 400 Bad Request - Invalid message ID"
|
|
163
|
+
- "Discord Webhook error: レート制限に達しました" - 429エラー時、retry-after秒後に再試行`,
|
|
164
|
+
inputSchema: EditMessageSchema,
|
|
165
|
+
annotations: {
|
|
166
|
+
readOnlyHint: false,
|
|
167
|
+
destructiveHint: false,
|
|
168
|
+
idempotentHint: true,
|
|
169
|
+
openWorldHint: true,
|
|
170
|
+
},
|
|
171
|
+
}, async (params) => {
|
|
172
|
+
// content, embeds のうち1つが必要
|
|
173
|
+
const hasContent = params.content && params.content.length > 0;
|
|
174
|
+
const hasEmbeds = params.embeds && params.embeds.length > 0;
|
|
175
|
+
if (!hasContent && !hasEmbeds) {
|
|
176
|
+
return {
|
|
177
|
+
content: [
|
|
178
|
+
{
|
|
179
|
+
type: "text",
|
|
180
|
+
text: "エラー: content、embeds のうち最低1つを指定してください",
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
isError: true,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
// payloadの構築
|
|
187
|
+
const payload = {};
|
|
188
|
+
if (hasContent)
|
|
189
|
+
payload.content = params.content;
|
|
190
|
+
if (hasEmbeds)
|
|
191
|
+
payload.embeds = params.embeds;
|
|
192
|
+
if (params.allowed_mentions)
|
|
193
|
+
payload.allowed_mentions = params.allowed_mentions;
|
|
194
|
+
// メッセージ編集
|
|
195
|
+
const { result, error } = await editDiscordMessage(params.message_id, payload);
|
|
196
|
+
if (error || !result) {
|
|
197
|
+
return {
|
|
198
|
+
content: [
|
|
199
|
+
{
|
|
200
|
+
type: "text",
|
|
201
|
+
text: error
|
|
202
|
+
? `エラー: ${formatError(error)}`
|
|
203
|
+
: "エラー: メッセージの編集に失敗しました",
|
|
204
|
+
},
|
|
205
|
+
],
|
|
206
|
+
isError: true,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
content: [
|
|
211
|
+
{
|
|
212
|
+
type: "text",
|
|
213
|
+
text: `メッセージを編集しました\nID: ${result.id}`,
|
|
214
|
+
},
|
|
215
|
+
],
|
|
216
|
+
structuredContent: {
|
|
217
|
+
success: true,
|
|
218
|
+
message_id: result.id,
|
|
219
|
+
timestamp: result.timestamp,
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
});
|
|
223
|
+
// メッセージ削除ツール
|
|
224
|
+
server.registerTool("discord_delete_message", {
|
|
225
|
+
title: "Delete Discord Message",
|
|
226
|
+
description: `Webhookで送信したメッセージを削除します。
|
|
227
|
+
|
|
228
|
+
環境変数DISCORD_WEBHOOK_URLに設定されたWebhookを使用します。
|
|
229
|
+
|
|
230
|
+
⚠️ レート制限: 30リクエスト/分/チャンネル
|
|
231
|
+
⚠️ この操作は取り消せません。
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
- message_id (string, required): 削除するメッセージID
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
{
|
|
238
|
+
"success": boolean, // 削除が成功したか
|
|
239
|
+
"message_id": string // 削除されたメッセージのID
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
Examples:
|
|
243
|
+
- メッセージ削除: { "message_id": "123456789" }
|
|
244
|
+
|
|
245
|
+
Error Handling:
|
|
246
|
+
- "Discord Webhook error: 404 Not Found - Message not found"
|
|
247
|
+
- "Discord Webhook error: 400 Bad Request - Invalid message ID"
|
|
248
|
+
- "Discord Webhook error: レート制限に達しました" - 429エラー時、retry-after秒後に再試行`,
|
|
249
|
+
inputSchema: DeleteMessageSchema,
|
|
250
|
+
annotations: {
|
|
251
|
+
readOnlyHint: false,
|
|
252
|
+
destructiveHint: true,
|
|
253
|
+
idempotentHint: true,
|
|
254
|
+
openWorldHint: true,
|
|
255
|
+
},
|
|
256
|
+
}, async (params) => {
|
|
257
|
+
// メッセージ削除
|
|
258
|
+
const { error } = await deleteDiscordMessage(params.message_id);
|
|
259
|
+
if (error) {
|
|
260
|
+
return {
|
|
261
|
+
content: [
|
|
262
|
+
{
|
|
263
|
+
type: "text",
|
|
264
|
+
text: `エラー: ${formatError(error)}`,
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
isError: true,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
content: [
|
|
272
|
+
{
|
|
273
|
+
type: "text",
|
|
274
|
+
text: `メッセージを削除しました\nID: ${params.message_id}`,
|
|
275
|
+
},
|
|
276
|
+
],
|
|
277
|
+
structuredContent: {
|
|
278
|
+
success: true,
|
|
279
|
+
message_id: params.message_id,
|
|
280
|
+
},
|
|
281
|
+
};
|
|
282
|
+
});
|
|
283
|
+
// ============ サーバー起動 ============
|
|
284
|
+
async function main() {
|
|
285
|
+
const transport = new StdioServerTransport();
|
|
286
|
+
await server.connect(transport);
|
|
287
|
+
process.stderr.write("Discord Webhook MCP Server running via stdio\n");
|
|
288
|
+
}
|
|
289
|
+
main().catch((error) => {
|
|
290
|
+
process.stderr.write(`Fatal error: ${error}\n`);
|
|
291
|
+
process.exit(1);
|
|
292
|
+
});
|
|
293
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|