apple-notes-mcp 2.6.2 → 2.6.4
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.md +2 -0
- package/build/index.js +55 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -362,6 +362,8 @@ Updates an existing note's content and/or title.
|
|
|
362
362
|
|
|
363
363
|
**Note:** Either `id` or `title` must be provided. Using `id` is recommended.
|
|
364
364
|
|
|
365
|
+
**Returns:** Confirmation with the note's visible title and, for ID-based updates, its ID. For HTML updates, the title comes from the first rendered line of `newContent`, matching Notes.app. The response also warns if the note is shared.
|
|
366
|
+
|
|
365
367
|
**Example - Using ID (recommended):**
|
|
366
368
|
```json
|
|
367
369
|
{
|
package/build/index.js
CHANGED
|
@@ -39565,12 +39565,24 @@ var AppleNotesManager = class {
|
|
|
39565
39565
|
set noteId to id of n
|
|
39566
39566
|
if seenIds does not contain noteId then
|
|
39567
39567
|
set end of seenIds to noteId
|
|
39568
|
+
try
|
|
39569
|
+
set noteCreated to creation date of n
|
|
39570
|
+
set createdParts to ${asDatePartsExpr("noteCreated")}
|
|
39571
|
+
on error
|
|
39572
|
+
set createdParts to ""
|
|
39573
|
+
end try
|
|
39574
|
+
try
|
|
39575
|
+
set noteModified to modification date of n
|
|
39576
|
+
set modifiedParts to ${asDatePartsExpr("noteModified")}
|
|
39577
|
+
on error
|
|
39578
|
+
set modifiedParts to ""
|
|
39579
|
+
end try
|
|
39568
39580
|
try
|
|
39569
39581
|
set noteFolder to name of container of n
|
|
39570
39582
|
on error
|
|
39571
39583
|
set noteFolder to "Notes"
|
|
39572
39584
|
end try
|
|
39573
|
-
set end of resultList to noteName & ${AS_FIELD_SEP} & noteId & ${AS_FIELD_SEP} & noteFolder${limitCheck}
|
|
39585
|
+
set end of resultList to noteName & ${AS_FIELD_SEP} & noteId & ${AS_FIELD_SEP} & noteFolder & ${AS_FIELD_SEP} & createdParts & ${AS_FIELD_SEP} & modifiedParts${limitCheck}
|
|
39574
39586
|
end if
|
|
39575
39587
|
end try
|
|
39576
39588
|
end repeat
|
|
@@ -39589,7 +39601,7 @@ var AppleNotesManager = class {
|
|
|
39589
39601
|
const notes = [];
|
|
39590
39602
|
const seenIds = /* @__PURE__ */ new Set();
|
|
39591
39603
|
for (const item of items) {
|
|
39592
|
-
const [title, id, folder2] = item.split(FIELD_SEP);
|
|
39604
|
+
const [title, id, folder2, created, modified] = item.split(FIELD_SEP);
|
|
39593
39605
|
if (!title?.trim()) continue;
|
|
39594
39606
|
const noteId = id?.trim() || generateFallbackId();
|
|
39595
39607
|
if (seenIds.has(noteId)) continue;
|
|
@@ -39600,8 +39612,8 @@ var AppleNotesManager = class {
|
|
|
39600
39612
|
content: "",
|
|
39601
39613
|
// Not fetched in search
|
|
39602
39614
|
tags: [],
|
|
39603
|
-
created:
|
|
39604
|
-
modified:
|
|
39615
|
+
created: parseAppleScriptDate(created ?? ""),
|
|
39616
|
+
modified: parseAppleScriptDate(modified ?? ""),
|
|
39605
39617
|
folder: folder2?.trim(),
|
|
39606
39618
|
account: targetAccount
|
|
39607
39619
|
});
|
|
@@ -41754,6 +41766,40 @@ function strippedImagesWarning(stripped) {
|
|
|
41754
41766
|
)} decoded) exceeded the per-image inline cap and ${stripped.strippedCount === 1 ? "was" : "were"} replaced with placeholders so the response stays within MCP message limits. The images are still in the note: use list-attachments with save-attachment or fetch-attachment to export them, or raise APPLE_NOTES_MCP_MAX_INLINE_IMAGE_BYTES.`;
|
|
41755
41767
|
}
|
|
41756
41768
|
|
|
41769
|
+
// src/utils/updateResponseTitle.ts
|
|
41770
|
+
var BLOCK_END_RE = /<\/(?:div|h[1-6]|p|li)>/gi;
|
|
41771
|
+
var BREAK_RE = /<br\s*\/?\s*>/gi;
|
|
41772
|
+
var TAG_RE = /<[^>]*>/g;
|
|
41773
|
+
var NON_RENDERED_BLOCK_RE = /<(script|style)\b[^>]*>[\s\S]*?(?:<\/\1>|$)/gi;
|
|
41774
|
+
function decodeHtmlEntities(text) {
|
|
41775
|
+
const decodeCodePoint = (match, value, radix) => {
|
|
41776
|
+
const codePoint = Number.parseInt(value, radix);
|
|
41777
|
+
if (!Number.isInteger(codePoint) || codePoint < 0 || codePoint > 1114111 || codePoint >= 55296 && codePoint <= 57343) {
|
|
41778
|
+
return match;
|
|
41779
|
+
}
|
|
41780
|
+
return String.fromCodePoint(codePoint);
|
|
41781
|
+
};
|
|
41782
|
+
return text.replace(/&#x([0-9a-f]+);?/gi, (match, hex) => decodeCodePoint(match, hex, 16)).replace(/&#([0-9]+);?/g, (match, decimal) => decodeCodePoint(match, decimal, 10)).replace(/ (?:;|(?![0-9a-z]))/gi, " ").replace(/"(?:;|(?![0-9a-z]))/gi, '"').replace(/&apos(?:;|(?![0-9a-z]))/gi, "'").replace(/<(?:;|(?![0-9a-z]))/gi, "<").replace(/>(?:;|(?![0-9a-z]))/gi, ">").replace(/&(?:;|(?![0-9a-z]))/gi, "&");
|
|
41783
|
+
}
|
|
41784
|
+
function firstVisibleHtmlLine(html) {
|
|
41785
|
+
let text = html;
|
|
41786
|
+
let previous;
|
|
41787
|
+
do {
|
|
41788
|
+
previous = text;
|
|
41789
|
+
text = text.replace(NON_RENDERED_BLOCK_RE, "");
|
|
41790
|
+
} while (text !== previous);
|
|
41791
|
+
text = text.replace(BREAK_RE, "\n").replace(BLOCK_END_RE, "\n");
|
|
41792
|
+
do {
|
|
41793
|
+
previous = text;
|
|
41794
|
+
text = text.replace(TAG_RE, "");
|
|
41795
|
+
} while (text !== previous);
|
|
41796
|
+
return decodeHtmlEntities(text).split(/[\r\n\u2028\u2029]+/).map((line) => line.replace(/\s+/g, " ").trim()).find(Boolean);
|
|
41797
|
+
}
|
|
41798
|
+
function resolveUpdateResponseTitle(currentTitle, newTitle, format, newContent) {
|
|
41799
|
+
if (format === "html") return firstVisibleHtmlLine(newContent) ?? currentTitle;
|
|
41800
|
+
return newTitle || currentTitle;
|
|
41801
|
+
}
|
|
41802
|
+
|
|
41757
41803
|
// src/tools/doctor.ts
|
|
41758
41804
|
import { spawnSync } from "child_process";
|
|
41759
41805
|
function runDoctor(manager) {
|
|
@@ -42389,7 +42435,9 @@ server.registerTool(
|
|
|
42389
42435
|
inputSchema: {
|
|
42390
42436
|
id: external_exports.string().max(MAX.ID).optional().describe("Note ID (preferred - more reliable than title)"),
|
|
42391
42437
|
title: external_exports.string().max(MAX.TITLE).optional().describe("Current note title (use id instead when available)"),
|
|
42392
|
-
newTitle: external_exports.string().max(MAX.TITLE).optional().describe(
|
|
42438
|
+
newTitle: external_exports.string().max(MAX.TITLE).optional().describe(
|
|
42439
|
+
"New title for plaintext updates. Ignored when format is 'html'; include the visible title as the first line of newContent instead."
|
|
42440
|
+
),
|
|
42393
42441
|
newContent: external_exports.string().min(1, "New content is required").max(MAX.CONTENT).describe(
|
|
42394
42442
|
"New note body. AppleScript cannot produce true Apple Notes checklists; checkbox inputs and `- [ ]` markdown do not render as checkable items. Use a plain list and convert in Notes.app with \u21E7\u2318L."
|
|
42395
42443
|
),
|
|
@@ -42418,7 +42466,7 @@ server.registerTool(
|
|
|
42418
42466
|
if (!success2) {
|
|
42419
42467
|
return errorResponse(`Failed to update note "${note2.title}"`);
|
|
42420
42468
|
}
|
|
42421
|
-
const displayTitle = newTitle
|
|
42469
|
+
const displayTitle = resolveUpdateResponseTitle(note2.title, newTitle, format, newContent);
|
|
42422
42470
|
const sharedWarning2 = note2.shared ? "\n\n\u26A0\uFE0F This note is shared with collaborators. Your changes will be visible to them." : "";
|
|
42423
42471
|
const checklistWarning2 = detectChecklistAttempt(newContent) ?? "";
|
|
42424
42472
|
return successResponse(`Note updated: "${displayTitle}"${sharedWarning2}${checklistWarning2}`, {
|
|
@@ -42446,7 +42494,7 @@ server.registerTool(
|
|
|
42446
42494
|
if (!success) {
|
|
42447
42495
|
return errorResponse(`Failed to update note "${title}"`);
|
|
42448
42496
|
}
|
|
42449
|
-
const finalTitle = newTitle
|
|
42497
|
+
const finalTitle = resolveUpdateResponseTitle(note.title, newTitle, format, newContent);
|
|
42450
42498
|
const sharedWarning = note.shared ? "\n\n\u26A0\uFE0F This note is shared with collaborators. Your changes will be visible to them." : "";
|
|
42451
42499
|
const checklistWarning = detectChecklistAttempt(newContent) ?? "";
|
|
42452
42500
|
return successResponse(`Note updated: "${finalTitle}"${sharedWarning}${checklistWarning}`, {
|
package/package.json
CHANGED