-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Add Discord MCP integration and improve README #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import { McpAppAuth } from "../../mcp-app/property"; | ||
|
|
||
| export const discordAuth = McpAppAuth.OAuth2({ | ||
| description: "Connect to Discord to send messages and manage channels", | ||
| authUrl: "https://discord.com/api/oauth2/authorize", | ||
| tokenUrl: "https://discord.com/api/oauth2/token", | ||
| required: true, | ||
| scope: ["bot", "messages.read", "guilds", "guilds.members.read", "identify"], | ||
| }); | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,211 @@ | ||||||||||||||
| import type { OAuth2Props } from "@/app/mcp/mcp-app/property"; | ||||||||||||||
| import type { OAuth2Property } from "@/app/mcp/mcp-app/property/authentication/oauth2-prop"; | ||||||||||||||
| import type { McpRequestHandlerExtra } from "../../mcp-app/tools"; | ||||||||||||||
| import type { | ||||||||||||||
| DiscordChannel, | ||||||||||||||
| DiscordEmbed, | ||||||||||||||
| DiscordGuild, | ||||||||||||||
| DiscordMessage, | ||||||||||||||
| DiscordMessagePayload, | ||||||||||||||
| DiscordUser, | ||||||||||||||
| } from "./types"; | ||||||||||||||
|
|
||||||||||||||
| const DISCORD_API_BASE = "https://discord.com/api/v10"; | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * Discord API client using OAuth2 access token | ||||||||||||||
| */ | ||||||||||||||
| export class DiscordClient { | ||||||||||||||
| private accessToken: string; | ||||||||||||||
|
|
||||||||||||||
| constructor(accessToken: string) { | ||||||||||||||
| this.accessToken = accessToken; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| private async makeRequest<T = unknown>( | ||||||||||||||
| endpoint: string, | ||||||||||||||
| options: RequestInit = {}, | ||||||||||||||
| ): Promise<T> { | ||||||||||||||
| const url = `${DISCORD_API_BASE}${endpoint}`; | ||||||||||||||
| const headers = { | ||||||||||||||
| Authorization: `Bearer ${this.accessToken}`, | ||||||||||||||
| "Content-Type": "application/json", | ||||||||||||||
| ...options.headers, | ||||||||||||||
| }; | ||||||||||||||
|
|
||||||||||||||
| const response = await fetch(url, { | ||||||||||||||
| ...options, | ||||||||||||||
| headers, | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| if (!response.ok) { | ||||||||||||||
| const errorText = await response.text(); | ||||||||||||||
| throw new Error(`Discord API Error (${response.status}): ${errorText}`); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
|
||||||||||||||
| // Handle 204 No Content or other empty responses | |
| if (response.status === 204 || response.headers.get("content-length") === "0") { | |
| return undefined as T; | |
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import { createMcpApp } from "../../mcp-app"; | ||
| import { McpAppCategory } from "../../mcp-app/app-metadata"; | ||
| import { discordAuth } from "./common"; | ||
| import { discordTools } from "./tools"; | ||
|
|
||
| export const discordMcpApp = createMcpApp({ | ||
| name: "discord", | ||
| displayName: "Discord", | ||
| description: "Discord MCP App for accessing Discord servers and channels", | ||
| logo: { | ||
| type: "url", | ||
| url: "https://api.iconify.design/logos:discord-icon.svg", | ||
| }, | ||
| categories: [McpAppCategory.COMMUNICATION], | ||
| auth: discordAuth, | ||
| tools: discordTools, | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The OAuth scopes configured here may not work as intended for user OAuth flows. The "bot" scope is not a valid Discord user OAuth scope - it's used for bot applications.
For user OAuth2 flows, Discord does not allow users to send messages to guild channels via the API using user tokens. The
/channels/{channel_id}/messagesPOST endpoint requires either:Consider either:
Valid user OAuth scopes would be:
identify,email,guilds,guilds.join,guilds.members.read,gdm.join,messages.read(for DMs only).