// mcp/modules/whatsappIntegration.js import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from "zod"; import { fetchJSON } from "../lib/api.js"; const log = (...args) => console.log("[MCP WhatsAppIntegration]", ...args); // Changed log prefix export default function registerWhatsappIntegration(server) { // --- WhatsApp Actions --- // Tool: whatsapp.send-text server.tool( "whatsapp.send-text", "Sends a text message via WhatsApp.", { to: z.string().describe("Recipient ID (e.g., 1234567890@c.us)"), content: z.string().describe("Text message content"), }, async (params) => { log("Tool invoked", "whatsapp.send-text", params); const result = await fetchJSON("/send-text", { method: "POST", body: JSON.stringify(params), }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); // Tool: whatsapp.send-image server.tool( "whatsapp.send-image", "Sends an image message via WhatsApp.", { to: z.string().describe("Recipient ID"), path: z.string().describe("Path or URL to the image"), caption: z.string().optional().describe("Image caption"), }, async (params) => { log("Tool invoked", "whatsapp.send-image", params); const result = await fetchJSON("/send-image", { method: "POST", body: JSON.stringify(params), }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); // Tool: whatsapp.send-file server.tool( "whatsapp.send-file", "Sends a file message via WhatsApp.", { to: z.string().describe("Recipient ID"), path: z.string().describe("Path or URL to the file"), filename: z.string().optional().describe("Name of the file"), caption: z.string().optional().describe("File caption"), }, async (params) => { log("Tool invoked", "whatsapp.send-file", params); const result = await fetchJSON("/send-file", { method: "POST", body: JSON.stringify(params), }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); // Tool: whatsapp.list-chats server.tool( "whatsapp.list-chats", "Retrieves a list of all chats.", {}, // No input parameters async () => { log("Tool invoked", "whatsapp.list-chats"); const result = await fetchJSON("/chats"); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); // Tool: whatsapp.get-chat-details server.tool( "whatsapp.get-chat-details", "Retrieves details for a specific chat by its ID.", { chatId: z.string().describe("ID of the chat (e.g., 1234567890@c.us)"), }, async (params) => { log("Tool invoked", "whatsapp.get-chat-details", params); const result = await fetchJSON(`/chats/${params.chatId}`); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); // Tool: whatsapp.get-chat-messages server.tool( "whatsapp.get-chat-messages", "Retrieves messages for a specific chat.", { chatId: z.string().describe("ID of the chat"), limit: z.number().optional().describe("Number of messages to retrieve"), includeMe: z.boolean().optional().describe("Include messages sent by me"), includeNotifications: z.boolean().optional().describe("Include notification messages"), }, async ({ chatId, ...queryParams}) => { log("Tool invoked", "whatsapp.get-chat-messages", { chatId, queryParams }); const qs = new URLSearchParams( Object.entries(queryParams) .filter(([, v]) => v !== undefined) .map(([k, v]) => [k, String(v)]) ); const result = await fetchJSON(`/chats/${chatId}/messages?${qs.toString()}`); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); server.tool( "whatsapp.delete-chat", "Deletes a chat by its ID. (Note: The underlying OpenWA endpoint for this is assumed and might need verification)", { chatId: z.string().describe("ID of the chat to delete (e.g., 1234567890@c.us)"), }, async (params) => { log("Tool invoked", "whatsapp.delete-chat", params); const result = await fetchJSON(`/chats/${params.chatId}`, { method: "DELETE", }); // Consider what a successful deletion should return. // OpenWA might return a success message or just a 200/204. // For now, we'll return the full result. return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); // Tool: whatsapp.create-group server.tool( "whatsapp.create-group", "Creates a new WhatsApp group.", { groupName: z.string().describe("Name of the group"), contactIds: z.array(z.string()).describe("Array of contact IDs to add to the group"), }, async (params) => { log("Tool invoked", "whatsapp.create-group", params); const result = await fetchJSON("/groups", { method: "POST", body: JSON.stringify(params), }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); // Tool: whatsapp.get-contact-details server.tool( "whatsapp.get-contact-details", "Retrieves details for a specific contact by ID.", { contactId: z.string().describe("ID of the contact (e.g., 1234567890@c.us)"), }, async (params) => { log("Tool invoked", "whatsapp.get-contact-details", params); const result = await fetchJSON(`/contacts/${params.contactId}`); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); // Tool: whatsapp.get-blocklist server.tool( "whatsapp.get-blocklist", "Retrieves the blocklist.", {}, // No input parameters async () => { log("Tool invoked", "whatsapp.get-blocklist"); const result = await fetchJSON("/blocklist"); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); // Tool: whatsapp.block-contact server.tool( "whatsapp.block-contact", "Blocks a contact on WhatsApp.", { contactId: z.string().describe("ID of the contact to block"), }, async (params) => { log("Tool invoked", "whatsapp.block-contact", params); const result = await fetchJSON("/blocklist/block", { method: "POST", body: JSON.stringify(params), }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); // Tool: whatsapp.unblock-contact server.tool( "whatsapp.unblock-contact", "Unblocks a contact on WhatsApp.", { contactId: z.string().describe("ID of the contact to unblock"), }, async (params) => { log("Tool invoked", "whatsapp.unblock-contact", params); const result = await fetchJSON("/blocklist/unblock", { method: "POST", body: JSON.stringify(params), }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); }