@heznpc/imcp 0.8.0 → 0.9.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.
package/README.ko.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # iMcp
2
2
 
3
- Apple 생태계 전체를 위한 MCP 서버 — Notes, Reminders, Calendar, Contacts, Mail, Music, Finder, Safari, System, Photos, Shortcuts, Apple Intelligence. AI를 Mac에 연결합니다.
3
+ Apple 생태계 전체를 위한 MCP 서버 — Notes, Reminders, Calendar, Contacts, Mail, Messages, Music, Finder, Safari, System, Photos, Shortcuts, Apple Intelligence. AI를 Mac에 연결합니다.
4
4
 
5
5
  > [English](README.md)
6
6
 
7
7
  ## 특징
8
8
 
9
- - **104개 도구** (12개 모듈) — Apple 앱 CRUD + 시스템 제어 + Apple Intelligence
9
+ - **110개 도구** (13개 모듈) — Apple 앱 CRUD + 시스템 제어 + Apple Intelligence
10
10
  - **20개 프롬프트** — 앱별 워크플로우 + 크로스 모듈 + 개발자 워크플로우 (dev-session, debug-loop, build-log)
11
11
  - **4개 MCP 리소스** — Notes, Calendar, Reminders 실시간 데이터 URI
12
12
  - **JXA + Swift 브릿지** — JXA로 기본 자동화, EventKit/PhotoKit으로 고급 기능
@@ -209,6 +209,17 @@ cd app && swift build -c release
209
209
  | `import_photo` | 파일에서 사진 가져오기 (Swift/PhotoKit) | 쓰기 |
210
210
  | `delete_photos` | ID로 사진 삭제 (Swift/PhotoKit) | 파괴적 |
211
211
 
212
+ ### Messages (6개)
213
+
214
+ | 도구 | 설명 | 타입 |
215
+ |------|------|------|
216
+ | `list_chats` | 최근 대화 목록 (참여자 포함) | 읽기 |
217
+ | `read_chat` | 대화 상세 조회 (참여자, 마지막 업데이트 포함) | 읽기 |
218
+ | `search_chats` | 이름/참여자/핸들로 검색 | 읽기 |
219
+ | `send_message` | iMessage/SMS 텍스트 전송 | 쓰기 |
220
+ | `send_file` | iMessage/SMS 파일 첨부 전송 | 쓰기 |
221
+ | `list_participants` | 대화 참여자 목록 | 읽기 |
222
+
212
223
  ### Shortcuts (4개)
213
224
 
214
225
  | 도구 | 설명 | 타입 |
@@ -331,6 +342,10 @@ AI 코딩 에이전트(Claude Code, Cursor, Copilot)가 MCP 프롬프트로 호
331
342
  ### Mail
332
343
  - 내용 기본 5000자 제한 (`maxLength` 파라미터로 조절 가능)
333
344
 
345
+ ### Messages
346
+ - 개별 메시지 내용(대화 기록)은 JXA로 접근 불가
347
+ - 전송 시 수신자가 Messages 서비스에 등록된 buddy여야 함
348
+
334
349
  ### Music
335
350
  - 스마트 재생목록 읽기 전용
336
351
  - 대기열 조작 불가
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # iMcp
2
2
 
3
- MCP server for the entire Apple ecosystem — Notes, Reminders, Calendar, Contacts, Mail, Music, Finder, Safari, System, Photos, Shortcuts, and Apple Intelligence. Connect any AI to your Mac.
3
+ MCP server for the entire Apple ecosystem — Notes, Reminders, Calendar, Contacts, Mail, Messages, Music, Finder, Safari, System, Photos, Shortcuts, and Apple Intelligence. Connect any AI to your Mac.
4
4
 
5
5
  > [한국어](README.ko.md)
6
6
 
7
7
  ## Features
8
8
 
9
- - **104 tools** across 12 modules — full CRUD for Apple apps + system control + Apple Intelligence
9
+ - **110 tools** across 13 modules — full CRUD for Apple apps + system control + Apple Intelligence
10
10
  - **20 prompts** — per-app workflows + cross-module + developer workflows (dev-session, debug-loop, build-log)
11
11
  - **4 MCP Resources** — live data URIs for notes, calendar, and reminders
12
12
  - **JXA + Swift bridge** — JXA for core automation, EventKit/PhotoKit via Swift for advanced features
