whatsapp_send_image
Send image messages to WhatsApp contacts or groups using URLs or base64 data, with options for captions, mentions, replies, and view-once delivery.
Instructions
Send an image message to a WhatsApp contact or group. Can send from URL or base64.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient phone number (with @s.whatsapp.net) or group ID (with @g.us) | |
| imageBase64 | No | Base64 encoded image data (alternative to imageURL) | |
| imageURL | No | URL of the image to send (alternative to imageBase64) | |
| mimeType | Yes | MIME type of the image | |
| caption | No | Caption for the image (max 1024 characters) | |
| mentions | No | List of phone numbers to mention in the caption | |
| replyTo | No | ID of the message being replied to | |
| isForwarded | No | Whether the message should be marked as forwarded | |
| viewOnce | No | Whether the image should be sent as view-once |
Implementation Reference
- src/tools/messaging.ts:76-150 (handler)Full ToolHandler implementation for 'whatsapp_send_image', including MCP inputSchema, Zod validation via sendImageMessageSchema, logging, and WSAPI call to POST /messages/image.export const sendImageMessage: ToolHandler = { name: 'whatsapp_send_image', description: 'Send an image message to a WhatsApp contact or group. Can send from URL or base64.', inputSchema: { type: 'object', properties: { to: { type: 'string', description: 'Recipient phone number (with @s.whatsapp.net) or group ID (with @g.us)', }, imageBase64: { type: 'string', description: 'Base64 encoded image data (alternative to imageURL)', optional: true, }, imageURL: { type: 'string', description: 'URL of the image to send (alternative to imageBase64)', optional: true, }, mimeType: { type: 'string', enum: ['image/jpeg', 'image/png', 'image/webp', 'image/gif'], description: 'MIME type of the image', }, caption: { type: 'string', description: 'Caption for the image (max 1024 characters)', optional: true, }, mentions: { type: 'array', items: { type: 'string' }, description: 'List of phone numbers to mention in the caption', optional: true, }, replyTo: { type: 'string', description: 'ID of the message being replied to', optional: true, }, isForwarded: { type: 'boolean', description: 'Whether the message should be marked as forwarded', optional: true, }, viewOnce: { type: 'boolean', description: 'Whether the image should be sent as view-once', optional: true, }, }, required: ['to', 'mimeType'], }, handler: async (args: any) => { const input = validateInput(sendImageMessageSchema, args) as SendImageMessageInput; logger.info('Sending image message', { to: input.to, mimeType: input.mimeType, hasCaption: !!input.caption, viewOnce: input.viewOnce, }); const result = await wsapiClient.post('/messages/image', input); logger.info('Image message sent successfully', { messageId: result.id }); return { success: true, messageId: result.id, message: 'Image message sent successfully', }; }, };
- src/validation/schemas.ts:20-32 (schema)Zod validation schema sendImageMessageSchema used in the handler's validateInput call, ensuring required fields like 'to', 'mimeType', and either image source.export const sendImageMessageSchema = z.object({ to: chatIdSchema, imageBase64: base64Schema.optional(), imageURL: urlSchema.optional(), mimeType: z.enum(['image/jpeg', 'image/png', 'image/webp', 'image/gif']), caption: z.string().max(1024).optional(), mentions: z.array(phoneNumberSchema).optional(), replyTo: messageIdSchema.optional(), isForwarded: z.boolean().optional(), viewOnce: z.boolean().optional(), }).refine(data => data.imageBase64 || data.imageURL, { message: "Either imageBase64 or imageURL must be provided", });
- src/tools/messaging.ts:544-555 (registration)Collects the sendImageMessage handler (among others) into messagingTools export, which is imported by the MCP server for registration.export const messagingTools = { sendTextMessage, sendImageMessage, sendVideoMessage, sendLinkMessage, sendReactionMessage, editMessage, deleteMessage, markMessageAsRead, starMessage, ...advancedMessagingTools, };
- src/server.ts:53-77 (registration)Registers tools from messagingTools into the MCP server's internal tools Map using this.tools.set(tool.name, tool), making 'whatsapp_send_image' available for list_tools and call_tool requests.private setupToolHandlers(): void { logger.info('Setting up tool handlers'); // Register all tool categories const toolCategories = [ messagingTools, contactTools, groupTools, chatTools, sessionTools, instanceTools, accountTools, ]; toolCategories.forEach(category => { Object.values(category).forEach(tool => { if (this.tools.has(tool.name)) { logger.warn(`Tool ${tool.name} already registered, skipping`); return; } this.tools.set(tool.name, tool); logger.debug(`Registered tool: ${tool.name}`); }); });