airmcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +645 -0
  3. package/dist/calendar/prompts.d.ts +2 -0
  4. package/dist/calendar/prompts.js +43 -0
  5. package/dist/calendar/prompts.js.map +1 -0
  6. package/dist/calendar/scripts.d.ts +20 -0
  7. package/dist/calendar/scripts.js +286 -0
  8. package/dist/calendar/scripts.js.map +1 -0
  9. package/dist/calendar/tools.d.ts +3 -0
  10. package/dist/calendar/tools.js +252 -0
  11. package/dist/calendar/tools.js.map +1 -0
  12. package/dist/cli/doctor.d.ts +7 -0
  13. package/dist/cli/doctor.js +157 -0
  14. package/dist/cli/doctor.js.map +1 -0
  15. package/dist/cli/init.d.ts +8 -0
  16. package/dist/cli/init.js +179 -0
  17. package/dist/cli/init.js.map +1 -0
  18. package/dist/contacts/scripts.d.ts +22 -0
  19. package/dist/contacts/scripts.js +220 -0
  20. package/dist/contacts/scripts.js.map +1 -0
  21. package/dist/contacts/tools.d.ts +3 -0
  22. package/dist/contacts/tools.js +173 -0
  23. package/dist/contacts/tools.js.map +1 -0
  24. package/dist/cross/prompts.d.ts +2 -0
  25. package/dist/cross/prompts.js +802 -0
  26. package/dist/cross/prompts.js.map +1 -0
  27. package/dist/cross/tools.d.ts +7 -0
  28. package/dist/cross/tools.js +81 -0
  29. package/dist/cross/tools.js.map +1 -0
  30. package/dist/finder/scripts.d.ts +8 -0
  31. package/dist/finder/scripts.js +127 -0
  32. package/dist/finder/scripts.js.map +1 -0
  33. package/dist/finder/tools.d.ts +3 -0
  34. package/dist/finder/tools.js +134 -0
  35. package/dist/finder/tools.js.map +1 -0
  36. package/dist/index.d.ts +2 -0
  37. package/dist/index.js +252 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/intelligence/tools.d.ts +3 -0
  40. package/dist/intelligence/tools.js +210 -0
  41. package/dist/intelligence/tools.js.map +1 -0
  42. package/dist/mail/scripts.d.ts +11 -0
  43. package/dist/mail/scripts.js +256 -0
  44. package/dist/mail/scripts.js.map +1 -0
  45. package/dist/mail/tools.d.ts +3 -0
  46. package/dist/mail/tools.js +188 -0
  47. package/dist/mail/tools.js.map +1 -0
  48. package/dist/maps/scripts.d.ts +6 -0
  49. package/dist/maps/scripts.js +61 -0
  50. package/dist/maps/scripts.js.map +1 -0
  51. package/dist/maps/tools.d.ts +3 -0
  52. package/dist/maps/tools.js +109 -0
  53. package/dist/maps/tools.js.map +1 -0
  54. package/dist/messages/scripts.d.ts +6 -0
  55. package/dist/messages/scripts.js +140 -0
  56. package/dist/messages/scripts.js.map +1 -0
  57. package/dist/messages/tools.d.ts +3 -0
  58. package/dist/messages/tools.js +105 -0
  59. package/dist/messages/tools.js.map +1 -0
  60. package/dist/music/scripts.d.ts +13 -0
  61. package/dist/music/scripts.js +218 -0
  62. package/dist/music/scripts.js.map +1 -0
  63. package/dist/music/tools.d.ts +3 -0
  64. package/dist/music/tools.js +205 -0
  65. package/dist/music/tools.js.map +1 -0
  66. package/dist/notes/prompts.d.ts +2 -0
  67. package/dist/notes/prompts.js +47 -0
  68. package/dist/notes/prompts.js.map +1 -0
  69. package/dist/notes/scripts.d.ts +15 -0
  70. package/dist/notes/scripts.js +348 -0
  71. package/dist/notes/scripts.js.map +1 -0
  72. package/dist/notes/tools.d.ts +3 -0
  73. package/dist/notes/tools.js +317 -0
  74. package/dist/notes/tools.js.map +1 -0
  75. package/dist/photos/scripts.d.ts +7 -0
  76. package/dist/photos/scripts.js +142 -0
  77. package/dist/photos/scripts.js.map +1 -0
  78. package/dist/photos/tools.d.ts +3 -0
  79. package/dist/photos/tools.js +158 -0
  80. package/dist/photos/tools.js.map +1 -0
  81. package/dist/podcasts/scripts.d.ts +6 -0
  82. package/dist/podcasts/scripts.js +116 -0
  83. package/dist/podcasts/scripts.js.map +1 -0
  84. package/dist/podcasts/tools.d.ts +3 -0
  85. package/dist/podcasts/tools.js +96 -0
  86. package/dist/podcasts/tools.js.map +1 -0
  87. package/dist/reminders/prompts.d.ts +2 -0
  88. package/dist/reminders/prompts.js +40 -0
  89. package/dist/reminders/prompts.js.map +1 -0
  90. package/dist/reminders/scripts.d.ts +21 -0
  91. package/dist/reminders/scripts.js +208 -0
  92. package/dist/reminders/scripts.js.map +1 -0
  93. package/dist/reminders/tools.d.ts +3 -0
  94. package/dist/reminders/tools.js +269 -0
  95. package/dist/reminders/tools.js.map +1 -0
  96. package/dist/safari/scripts.d.ts +12 -0
  97. package/dist/safari/scripts.js +203 -0
  98. package/dist/safari/scripts.js.map +1 -0
  99. package/dist/safari/tools.d.ts +3 -0
  100. package/dist/safari/tools.js +188 -0
  101. package/dist/safari/tools.js.map +1 -0
  102. package/dist/screen/scripts.d.ts +26 -0
  103. package/dist/screen/scripts.js +115 -0
  104. package/dist/screen/scripts.js.map +1 -0
  105. package/dist/screen/tools.d.ts +3 -0
  106. package/dist/screen/tools.js +168 -0
  107. package/dist/screen/tools.js.map +1 -0
  108. package/dist/semantic/embeddings.d.ts +12 -0
  109. package/dist/semantic/embeddings.js +101 -0
  110. package/dist/semantic/embeddings.js.map +1 -0
  111. package/dist/semantic/service.d.ts +68 -0
  112. package/dist/semantic/service.js +257 -0
  113. package/dist/semantic/service.js.map +1 -0
  114. package/dist/semantic/store.d.ts +56 -0
  115. package/dist/semantic/store.js +107 -0
  116. package/dist/semantic/store.js.map +1 -0
  117. package/dist/semantic/tools.d.ts +10 -0
  118. package/dist/semantic/tools.js +102 -0
  119. package/dist/semantic/tools.js.map +1 -0
  120. package/dist/shared/config.d.ts +41 -0
  121. package/dist/shared/config.js +152 -0
  122. package/dist/shared/config.js.map +1 -0
  123. package/dist/shared/esc.d.ts +10 -0
  124. package/dist/shared/esc.js +35 -0
  125. package/dist/shared/esc.js.map +1 -0
  126. package/dist/shared/hitl-guard.d.ts +8 -0
  127. package/dist/shared/hitl-guard.js +39 -0
  128. package/dist/shared/hitl-guard.js.map +1 -0
  129. package/dist/shared/hitl.d.ts +16 -0
  130. package/dist/shared/hitl.js +131 -0
  131. package/dist/shared/hitl.js.map +1 -0
  132. package/dist/shared/jxa.d.ts +1 -0
  133. package/dist/shared/jxa.js +52 -0
  134. package/dist/shared/jxa.js.map +1 -0
  135. package/dist/shared/modules.d.ts +2 -0
  136. package/dist/shared/modules.js +43 -0
  137. package/dist/shared/modules.js.map +1 -0
  138. package/dist/shared/prompt.d.ts +11 -0
  139. package/dist/shared/prompt.js +8 -0
  140. package/dist/shared/prompt.js.map +1 -0
  141. package/dist/shared/registry.d.ts +9 -0
  142. package/dist/shared/registry.js +2 -0
  143. package/dist/shared/registry.js.map +1 -0
  144. package/dist/shared/resources.d.ts +14 -0
  145. package/dist/shared/resources.js +222 -0
  146. package/dist/shared/resources.js.map +1 -0
  147. package/dist/shared/result.d.ts +23 -0
  148. package/dist/shared/result.js +19 -0
  149. package/dist/shared/result.js.map +1 -0
  150. package/dist/shared/setup.d.ts +3 -0
  151. package/dist/shared/setup.js +53 -0
  152. package/dist/shared/setup.js.map +1 -0
  153. package/dist/shared/share-guard.d.ts +30 -0
  154. package/dist/shared/share-guard.js +60 -0
  155. package/dist/shared/share-guard.js.map +1 -0
  156. package/dist/shared/swift.d.ts +2 -0
  157. package/dist/shared/swift.js +73 -0
  158. package/dist/shared/swift.js.map +1 -0
  159. package/dist/shortcuts/prompts.d.ts +2 -0
  160. package/dist/shortcuts/prompts.js +148 -0
  161. package/dist/shortcuts/prompts.js.map +1 -0
  162. package/dist/shortcuts/scripts.d.ts +10 -0
  163. package/dist/shortcuts/scripts.js +115 -0
  164. package/dist/shortcuts/scripts.js.map +1 -0
  165. package/dist/shortcuts/tools.d.ts +14 -0
  166. package/dist/shortcuts/tools.js +230 -0
  167. package/dist/shortcuts/tools.js.map +1 -0
  168. package/dist/system/scripts.d.ts +17 -0
  169. package/dist/system/scripts.js +257 -0
  170. package/dist/system/scripts.js.map +1 -0
  171. package/dist/system/tools.d.ts +3 -0
  172. package/dist/system/tools.js +333 -0
  173. package/dist/system/tools.js.map +1 -0
  174. package/dist/tv/scripts.d.ts +6 -0
  175. package/dist/tv/scripts.js +121 -0
  176. package/dist/tv/scripts.js.map +1 -0
  177. package/dist/tv/tools.d.ts +3 -0
  178. package/dist/tv/tools.js +95 -0
  179. package/dist/tv/tools.js.map +1 -0
  180. package/dist/ui/scripts.d.ts +24 -0
  181. package/dist/ui/scripts.js +345 -0
  182. package/dist/ui/scripts.js.map +1 -0
  183. package/dist/ui/tools.d.ts +3 -0
  184. package/dist/ui/tools.js +145 -0
  185. package/dist/ui/tools.js.map +1 -0
  186. package/package.json +101 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/maps/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function listChatsScript(limit: number): string;
