messages_list_chats
Retrieve a list of available iMessage and SMS chats with optional participant details using macOS AppleScript integration.
Instructions
[iMessage operations] List available iMessage and SMS chats
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| includeParticipantDetails | No | Include detailed participant information |
Implementation Reference
- src/categories/messages.ts:13-22 (schema)Input schema definition for the messages_list_chats tool, allowing optional inclusion of participant details.schema: { type: "object", properties: { includeParticipantDetails: { type: "boolean", description: "Include detailed participant information", default: false } } },
- src/categories/messages.ts:23-60 (handler)Core handler logic: Generates AppleScript that iterates over Messages app chats, extracts chat info (name, ID, group status), and optionally includes participant details.script: (args) => ` tell application "Messages" set chatList to {} repeat with aChat in chats set chatName to name of aChat if chatName is missing value then set chatName to "" -- Try to get the contact name for individual chats try set theParticipants to participants of aChat if (count of theParticipants) is 1 then set theParticipant to item 1 of theParticipants set chatName to name of theParticipant end if end try end if set chatInfo to {id:id of aChat, name:chatName, isGroupChat:(id of aChat contains "+")} ${args.includeParticipantDetails ? ` -- Add participant details if requested set participantList to {} repeat with aParticipant in participants of aChat set participantInfo to {id:id of aParticipant, handle:handle of aParticipant} try set participantInfo to participantInfo & {name:name of aParticipant} end try copy participantInfo to end of participantList end repeat set chatInfo to chatInfo & {participant:participantList} ` : ''} copy chatInfo to end of chatList end repeat return chatList end tell ` },
- src/index.ts:11-34 (registration)Registration of the messages category (containing list_chats script) by importing and adding to the MCP server framework.import { messagesCategory } from "./categories/messages.js"; import { notesCategory } from "./categories/notes.js"; const server = new AppleScriptFramework({ name: "applescript-server", version: "1.0.4", debug: false, }); // Log startup information using stderr (server isn't connected yet) console.error(`[INFO] Starting AppleScript MCP server - PID: ${process.pid}`); // Add all categories console.error("[INFO] Registering categories..."); server.addCategory(systemCategory); server.addCategory(calendarCategory); server.addCategory(finderCategory); server.addCategory(clipboardCategory); server.addCategory(notificationsCategory); server.addCategory(itermCategory); server.addCategory(mailCategory); server.addCategory(pagesCategory); server.addCategory(shortcutsCategory); server.addCategory(messagesCategory);
- src/framework.ts:221-232 (registration)Dynamic tool registration in ListTools handler: constructs tool name as '{category}_{script}' e.g. 'messages_list_chats'.this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: this.categories.flatMap((category) => category.scripts.map((script) => ({ name: `${category.name}_${script.name}`, // Changed from dot to underscore description: `[${category.description}] ${script.description}`, inputSchema: script.schema || { type: "object", properties: {}, }, })), ), }));
- src/framework.ts:243-294 (handler)Generic tool execution handler: parses tool name 'messages_list_chats' into category/script, generates script from handler, executes via osascript, returns result.// Split on underscore instead of dot const [categoryName, ...scriptNameParts] = toolName.split("_"); const scriptName = scriptNameParts.join("_"); // Rejoin in case script name has underscores const category = this.categories.find((c) => c.name === categoryName); if (!category) { this.log("warning", "Category not found", { categoryName }); throw new McpError( ErrorCode.MethodNotFound, `Category not found: ${categoryName}`, ); } const script = category.scripts.find((s) => s.name === scriptName); if (!script) { this.log("warning", "Script not found", { categoryName, scriptName }); throw new McpError( ErrorCode.MethodNotFound, `Script not found: ${scriptName}`, ); } this.log("debug", "Generating script content", { categoryName, scriptName, isFunction: typeof script.script === "function" }); const scriptContent = typeof script.script === "function" ? script.script(request.params.arguments) : script.script; const result = await this.executeScript(scriptContent); this.log("info", "Tool execution completed successfully", { tool: toolName, resultLength: result.length }); return { content: [ { type: "text", text: result, }, ], };