Added Webhook Management Tools
This commit is contained in:
parent
acccac2759
commit
9e329f35ce
|
@ -20,6 +20,8 @@ build/
|
||||||
.vscode/
|
.vscode/
|
||||||
*.swp
|
*.swp
|
||||||
*.swo
|
*.swo
|
||||||
|
record/
|
||||||
|
*.mdc
|
||||||
|
|
||||||
# Operating Systems
|
# Operating Systems
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
|
@ -19,6 +19,7 @@ MCP-Discord provides the following Discord-related functionalities:
|
||||||
- Create/delete/reply to forum posts
|
- Create/delete/reply to forum posts
|
||||||
- Create/delete text channels
|
- Create/delete text channels
|
||||||
- Add/remove message reactions
|
- Add/remove message reactions
|
||||||
|
- Create/edit/delete/use webhooks
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ MCP-Discord provides the following Discord-related functionalities:
|
||||||
- [Channel Management](#channel-management)
|
- [Channel Management](#channel-management)
|
||||||
- [Forum Functions](#forum-functions)
|
- [Forum Functions](#forum-functions)
|
||||||
- [Messages and Reactions](#messages-and-reactions)
|
- [Messages and Reactions](#messages-and-reactions)
|
||||||
|
- [Webhook Management](#webhook-management)
|
||||||
- [Development](#development)
|
- [Development](#development)
|
||||||
- [License](#license)
|
- [License](#license)
|
||||||
|
|
||||||
|
@ -155,6 +157,13 @@ node path/to/mcp-discord/build/index.js --config "{\"DISCORD_TOKEN\":\"your_disc
|
||||||
- `discord_remove_reaction`: Remove a reaction from a message
|
- `discord_remove_reaction`: Remove a reaction from a message
|
||||||
- `discord_delete_message`: Delete a specific message from a channel
|
- `discord_delete_message`: Delete a specific message from a channel
|
||||||
|
|
||||||
|
### Webhook Management
|
||||||
|
|
||||||
|
- `discord_create_webhook`: Creates a new webhook for a Discord channel
|
||||||
|
- `discord_send_webhook_message`: Sends a message to a Discord channel using a webhook
|
||||||
|
- `discord_edit_webhook`: Edits an existing webhook for a Discord channel
|
||||||
|
- `discord_delete_webhook`: Deletes an existing webhook for a Discord channel
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
252
src/index.ts
252
src/index.ts
|
@ -148,6 +148,37 @@ const DeleteMessageSchema = z.object({
|
||||||
reason: z.string().optional()
|
reason: z.string().optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const CreateWebhookSchema = z.object({
|
||||||
|
channelId: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
avatar: z.string().optional(),
|
||||||
|
reason: z.string().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
const SendWebhookMessageSchema = z.object({
|
||||||
|
webhookId: z.string(),
|
||||||
|
webhookToken: z.string(),
|
||||||
|
content: z.string(),
|
||||||
|
username: z.string().optional(),
|
||||||
|
avatarURL: z.string().optional(),
|
||||||
|
threadId: z.string().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
const EditWebhookSchema = z.object({
|
||||||
|
webhookId: z.string(),
|
||||||
|
webhookToken: z.string().optional(),
|
||||||
|
name: z.string().optional(),
|
||||||
|
avatar: z.string().optional(),
|
||||||
|
channelId: z.string().optional(),
|
||||||
|
reason: z.string().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
const DeleteWebhookSchema = z.object({
|
||||||
|
webhookId: z.string(),
|
||||||
|
webhookToken: z.string().optional(),
|
||||||
|
reason: z.string().optional()
|
||||||
|
});
|
||||||
|
|
||||||
// Set up the tool list
|
// Set up the tool list
|
||||||
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
||||||
return {
|
return {
|
||||||
|
@ -353,6 +384,65 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
||||||
},
|
},
|
||||||
required: ["channelId", "messageId"]
|
required: ["channelId", "messageId"]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "discord_create_webhook",
|
||||||
|
description: "Creates a new webhook for a Discord channel",
|
||||||
|
inputSchema: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
channelId: { type: "string" },
|
||||||
|
name: { type: "string" },
|
||||||
|
avatar: { type: "string" },
|
||||||
|
reason: { type: "string" }
|
||||||
|
},
|
||||||
|
required: ["channelId", "name"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "discord_send_webhook_message",
|
||||||
|
description: "Sends a message to a Discord channel using a webhook",
|
||||||
|
inputSchema: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
webhookId: { type: "string" },
|
||||||
|
webhookToken: { type: "string" },
|
||||||
|
content: { type: "string" },
|
||||||
|
username: { type: "string" },
|
||||||
|
avatarURL: { type: "string" },
|
||||||
|
threadId: { type: "string" }
|
||||||
|
},
|
||||||
|
required: ["webhookId", "webhookToken", "content"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "discord_edit_webhook",
|
||||||
|
description: "Edits an existing webhook for a Discord channel",
|
||||||
|
inputSchema: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
webhookId: { type: "string" },
|
||||||
|
webhookToken: { type: "string" },
|
||||||
|
name: { type: "string" },
|
||||||
|
avatar: { type: "string" },
|
||||||
|
channelId: { type: "string" },
|
||||||
|
reason: { type: "string" }
|
||||||
|
},
|
||||||
|
required: ["webhookId"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "discord_delete_webhook",
|
||||||
|
description: "Deletes an existing webhook for a Discord channel",
|
||||||
|
inputSchema: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
webhookId: { type: "string" },
|
||||||
|
webhookToken: { type: "string" },
|
||||||
|
reason: { type: "string" }
|
||||||
|
},
|
||||||
|
required: ["webhookId"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
@ -1072,6 +1162,168 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "discord_create_webhook": {
|
||||||
|
const { channelId, name, avatar, reason } = CreateWebhookSchema.parse(args);
|
||||||
|
try {
|
||||||
|
if (!client.isReady()) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: "Discord client not logged in. Please use discord_login tool first." }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const channel = await client.channels.fetch(channelId);
|
||||||
|
if (!channel || !channel.isTextBased()) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Cannot find text channel with ID: ${channelId}` }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the channel supports webhooks
|
||||||
|
if (!('createWebhook' in channel)) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Channel type does not support webhooks: ${channelId}` }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the webhook
|
||||||
|
const webhook = await channel.createWebhook({
|
||||||
|
name: name,
|
||||||
|
avatar: avatar,
|
||||||
|
reason: reason
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [{
|
||||||
|
type: "text",
|
||||||
|
text: `Successfully created webhook with ID: ${webhook.id} and token: ${webhook.token}`
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Failed to create webhook: ${error}` }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case "discord_send_webhook_message": {
|
||||||
|
const { webhookId, webhookToken, content, username, avatarURL, threadId } = SendWebhookMessageSchema.parse(args);
|
||||||
|
try {
|
||||||
|
if (!client.isReady()) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: "Discord client not logged in. Please use discord_login tool first." }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const webhook = await client.fetchWebhook(webhookId, webhookToken);
|
||||||
|
if (!webhook) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Cannot find webhook with ID: ${webhookId}` }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the message
|
||||||
|
await webhook.send({
|
||||||
|
content: content,
|
||||||
|
username: username,
|
||||||
|
avatarURL: avatarURL,
|
||||||
|
threadId: threadId
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [{
|
||||||
|
type: "text",
|
||||||
|
text: `Successfully sent webhook message to webhook ID: ${webhookId}`
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Failed to send webhook message: ${error}` }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case "discord_edit_webhook": {
|
||||||
|
const { webhookId, webhookToken, name, avatar, channelId, reason } = EditWebhookSchema.parse(args);
|
||||||
|
try {
|
||||||
|
if (!client.isReady()) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: "Discord client not logged in. Please use discord_login tool first." }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const webhook = await client.fetchWebhook(webhookId, webhookToken);
|
||||||
|
if (!webhook) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Cannot find webhook with ID: ${webhookId}` }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit the webhook
|
||||||
|
await webhook.edit({
|
||||||
|
name: name,
|
||||||
|
avatar: avatar,
|
||||||
|
channel: channelId,
|
||||||
|
reason: reason
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [{
|
||||||
|
type: "text",
|
||||||
|
text: `Successfully edited webhook with ID: ${webhook.id}`
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Failed to edit webhook: ${error}` }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case "discord_delete_webhook": {
|
||||||
|
const { webhookId, webhookToken, reason } = DeleteWebhookSchema.parse(args);
|
||||||
|
try {
|
||||||
|
if (!client.isReady()) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: "Discord client not logged in. Please use discord_login tool first." }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const webhook = await client.fetchWebhook(webhookId, webhookToken);
|
||||||
|
if (!webhook) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Cannot find webhook with ID: ${webhookId}` }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the webhook
|
||||||
|
await webhook.delete(reason || "Webhook deleted via API");
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [{
|
||||||
|
type: "text",
|
||||||
|
text: `Successfully deleted webhook with ID: ${webhook.id}`
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Failed to delete webhook: ${error}` }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown tool: ${name}`);
|
throw new Error(`Unknown tool: ${name}`);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue