imsg-mcp 1.3.1 → 1.3.2

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/dist/index.js CHANGED
@@ -6,14 +6,14 @@ import { promisify } from "node:util";
6
6
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
7
7
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8
8
  import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ReadResourceRequestSchema } from "@modelcontextprotocol/sdk/types.js";
9
- import { c as checkLocalAccess, f as formatAccessReport, s as shutdown, g as getImsgDbPath, a as getContactsDbPaths, b as getSlugsDbPath, d as appendLog, e as getFileLogLines, h as getLogDirectory, p as perf, i as checkMessagesAvailable, j as sendToChat, k as sendToChatId, l as sendMessageReliable, m as sendMessageAlt, n as sendAttachment, o as checkImessageAvailability, q as installShutdownHandlers, r as registerCleanup, t as enableStdinEofDetection, u as enableOrphanWatchdog, v as logStartup, w as info, x as startHeapMonitor, y as getLogs, z as setLastSendError, A as logShutdown, B as stopHeapMonitor, C as getLogFilePath, D as getLastSendError } from "./shutdown-CikCSZru.js";
10
- import { m as minMessageId, r as resolveRecipient, d as defaultCountryFromEnv, a as rankFuzzy, b as dispatchAnalytic, i as installWatchdog, n as noteActivity, c as readWatchdogState } from "./watchdog-CnbBZnfg.js";
9
+ import { c as checkLocalAccess, f as formatAccessReport, s as shutdown, g as getImsgDbPath, a as getContactsDbPaths, b as getSlugsDbPath, d as appendLog, e as getFileLogLines, h as getLogDirectory, p as perf, i as checkMessagesAvailable, j as sendToChat, k as sendToChatId, l as sendMessageReliable, m as sendMessageAlt, n as sendAttachment, o as checkImessageAvailability, q as installShutdownHandlers, r as registerCleanup, t as enableStdinEofDetection, u as enableOrphanWatchdog, v as logStartup, w as info, x as startHeapMonitor, y as getLogs, z as setLastSendError, A as logShutdown, B as stopHeapMonitor, C as getLogFilePath, D as getLastSendError } from "./shutdown-pPAPSnk3.js";
10
+ import { m as minMessageId, r as resolveRecipient, d as defaultCountryFromEnv, a as rankFuzzy, b as dispatchAnalytic, i as installWatchdog, n as noteActivity, c as readWatchdogState } from "./watchdog-Cbgm050b.js";
11
11
  import { homedir } from "node:os";
12
12
  import Database from "better-sqlite3";
13
- import { I as IMessageDB, n as normalizedPhoneVariants, h as hasNativeModule } from "./imessage-db-vDZF7E8B.js";
13
+ import { I as IMessageDB, n as normalizedPhoneVariants, h as hasNativeModule } from "./imessage-db-Cz8MIIpG.js";
14
14
  import { streamExport } from "./exportStream-BCoZYUUZ.js";
15
15
  import { z } from "zod";
16
- import { A as APP_VERSION, a as APP_NAME } from "./meta-DCZ9Xe9g.js";
16
+ import { A as APP_VERSION, a as APP_NAME } from "./meta-DzE7CSrZ.js";
17
17
  import { randomUUID } from "node:crypto";
18
18
  import { parseUserDate } from "./dateParse-DJXMfq3a.js";
19
19
  const DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
@@ -1966,7 +1966,7 @@ const TOOLS = [
1966
1966
  },
1967
1967
  {
1968
1968
  name: "check_imessage_availability",
1969
- description: "Preflight check: is this handle reachable via iMessage or SMS? Call BEFORE send_message to avoid wasted send attempts to unreachable recipients. Returns the best-guess service plus a human-readable hint when unreachable.",
1969
+ description: "Preflight check: is this handle reachable via iMessage or SMS? Authoritative when a conversation with the handle already exists (service comes from chat.db history); best-effort otherwise (Messages.app cannot verify iMessage registration without sending). send_message routes on the same ground truth automatically, so this is mainly useful for never-messaged handles and format validation.",
1970
1970
  annotations: annotations.status,
1971
1971
  inputSchema: {
1972
1972
  type: "object",
@@ -2757,6 +2757,7 @@ Call again with one of the contact:N labels.`,
2757
2757
  normalizedRecipient = resolution.handle;
2758
2758
  resolvedTarget = resolution.handle;
2759
2759
  }
2760
+ let preferredService;
2760
2761
  if (threadSlug) {
2761
2762
  const slugRecord = this.db.getSlugRecord(threadSlug);
2762
2763
  if (!slugRecord) {
@@ -2765,6 +2766,7 @@ Call again with one of the contact:N labels.`,
2765
2766
  {}
2766
2767
  );
2767
2768
  }