@@ -209,6 +209,17 @@ Features: server status indicator, one-click permission setup, copy Claude confi
209
209
  | `import_photo` | Import from file path (Swift/PhotoKit) | write |
210
210
  | `delete_photos` | Delete photos by ID (Swift/PhotoKit) | destructive |
211
211
 
212
+ ### Messages (6 tools)
213
+
214
+ | Tool | Description | Type |
215
+ |------|-------------|------|
216
+ | `list_chats` | List recent chats with participants | read |
217
+ | `read_chat` | Read chat details including participants and last update | read |
218
+ | `search_chats` | Search by name, participant, or handle | read |
219
+ | `send_message` | Send text via iMessage/SMS | write |
220
+ | `send_file` | Send file attachment via iMessage/SMS | write |
221
+ | `list_participants` | List participants in a chat | read |
222
+
212
223
  ### Shortcuts (4 tools)
213
224
 
214
225
  | Tool | Description | Type |
@@ -331,6 +342,10 @@ These prompts are designed for AI coding agents (Claude Code, Cursor, Copilot) t
331
342
  ### Mail
332
343
  - Content truncated to 5000 characters by default (configurable via `maxLength` parameter)
333
344
 
345
+ ### Messages
346
+ - Chat message history (individual message content) is not accessible via JXA
347
+ - Send requires the recipient to be a known buddy in the Messages service
348
+
334
349
  ### Music
335
350
  - Smart playlists are read-only
336
351
  - No queue manipulation
package/dist/index.js CHANGED
@@ -15,6 +15,7 @@ import { registerSafariTools } from "./safari/tools.js";
15
15
  import { registerSystemTools } from "./system/tools.js";
16
16
  import { registerPhotosTools } from "./photos/tools.js";
17
17
  import { registerShortcutsTools } from "./shortcuts/tools.js";
18
+ import { registerMessagesTools } from "./messages/tools.js";
18
19
  import { registerIntelligenceTools } from "./intelligence/tools.js";
19
20
  import { registerCrossPrompts } from "./cross/prompts.js";
20
21
  import { registerResources } from "./shared/resources.js";
@@ -23,7 +24,7 @@ import { parseConfig } from "./shared/config.js";
23
24
  const config = parseConfig();
24
25
  const server = new McpServer({
25
26
  name: "imcp",
26
- version: "0.8.0",
27
+ version: "0.9.0",
27
28
  });
28
29
  // Apple Apps
29
30
  registerNoteTools(server, config);
@@ -40,6 +41,7 @@ registerSafariTools(server, config);
40
41
  registerSystemTools(server, config);
41
42
  registerPhotosTools(server, config);
42
43
  registerShortcutsTools(server, config);
44
+ registerMessagesTools(server, config);
43
45
  // Apple Intelligence
44
46
  registerIntelligenceTools(server, config);