2
+ export declare function readChatScript(chatId: string): string;
3
+ export declare function searchMessagesScript(query: string, limit: number): string;
4
+ export declare function sendMessageScript(target: string, text: string): string;
5
+ export declare function sendFileScript(target: string, filePath: string): string;
6
+ export declare function listParticipantsScript(chatId: string): string;
@@ -0,0 +1,140 @@
1
+ // JXA scripts for Apple Messages automation.
2
+ import { esc } from "../shared/esc.js";
3
+ export function listChatsScript(limit) {
4
+ return `
5
+ const Messages = Application('Messages');
6
+ const chats = Messages.chats();
7
+ const count = Math.min(chats.length, ${limit});
8
+ const result = [];
9
+ for (let i = 0; i < count; i++) {
10
+ const c = chats[i];
11
+ let parts = [];
12
+ try {
13
+ const participants = c.participants();
14
+ parts = participants.map(p => {
15
+ let name = null, handle = null;
16
+ try { name = p.name(); } catch(e) {}
17
+ try { handle = p.handle(); } catch(e) {}
18
+ return {name, handle};
19
+ });
20
+ } catch(e) {}
21
+ let updated = null;
22
+ try { updated = c.updatedDate() ? c.updatedDate().toISOString() : null; } catch(e) {}
23
+ result.push({
24
+ id: c.id(),
25
+ name: c.name() || null,
26
+ participants: parts,
27
+ updated: updated
28
+ });
29
+ }
30
+ JSON.stringify({total: chats.length, returned: count, chats: result});
31
+ `;
32
+ }
33
+ export function readChatScript(chatId) {
34
+ return `
35
+ const Messages = Application('Messages');
36
+ const chats = Messages.chats.whose({id: '${esc(chatId)}'})();
37
+ if (chats.length === 0) throw new Error('Chat not found: ${esc(chatId)}');
38
+ const chat = chats[0];
39
+ let parts = [];
40
+ try {
41
+ const participants = chat.participants();
42
+ parts = participants.map(p => {
43
+ let name = null, handle = null;
44
+ try { name = p.name(); } catch(e) {}
45
+ try { handle = p.handle(); } catch(e) {}
46
+ return {name, handle};
47
+ });
48
+ } catch(e) {}
49
+ let updated = null;
50
+ try { updated = chat.updatedDate() ? chat.updatedDate().toISOString() : null; } catch(e) {}
51
+ JSON.stringify({
52
+ id: chat.id(),
53
+ name: chat.name() || null,
54
+ participants: parts,
55
+ updated: updated
56
+ });
57
+ `;
58
+ }
59
+ export function searchMessagesScript(query, limit) {
60
+ return `
61
+ const Messages = Application('Messages');
62
+ const chats = Messages.chats();
63
+ const q = '${esc(query)}'.toLowerCase();
64
+ const result = [];
65
+ for (const chat of chats) {
66
+ if (result.length >= ${limit}) break;
67
+ const name = chat.name() || '';
68
+ let parts = [];
69
+ let participantNames = '';
70
+ let participantHandles = '';
71
+ try {
72
+ const participants = chat.participants();
73
+ parts = participants.map(p => {
74
+ let pn = null, ph = null;
75
+ try { pn = p.name(); } catch(e) {}
76
+ try { ph = p.handle(); } catch(e) {}
77
+ return {name: pn, handle: ph};
78
+ });
79
+ participantNames = parts.map(p => p.name || '').join(' ');
80
+ participantHandles = parts.map(p => p.handle || '').join(' ');
81
+ } catch(e) {}
82
+ if (name.toLowerCase().includes(q) ||
83
+ participantNames.toLowerCase().includes(q) ||
84
+ participantHandles.toLowerCase().includes(q)) {
85
+ let updated = null;
86
+ try { updated = chat.updatedDate() ? chat.updatedDate().toISOString() : null; } catch(e) {}
87
+ result.push({
88
+ id: chat.id(),
89
+ name: name || null,
90
+ participants: parts,
91
+ updated: updated
92
+ });
93
+ }
94
+ }
95
+ JSON.stringify({returned: result.length, chats: result});
96
+ `;
97
+ }
98
+ export function sendMessageScript(target, text) {
99
+ return `
100
+ const Messages = Application('Messages');
101
+ const service = Messages.services().find(s => s.serviceType() === 'iMessage') || Messages.services()[0];
102
+ if (!service) throw new Error('No messaging service available');
103
+ const buddy = service.buddies.whose({handle: '${esc(target)}'})();
104
+ if (buddy.length === 0) throw new Error('Buddy not found for handle: ${esc(target)}');
105
+ Messages.send('${esc(text)}', {to: buddy[0]});
106
+ JSON.stringify({sent: true, to: '${esc(target)}', text: '${esc(text)}'.substring(0, 100)});
107
+ `;
108
+ }
109
+ export function sendFileScript(target, filePath) {
110
+ return `
111
+ const Messages = Application('Messages');
112
+ const service = Messages.services().find(s => s.serviceType() === 'iMessage') || Messages.services()[0];
113
+ if (!service) throw new Error('No messaging service available');
114
+ const buddy = service.buddies.whose({handle: '${esc(target)}'})();
115
+ if (buddy.length === 0) throw new Error('Buddy not found for handle: ${esc(target)}');
116
+ const file = Path('${esc(filePath)}');
117
+ Messages.send(file, {to: buddy[0]});
118
+ JSON.stringify({sent: true, to: '${esc(target)}', file: '${esc(filePath)}'});
119
+ `;
120
+ }
121
+ export function listParticipantsScript(chatId) {
122
+ return `
123
+ const Messages = Application('Messages');
124
+ const chats = Messages.chats.whose({id: '${esc(chatId)}'})();
125
+ if (chats.length === 0) throw new Error('Chat not found: ${esc(chatId)}');
126
+ const chat = chats[0];
127
+ let result = [];
128
+ try {
129
+ const participants = chat.participants();
130
+ result = participants.map(p => {
131
+ let name = null, handle = null;
132
+ try { name = p.name(); } catch(e) {}
133
+ try { handle = p.handle(); } catch(e) {}
134
+ return {name, handle};
135
+ });
136
+ } catch(e) {}
137
+ JSON.stringify({chatId: '${esc(chatId)}', chatName: chat.name() || null, participants: result});
138
+ `;
139
+ }
140
+ //# sourceMappingURL=scripts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripts.js","sourceRoot":"","sources":["../../src/messages/scripts.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAE7C,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAEvC,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO;;;2CAGkC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;GAwB7C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO;;+CAEsC,GAAG,CAAC,MAAM,CAAC;+DACK,GAAG,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;GAoBvE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAAa,EACb,KAAa;IAEb,OAAO;;;iBAGQ,GAAG,CAAC,KAAK,CAAC;;;6BAGE,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8B/B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,MAAc,EACd,IAAY;IAEZ,OAAO;;;;oDAI2C,GAAG,CAAC,MAAM,CAAC;2EACY,GAAG,CAAC,MAAM,CAAC;qBACjE,GAAG,CAAC,IAAI,CAAC;uCACS,GAAG,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC;GACrE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,QAAgB;IAEhB,OAAO;;;;oDAI2C,GAAG,CAAC,MAAM,CAAC;2EACY,GAAG,CAAC,MAAM,CAAC;yBAC7D,GAAG,CAAC,QAAQ,CAAC;;uCAEC,GAAG,CAAC,MAAM,CAAC,aAAa,GAAG,CAAC,QAAQ,CAAC;GACzE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,OAAO;;+CAEsC,GAAG,CAAC,MAAM,CAAC;+DACK,GAAG,CAAC,MAAM,CAAC;;;;;;;;;;;;+BAY3C,GAAG,CAAC,MAAM,CAAC;GACvC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { AirMcpConfig } from "../shared/config.js";
3
+ export declare function registerMessagesTools(server: McpServer, config: AirMcpConfig): void;
@@ -0,0 +1,105 @@
1
+ import { z } from "zod";
2
+ import { runJxa } from "../shared/jxa.js";
3
+ import { ok, err } from "../shared/result.js";
4
+ import { listChatsScript, readChatScript, searchMessagesScript, sendMessageScript, sendFileScript, listParticipantsScript, } from "./scripts.js";
5
+ export function registerMessagesTools(server, config) {
6
+ const { allowSendMessages } = config;
7
+ server.registerTool("list_chats", {
8
+ title: "List Chats",
9
+ description: "List recent chats in Messages with participants and last update time.",
10
+ inputSchema: {
11
+ limit: z.number().int().min(1).max(200).optional().default(50).describe("Max chats to return (default: 50)"),
12
+ },
13
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
14
+ }, async ({ limit }) => {
15
+ try {
16
+ return ok(await runJxa(listChatsScript(limit)));
17
+ }
18
+ catch (e) {
19
+ return err(`Failed to list chats: ${e instanceof Error ? e.message : String(e)}`);
20
+ }
21
+ });
22
+ server.registerTool("read_chat", {
23
+ title: "Read Chat",
24
+ description: "Read chat details including participants and last update time by chat ID.",
25
+ inputSchema: {
26
+ chatId: z.string().describe("Chat ID"),
27
+ },
28
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
29
+ }, async ({ chatId }) => {
30
+ try {
31
+ return ok(await runJxa(readChatScript(chatId)));
32
+ }
33
+ catch (e) {
34
+ return err(`Failed to read chat: ${e instanceof Error ? e.message : String(e)}`);
35
+ }
36
+ });
37
+ server.registerTool("search_chats", {
38
+ title: "Search Chats",
39
+ description: "Search chats by participant name, handle, or chat name.",
40
+ inputSchema: {
41
+ query: z.string().describe("Search keyword (matches chat name, participant name, or handle)"),
42
+ limit: z.number().int().min(1).max(100).optional().default(20).describe("Max results (default: 20)"),
43
+ },
44
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
45
+ }, async ({ query, limit }) => {
46
+ try {
47
+ return ok(await runJxa(searchMessagesScript(query, limit)));
48
+ }
49
+ catch (e) {
50
+ return err(`Failed to search chats: ${e instanceof Error ? e.message : String(e)}`);
51
+ }
52
+ });
53
+ server.registerTool("send_message", {
54
+ title: "Send Message",
55
+ description: "Send a text message via iMessage/SMS. Requires a phone number or email as the target handle.",
56
+ inputSchema: {
57
+ target: z.string().min(1).describe("Recipient handle (phone number or email, e.g. '+821012345678' or 'user@example.com')"),
58
+ text: z.string().min(1).max(10000).describe("Message text to send"),
59
+ },
60
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
61
+ }, async ({ target, text }) => {
62
+ if (!allowSendMessages)
63
+ return err("Sending messages is disabled. Set AIRMCP_ALLOW_SEND_MESSAGES=true to enable.");
64
+ try {
65
+ return ok(await runJxa(sendMessageScript(target, text)));
66
+ }
67
+ catch (e) {
68
+ return err(`Failed to send message: ${e instanceof Error ? e.message : String(e)}`);
69
+ }
70
+ });
71
+ server.registerTool("send_file", {
72
+ title: "Send File",
73
+ description: "Send a file attachment via iMessage/SMS. Requires absolute file path and recipient handle.",
74
+ inputSchema: {
75
+ target: z.string().min(1).describe("Recipient handle (phone number or email)"),
76
+ filePath: z.string().min(1).describe("Absolute file path to send"),
77
+ },
78
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
79
+ }, async ({ target, filePath }) => {
80
+ if (!allowSendMessages)
81
+ return err("Sending messages is disabled. Set AIRMCP_ALLOW_SEND_MESSAGES=true to enable.");
82
+ try {
83
+ return ok(await runJxa(sendFileScript(target, filePath)));
84
+ }
85
+ catch (e) {
86
+ return err(`Failed to send file: ${e instanceof Error ? e.message : String(e)}`);
87
+ }
88
+ });
89
+ server.registerTool("list_participants", {
90
+ title: "List Chat Participants",
91
+ description: "List all participants in a specific chat.",
92
+ inputSchema: {
93
+ chatId: z.string().describe("Chat ID"),
94
+ },
95
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
96
+ }, async ({ chatId }) => {
97
+ try {
98
+ return ok(await runJxa(listParticipantsScript(chatId)));
99
+ }
100
+ catch (e) {
101
+ return err(`Failed to list participants: ${e instanceof Error ? e.message : String(e)}`);
102
+ }
103
+ });
104
+ }
105
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/messages/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export declare function listPlaylistsScript(): string;
2
+ export declare function listTracksScript(playlist: string, limit: number): string;
3
+ export declare function nowPlayingScript(): string;
4
+ export declare function playbackControlScript(action: string): string;
5
+ export declare function searchTracksScript(query: string, limit: number): string;
6
+ export declare function playTrackScript(trackName: string, playlist?: string): string;
7
+ export declare function playPlaylistScript(name: string, shuffle?: boolean): string;
8
+ export declare function getTrackInfoScript(trackName: string): string;
9
+ export declare function setShuffleScript(shuffle?: boolean, songRepeat?: string): string;
10
+ export declare function createPlaylistScript(name: string): string;
11
+ export declare function addToPlaylistScript(playlistName: string, trackName: string): string;
12
+ export declare function removeFromPlaylistScript(playlistName: string, trackName: string): string;
13
+ export declare function deletePlaylistScript(name: string): string;
@@ -0,0 +1,218 @@
1
+ // JXA scripts for Apple Music automation.
2
+ import { esc } from "../shared/esc.js";
3
+ export function listPlaylistsScript() {
4
+ return `
5
+ const Music = Application('Music');
6
+ const names = Music.playlists.name();
7
+ const ids = Music.playlists.id();
8
+ const durations = Music.playlists.duration();
9
+ const result = names.map((name, i) => ({
10
+ id: ids[i],
11
+ name: name,
12
+ duration: durations[i],
13
+ trackCount: Music.playlists[i].tracks.length
14
+ }));
15
+ JSON.stringify(result);
16
+ `;
17
+ }
18
+ export function listTracksScript(playlist, limit) {
19
+ return `
20
+ const Music = Application('Music');
21
+ const playlists = Music.playlists.whose({name: '${esc(playlist)}'})();
22
+ if (playlists.length === 0) throw new Error('Playlist not found: ${esc(playlist)}');
23
+ const pl = playlists[0];
24
+ const tracks = pl.tracks();
25
+ const count = Math.min(tracks.length, ${limit});
26
+ const result = [];
27
+ for (let i = 0; i < count; i++) {
28
+ const t = tracks[i];
29
+ result.push({
30
+ id: t.id(),
31
+ name: t.name(),
32
+ artist: t.artist(),
33
+ album: t.album(),
34
+ duration: t.duration(),
35
+ trackNumber: t.trackNumber(),
36
+ genre: t.genre(),
37
+ year: t.year()
38
+ });
39
+ }
40
+ JSON.stringify({total: tracks.length, returned: count, tracks: result});
41
+ `;
42
+ }
43
+ export function nowPlayingScript() {
44
+ return `
45
+ const Music = Application('Music');
46
+ const state = Music.playerState();
47
+ if (state === 'stopped') {
48
+ JSON.stringify({playerState: 'stopped', track: null});
49
+ } else {
50
+ const t = Music.currentTrack;
51
+ JSON.stringify({
52
+ playerState: state,
53
+ track: {
54
+ name: t.name(),
55
+ artist: t.artist(),
56
+ album: t.album(),
57
+ duration: t.duration(),
58
+ playerPosition: Music.playerPosition()
59
+ }
60
+ });
61
+ }
62
+ `;
63
+ }
64
+ const ALLOWED_ACTIONS = new Set(["play", "pause", "nextTrack", "previousTrack"]);
65
+ export function playbackControlScript(action) {
66
+ if (!ALLOWED_ACTIONS.has(action)) {
67
+ throw new Error(`Invalid playback action: ${action}`);
68
+ }
69
+ return `
70
+ const Music = Application('Music');
71
+ Music.${action}();
72
+ const state = Music.playerState();
73
+ JSON.stringify({action: '${action}', playerState: state});
74
+ `;
75
+ }
76
+ export function searchTracksScript(query, limit) {
77
+ return `
78
+ const Music = Application('Music');
79
+ const lib = Music.playlists.whose({name: 'Library'})();
80
+ if (lib.length === 0) {
81
+ JSON.stringify({returned: 0, tracks: []});
82
+ } else {
83
+ const tracks = lib[0].tracks();
84
+ const q = '${esc(query)}'.toLowerCase();
85
+ const result = [];
86
+ for (let i = 0; i < tracks.length && result.length < ${limit}; i++) {
87
+ const name = tracks[i].name() || '';
88
+ const artist = tracks[i].artist() || '';
89
+ const album = tracks[i].album() || '';
90
+ if (name.toLowerCase().includes(q) || artist.toLowerCase().includes(q) || album.toLowerCase().includes(q)) {
91
+ result.push({
92
+ id: tracks[i].id(),
93
+ name: name,
94
+ artist: artist,
95
+ album: album,
96
+ duration: tracks[i].duration()
97
+ });
98
+ }
99
+ }
100
+ JSON.stringify({returned: result.length, tracks: result});
101
+ }
102
+ `;
103
+ }
104
+ export function playTrackScript(trackName, playlist) {
105
+ if (playlist) {
106
+ return `
107
+ const Music = Application('Music');
108
+ const pls = Music.playlists.whose({name: '${esc(playlist)}'})();
109
+ if (pls.length === 0) throw new Error('Playlist not found: ${esc(playlist)}');
110
+ const tracks = pls[0].tracks.whose({name: '${esc(trackName)}'})();
111
+ if (tracks.length === 0) throw new Error('Track not found: ${esc(trackName)}');
112
+ tracks[0].play();
113
+ JSON.stringify({playing: true, track: tracks[0].name(), artist: tracks[0].artist()});
114
+ `;
115
+ }
116
+ return `
117
+ const Music = Application('Music');
118
+ const lib = Music.playlists.whose({name: 'Library'})();
119
+ if (lib.length === 0) throw new Error('Library not found');
120
+ const tracks = lib[0].tracks.whose({name: '${esc(trackName)}'})();
121
+ if (tracks.length === 0) throw new Error('Track not found: ${esc(trackName)}');
122
+ tracks[0].play();
123
+ JSON.stringify({playing: true, track: tracks[0].name(), artist: tracks[0].artist()});
124
+ `;
125
+ }
126
+ export function playPlaylistScript(name, shuffle) {
127
+ return `
128
+ const Music = Application('Music');
129
+ const pls = Music.playlists.whose({name: '${esc(name)}'})();
130
+ if (pls.length === 0) throw new Error('Playlist not found: ${esc(name)}');
131
+ ${shuffle !== undefined ? `Music.shuffleEnabled = ${shuffle};` : ''}
132
+ pls[0].play();
133
+ JSON.stringify({playing: true, playlist: '${esc(name)}', shuffle: Music.shuffleEnabled()});
134
+ `;
135
+ }
136
+ export function getTrackInfoScript(trackName) {
137
+ return `
138
+ const Music = Application('Music');
139
+ const lib = Music.playlists.whose({name: 'Library'})();
140
+ if (lib.length === 0) throw new Error('Library not found');
141
+ const tracks = lib[0].tracks.whose({name: '${esc(trackName)}'})();
142
+ if (tracks.length === 0) throw new Error('Track not found: ${esc(trackName)}');
143
+ const t = tracks[0];
144
+ JSON.stringify({
145
+ id: t.id(),
146
+ name: t.name(),
147
+ artist: t.artist(),
148
+ album: t.album(),
149
+ albumArtist: t.albumArtist(),
150
+ genre: t.genre(),
151
+ year: t.year(),
152
+ trackNumber: t.trackNumber(),
153
+ discNumber: t.discNumber(),
154
+ duration: t.duration(),
155
+ playedCount: t.playedCount(),
156
+ rating: t.rating(),
157
+ loved: t.loved(),
158
+ dateAdded: t.dateAdded() ? t.dateAdded().toISOString() : null,
159
+ sampleRate: t.sampleRate(),
160
+ bitRate: t.bitRate(),
161
+ size: t.size()
162
+ });
163
+ `;
164
+ }
165
+ export function setShuffleScript(shuffle, songRepeat) {
166
+ const lines = [];
167
+ if (shuffle !== undefined)
168
+ lines.push(`Music.shuffleEnabled = ${shuffle};`);
169
+ if (songRepeat !== undefined)
170
+ lines.push(`Music.songRepeat = '${esc(songRepeat)}';`);
171
+ return `
172
+ const Music = Application('Music');
173
+ ${lines.join('\n ')}
174
+ JSON.stringify({
175
+ shuffleEnabled: Music.shuffleEnabled(),
176
+ songRepeat: Music.songRepeat()
177
+ });
178
+ `;
179
+ }
180
+ export function createPlaylistScript(name) {
181
+ return `
182
+ const Music = Application('Music');
183
+ const pl = Music.make({new: 'playlist', withProperties: {name: '${esc(name)}'}});
184
+ JSON.stringify({name: pl.name(), id: pl.id()});
185
+ `;
186
+ }
187
+ export function addToPlaylistScript(playlistName, trackName) {
188
+ return `
189
+ const Music = Application('Music');
190
+ const pls = Music.playlists.whose({name: '${esc(playlistName)}'})();
191
+ if (pls.length === 0) throw new Error('Playlist not found: ${esc(playlistName)}');
192
+ const tracks = Music.tracks.whose({name: '${esc(trackName)}'})();
193
+ if (tracks.length === 0) throw new Error('Track not found: ${esc(trackName)}');
194
+ Music.duplicate(tracks[0], {to: pls[0]});
195
+ JSON.stringify({added: true, track: '${esc(trackName)}', playlist: '${esc(playlistName)}'});
196
+ `;
197
+ }
198
+ export function removeFromPlaylistScript(playlistName, trackName) {
199
+ return `
200
+ const Music = Application('Music');
201
+ const pls = Music.playlists.whose({name: '${esc(playlistName)}'})();
202
+ if (pls.length === 0) throw new Error('Playlist not found: ${esc(playlistName)}');
203
+ const tracks = pls[0].tracks.whose({name: '${esc(trackName)}'})();
204
+ if (tracks.length === 0) throw new Error('Track not found: ${esc(trackName)}');
205
+ tracks[0].delete();
206
+ JSON.stringify({removed: true, track: '${esc(trackName)}', playlist: '${esc(playlistName)}'});
207
+ `;
208
+ }
209
+ export function deletePlaylistScript(name) {
210
+ return `
211
+ const Music = Application('Music');
212
+ const pls = Music.playlists.whose({name: '${esc(name)}'})();
213
+ if (pls.length === 0) throw new Error('Playlist not found: ${esc(name)}');
214
+ pls[0].delete();
215
+ JSON.stringify({deleted: true, playlist: '${esc(name)}'});
216
+ `;
217
+ }
218
+ //# sourceMappingURL=scripts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripts.js","sourceRoot":"","sources":["../../src/music/scripts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { AirMcpConfig } from "../shared/config.js";
3
+ export declare function registerMusicTools(server: McpServer, _config: AirMcpConfig): void;