Files
hermes-mcp/src/clients/discord.ts
Garfield e1e7d88c8a feat: Discord + Instagram integrations
Discord Bot API
- New client: src/clients/discord.ts
- Tools: discord_get_me, discord_get_guilds, discord_get_channels, discord_send_message, discord_get_messages
- REST endpoints: GET /api/discord/me, /api/discord/guilds, /api/discord/channels, /api/discord/messages, POST /api/discord/message
- Multi-account env var: DISCORD_{ACCOUNT}_BOT_TOKEN

Instagram Graph API
- New client: src/clients/instagram.ts
- Tools: instagram_get_profile, instagram_get_media, instagram_create_post
- REST endpoints: GET /api/instagram/profile, /api/instagram/media, POST /api/instagram/post
- Multi-account env vars: INSTAGRAM_{ACCOUNT}_ACCESS_TOKEN, INSTAGRAM_{ACCOUNT}_BUSINESS_ACCOUNT_ID

Total tools: 32
2026-05-05 22:01:21 -04:00

102 lines
2.7 KiB
TypeScript

const DISCORD_API_BASE = 'https://discord.com/api/v10';
function getToken(account: string): string {
const envKey = `DISCORD_${account.toUpperCase()}_BOT_TOKEN`;
return process.env[envKey] ?? '';
}
async function discordRequest(
token: string,
endpoint: string,
method: 'GET' | 'POST' = 'GET',
body?: unknown
) {
const url = `${DISCORD_API_BASE}${endpoint}`;
const res = await fetch(url, {
method,
headers: {
'Authorization': `Bot ${token}`,
'Content-Type': 'application/json',
},
body: body ? JSON.stringify(body) : undefined,
signal: AbortSignal.timeout(15000),
});
if (!res.ok) {
const error = await res.text();
throw new Error(`Discord API error (${res.status}): ${error}`);
}
return res.json();
}
export async function getMe(args: { account?: string }): Promise<{
id: string;
username: string;
bot: boolean;
}> {
const token = getToken(args.account ?? 'default');
if (!token) {
throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN');
}
return discordRequest(token, '/users/@me');
}
export async function getGuilds(args: { account?: string }): Promise<Array<{
id: string;
name: string;
icon?: string;
}>> {
const token = getToken(args.account ?? 'default');
if (!token) {
throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN');
}
return discordRequest(token, '/users/@me/guilds');
}
export async function getChannels(args: { guild_id: string; account?: string }): Promise<Array<{
id: string;
name: string;
type: number;
}>> {
const token = getToken(args.account ?? 'default');
if (!token) {
throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN');
}
return discordRequest(token, `/guilds/${args.guild_id}/channels`);
}
export async function sendMessage(args: {
channel_id: string;
content: string;
account?: string;
}): Promise<{ id: string; channel_id: string }> {
const token = getToken(args.account ?? 'default');
if (!token) {
throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN');
}
return discordRequest(token, `/channels/${args.channel_id}/messages`, 'POST', {
content: args.content,
});
}
export async function getMessages(args: {
channel_id: string;
limit?: number;
account?: string;
}): Promise<Array<{
id: string;
content: string;
author: { username: string; id: string };
timestamp: string;
}>> {
const token = getToken(args.account ?? 'default');
if (!token) {
throw new Error('Missing Discord credentials. Set DISCORD_{ACCOUNT}_BOT_TOKEN');
}
const limit = args.limit ?? 10;
return discordRequest(token, `/channels/${args.channel_id}/messages?limit=${limit}`);
}