45
47
  // Cross-module workflows
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.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,103 @@
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
+ const participants = c.participants();
12
+ result.push({
13
+ id: c.id(),
14
+ name: c.name() || null,
15
+ participants: participants.map(p => ({
16
+ name: p.name(),
17
+ handle: p.handle()
18
+ })),
19
+ updated: c.updatedDate() ? c.updatedDate().toISOString() : null
20
+ });
21
+ }
22
+ JSON.stringify({total: chats.length, returned: count, chats: result});
23
+ `;
24
+ }
25
+ export function readChatScript(chatId) {
26
+ return `
27
+ const Messages = Application('Messages');
28
+ const chats = Messages.chats.whose({id: '${esc(chatId)}'})();
29
+ if (chats.length === 0) throw new Error('Chat not found: ${esc(chatId)}');
30
+ const chat = chats[0];
31
+ const participants = chat.participants();
32
+ JSON.stringify({
33
+ id: chat.id(),
34
+ name: chat.name() || null,
35
+ participants: participants.map(p => ({name: p.name(), handle: p.handle()})),
36
+ updated: chat.updatedDate() ? chat.updatedDate().toISOString() : null
37
+ });
38
+ `;
39
+ }
40
+ export function searchMessagesScript(query, limit) {
41
+ return `
42
+ const Messages = Application('Messages');
43
+ const chats = Messages.chats();
44
+ const q = '${esc(query)}'.toLowerCase();
45
+ const result = [];
46
+ for (const chat of chats) {
47
+ if (result.length >= ${limit}) break;
48
+ const name = chat.name() || '';
49
+ const participants = chat.participants();
50
+ const participantNames = participants.map(p => p.name() || '').join(' ');
51
+ const participantHandles = participants.map(p => p.handle() || '').join(' ');
52
+ if (name.toLowerCase().includes(q) ||
53
+ participantNames.toLowerCase().includes(q) ||
54
+ participantHandles.toLowerCase().includes(q)) {
55
+ result.push({
56
+ id: chat.id(),
57
+ name: name || null,
58
+ participants: participants.map(p => ({name: p.name(), handle: p.handle()})),
59
+ updated: chat.updatedDate() ? chat.updatedDate().toISOString() : null
60
+ });
61
+ }
62
+ }
63
+ JSON.stringify({returned: result.length, chats: result});
64
+ `;
65
+ }
66
+ export function sendMessageScript(target, text) {
67
+ return `
68
+ const Messages = Application('Messages');
69
+ const service = Messages.services().find(s => s.serviceType() === 'iMessage') || Messages.services()[0];
70
+ if (!service) throw new Error('No messaging service available');
71
+ const buddy = service.buddies.whose({handle: '${esc(target)}'})();
72
+ if (buddy.length === 0) throw new Error('Buddy not found for handle: ${esc(target)}');
73
+ Messages.send('${esc(text)}', {to: buddy[0]});
74
+ JSON.stringify({sent: true, to: '${esc(target)}', text: '${esc(text)}'.substring(0, 100)});
75
+ `;
76
+ }
77
+ export function sendFileScript(target, filePath) {
78
+ return `
79
+ const Messages = Application('Messages');
80
+ const service = Messages.services().find(s => s.serviceType() === 'iMessage') || Messages.services()[0];
81
+ if (!service) throw new Error('No messaging service available');
82
+ const buddy = service.buddies.whose({handle: '${esc(target)}'})();
83
+ if (buddy.length === 0) throw new Error('Buddy not found for handle: ${esc(target)}');
84
+ const file = Path('${esc(filePath)}');
85
+ Messages.send(file, {to: buddy[0]});
86
+ JSON.stringify({sent: true, to: '${esc(target)}', file: '${esc(filePath)}'});
87
+ `;
88
+ }
89
+ export function listParticipantsScript(chatId) {
90
+ return `
91
+ const Messages = Application('Messages');
92
+ const chats = Messages.chats.whose({id: '${esc(chatId)}'})();
93
+ if (chats.length === 0) throw new Error('Chat not found: ${esc(chatId)}');
94
+ const chat = chats[0];
95
+ const participants = chat.participants();
96
+ const result = participants.map(p => ({
97
+ name: p.name(),
98
+ handle: p.handle()
99
+ }));
100
+ JSON.stringify({chatId: '${esc(chatId)}', chatName: chat.name() || null, participants: result});
101
+ `;
102
+ }
103
+ //# 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;;;;;;;;;;;;;;;;GAgB7C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO;;+CAEsC,GAAG,CAAC,MAAM,CAAC;+DACK,GAAG,CAAC,MAAM,CAAC;;;;;;;;;GASvE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAAa,EACb,KAAa;IAEb,OAAO;;;iBAGQ,GAAG,CAAC,KAAK,CAAC;;;6BAGE,KAAK;;;;;;;;;;;;;;;;;GAiB/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;;;;;;;+BAO3C,GAAG,CAAC,MAAM,CAAC;GACvC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ImcpConfig } from "../shared/config.js";
3
+ export declare function registerMessagesTools(server: McpServer, _config: ImcpConfig): void;
@@ -0,0 +1,100 @@
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
+ server.registerTool("list_chats", {
7
+ title: "List Chats",
8
+ description: "List recent chats in Messages with participants and last update time.",
9
+ inputSchema: {
10
+ limit: z.number().int().min(1).max(200).optional().default(50).describe("Max chats to return (default: 50)"),
11
+ },
12
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
13
+ }, async ({ limit }) => {
14
+ try {
15
+ return ok(await runJxa(listChatsScript(limit)));
16
+ }
17
+ catch (e) {
18
+ return err(`Failed to list chats: ${e instanceof Error ? e.message : String(e)}`);
19
+ }
20
+ });
21
+ server.registerTool("read_chat", {
22
+ title: "Read Chat",
23
+ description: "Read chat details including participants and last update time by chat ID.",
24
+ inputSchema: {
25
+ chatId: z.string().describe("Chat ID"),
26
+ },
27
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
28
+ }, async ({ chatId }) => {
29
+ try {
30
+ return ok(await runJxa(readChatScript(chatId)));
31
+ }
32
+ catch (e) {
33
+ return err(`Failed to read chat: ${e instanceof Error ? e.message : String(e)}`);
34
+ }
35
+ });
36
+ server.registerTool("search_chats", {
37
+ title: "Search Chats",
38
+ description: "Search chats by participant name, handle, or chat name.",
39
+ inputSchema: {
40
+ query: z.string().describe("Search keyword (matches chat name, participant name, or handle)"),
41
+ limit: z.number().int().min(1).max(100).optional().default(20).describe("Max results (default: 20)"),
42
+ },
43
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
44
+ }, async ({ query, limit }) => {
45
+ try {
46
+ return ok(await runJxa(searchMessagesScript(query, limit)));
47
+ }
48
+ catch (e) {
49
+ return err(`Failed to search chats: ${e instanceof Error ? e.message : String(e)}`);
50
+ }
51
+ });
52
+ server.registerTool("send_message", {
53
+ title: "Send Message",
54
+ description: "Send a text message via iMessage/SMS. Requires a phone number or email as the target handle.",
55
+ inputSchema: {
56
+ target: z.string().describe("Recipient handle (phone number or email, e.g. '+821012345678' or 'user@example.com')"),
57
+ text: z.string().min(1).max(10000).describe("Message text to send"),
58
+ },
59
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
60
+ }, async ({ target, text }) => {
61
+ try {
62
+ return ok(await runJxa(sendMessageScript(target, text)));
63
+ }
64
+ catch (e) {
65
+ return err(`Failed to send message: ${e instanceof Error ? e.message : String(e)}`);
66
+ }
67
+ });
68
+ server.registerTool("send_file", {
69
+ title: "Send File",
70
+ description: "Send a file attachment via iMessage/SMS. Requires absolute file path and recipient handle.",
71
+ inputSchema: {
72
+ target: z.string().describe("Recipient handle (phone number or email)"),
73
+ filePath: z.string().describe("Absolute path to the file to send"),
74
+ },
75
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
76
+ }, async ({ target, filePath }) => {
77
+ try {
78
+ return ok(await runJxa(sendFileScript(target, filePath)));
79
+ }
80
+ catch (e) {
81
+ return err(`Failed to send file: ${e instanceof Error ? e.message : String(e)}`);
82
+ }
83
+ });
84
+ server.registerTool("list_participants", {
85
+ title: "List Chat Participants",
86
+ description: "List all participants in a specific chat.",
87
+ inputSchema: {
88
+ chatId: z.string().describe("Chat ID"),
89
+ },
90
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
91
+ }, async ({ chatId }) => {
92
+ try {
93
+ return ok(await runJxa(listParticipantsScript(chatId)));
94
+ }
95
+ catch (e) {
96
+ return err(`Failed to list participants: ${e instanceof Error ? e.message : String(e)}`);
97
+ }
98
+ });
99
+ }
100
+ //# 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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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@heznpc/imcp",
3
- "version": "0.8.0",
4
- "description": "MCP server for the entire Apple ecosystem — Notes, Reminders, Calendar, Contacts, Mail, Music, Finder, Safari, Photos, Shortcuts, System, and Apple Intelligence. Connect any AI to your Mac.",
3
+ "version": "0.9.0",
4
+ "description": "MCP server for the entire Apple ecosystem — Notes, Reminders, Calendar, Contacts, Mail, Messages, Music, Finder, Safari, Photos, Shortcuts, System, and Apple Intelligence. Connect any AI to your Mac.",
5
5
  "keywords": [
6
6
  "mcp",
7
7
  "model-context-protocol",
@@ -17,6 +17,8 @@
17
17
  "apple-contacts",
18
18
  "mail",
19
19
  "apple-mail",
20
+ "messages",
21
+ "imessage",
20
22
  "music",
21
23
  "apple-music",
22
24
  "finder",