2769
+ preferredService = slugRecord.service === "SMS" ? "SMS" : "iMessage";
2768
2770
  if (slugRecord.isGroup) {
2769
2771
  if (slugRecord.displayName && !slugRecord.displayName.startsWith("chat")) {
2770
2772
  result = await sendToChat(slugRecord.displayName, message);
@@ -2772,14 +2774,18 @@ Call again with one of the contact:N labels.`,
2772
2774
  result = await sendToChatId(slugRecord.chatGuid, message);
2773
2775
  }
2774
2776
  } else {
2775
- result = await sendMessageReliable(slugRecord.chatIdentifier, message);
2777
+ result = await sendMessageReliable(slugRecord.chatIdentifier, message, preferredService);
2776
2778
  if (!result.success) {
2777
2779
  result = await sendMessageAlt(slugRecord.chatIdentifier, message);
2778
2780
  }
2779
2781
  }
2780
2782
  resolvedTarget = slugRecord.displayName || slugRecord.chatIdentifier;
2781
2783
  } else {
2782
- result = await sendMessageReliable(normalizedRecipient, message);
2784
+ const existingChat = await this.db.findChatByHandle(normalizedRecipient);
2785
+ if (existingChat && !existingChat.isGroupChat) {
2786
+ preferredService = existingChat.serviceType === "SMS" ? "SMS" : "iMessage";
2787
+ }
2788
+ result = await sendMessageReliable(normalizedRecipient, message, preferredService);
2783
2789
  if (!result.success) {
2784
2790
  result = await sendMessageAlt(normalizedRecipient, message);
2785
2791
  }
@@ -2787,7 +2793,7 @@ Call again with one of the contact:N labels.`,
2787
2793
  if (result.success) {
2788
2794
  const attachmentResults = [];
2789
2795
  if (attachments?.length) {
2790
- const targetHandle = threadSlug ? this.db.getSlugRecord(threadSlug)?.chatIdentifier : recipient;
2796
+ const targetHandle = threadSlug ? this.db.getSlugRecord(threadSlug)?.chatIdentifier : normalizedRecipient;
2791
2797
  const isGroupTarget = threadSlug ? Boolean(this.db.getSlugRecord(threadSlug)?.isGroup) : false;
2792
2798
  if (isGroupTarget) {
2793
2799
  for (const p of attachments) {
@@ -2799,7 +2805,7 @@ Call again with one of the contact:N labels.`,
2799
2805
  }
2800
2806
  } else if (targetHandle) {
2801
2807
  for (const p of attachments) {
2802
- const r = await sendAttachment(targetHandle, p);
2808
+ const r = await sendAttachment(targetHandle, p, preferredService);
2803
2809
  attachmentResults.push({
2804
2810
  path: p,
2805
2811
  success: r.success,
@@ -3132,8 +3138,18 @@ ${withThreads.map((t) => ` ${t.handle} → ${t.threadSlug}`).join("\n")}` : "";
3132
3138
  const { handle } = CheckImessageAvailabilitySchema.parse(args);
3133
3139
  const selectorHit = resolveContactSelector(handle);
3134
3140
  const effectiveHandle = selectorHit?.handle ?? handle;
3141
+ const existingChat = await this.db.findChatByHandle(effectiveHandle);
3142
+ if (existingChat && !existingChat.isGroupChat) {
3143
+ const service = existingChat.serviceType === "SMS" ? "SMS" : "iMessage";
3144
+ return toolText(`${handle} reachable via ${service} (existing conversation).`, {
3145
+ handle,
3146
+ service,
3147
+ reachable: true,
3148
+ hint: "Derived from existing conversation history — authoritative. send_message will route on this service."
3149
+ });
3150
+ }
3135
3151
  const result = await checkImessageAvailability(effectiveHandle);
3136
- const text = result.reachable ? `${handle} reachable via ${result.service}.` : `${handle} not reachable. ${result.hint ?? ""}`.trim();
3152
+ const text = result.reachable ? `${handle} reachable via ${result.service} (best-effort probe — no conversation history for this handle; Messages.app cannot verify iMessage registration without sending).` : `${handle} not reachable. ${result.hint ?? ""}`.trim();
3137
3153
  return toolText(text, {
3138
3154
  handle,
3139
3155
  service: result.service,