Skip to main content
Glama

Apple MCP Tools

by wearesage
messagesHandler.ts3.79 kB
import { z } from "zod"; import type { LoadModuleFunction, ToolResult } from "./../types"; // Define the Zod schema for messages arguments export const MessagesArgsSchema = z.discriminatedUnion("operation", [ z.object({ operation: z.literal("send"), phoneNumber: z.string(), message: z.string() }), z.object({ operation: z.literal("read"), phoneNumber: z.string(), limit: z.number().optional() }), z.object({ operation: z.literal("schedule"), phoneNumber: z.string(), message: z.string(), scheduledTime: z.string().datetime() }), // Assuming ISO 8601 format z.object({ operation: z.literal("unread"), limit: z.number().optional() }), ]); // Define the argument type from the schema type MessagesArgs = z.infer<typeof MessagesArgsSchema>; export async function handleMessages( args: MessagesArgs, loadModule: LoadModuleFunction ): Promise<ToolResult> { try { const messageModule = await loadModule('message'); switch (args.operation) { case "send": { await messageModule.sendMessage(args.phoneNumber, args.message); return { content: [{ type: "text", text: `Message sent to ${args.phoneNumber}` }], isError: false }; } case "read": { const messages = await messageModule.readMessages(args.phoneNumber, args.limit); return { content: [{ type: "text", text: messages.length > 0 ? messages.map(msg => `[${new Date(msg.date).toLocaleString()}] ${msg.is_from_me ? 'Me' : msg.sender}: ${msg.content}` ).join("\n") : "No messages found" }], isError: false }; } case "schedule": { const scheduledMsg = await messageModule.scheduleMessage( args.phoneNumber, args.message, new Date(args.scheduledTime) ); return { content: [{ type: "text", text: `Message scheduled to be sent to ${args.phoneNumber} at ${scheduledMsg.scheduledTime}` }], isError: false }; } case "unread": { const messages = await messageModule.getUnreadMessages(args.limit); // Look up contact names for all messages const contactsModule = await loadModule('contacts'); // Need contacts module here const messagesWithNames = await Promise.all( messages.map(async msg => { // Only look up names for messages not from me if (!msg.is_from_me) { const contactName = await contactsModule.findContactByPhone(msg.sender); return { ...msg, displayName: contactName || msg.sender // Use contact name if found, otherwise use phone/email }; } return { ...msg, displayName: 'Me' }; }) ); return { content: [{ type: "text", text: messagesWithNames.length > 0 ? `Found ${messagesWithNames.length} unread message(s):\n` + messagesWithNames.map(msg => `[${new Date(msg.date).toLocaleString()}] From ${msg.displayName}:\n${msg.content}` ).join("\n\n") : "No unread messages found" }], isError: false }; } default: // This should be unreachable due to Zod validation throw new Error(`Unknown messages operation: ${(args as any).operation}`); } } catch (error) { return { content: [{ type: "text", text: `Error with messages operation: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wearesage/mcp-apple'

If you have feedback or need assistance with the MCP directory API, please join our Discord server