apple-notes-mcp 2.9.34 → 2.9.35
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 +4 -1
- package/build/index.js +36 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2097,7 +2097,10 @@ On macOS 27, Notes' AppleScript does not list PDF attachments, so it cannot see
|
|
|
2097
2097
|
a PDF this tool just added. When that happens and the server has Full Disk
|
|
2098
2098
|
Access, it verifies through the read-only NoteStore database instead: success
|
|
2099
2099
|
requires exactly one new attachment row on the note whose media file matches
|
|
2100
|
-
the source bytes,
|
|
2100
|
+
the source bytes, whose type fits the file's extension, and, when the decoded
|
|
2101
|
+
note body lists attachments, that the body references. The check repeats for
|
|
2102
|
+
about two seconds while Notes' database catches up, and `contentHash` is read
|
|
2103
|
+
after it finishes. The result carries `verifiedBy: "database"`. Without Full
|
|
2101
2104
|
Disk Access a PDF attach reports "insertion outcome uncertain"; read the note
|
|
2102
2105
|
before retrying, because the attachment was probably created.
|
|
2103
2106
|
|
package/build/index.js
CHANGED
|
@@ -54118,18 +54118,34 @@ function storedAttachmentIds(manager, id2) {
|
|
|
54118
54118
|
return null;
|
|
54119
54119
|
}
|
|
54120
54120
|
}
|
|
54121
|
-
|
|
54121
|
+
var KIND_BY_EXTENSION = {
|
|
54122
|
+
".pdf": "pdf",
|
|
54123
|
+
".png": "image",
|
|
54124
|
+
".jpg": "image",
|
|
54125
|
+
".jpeg": "image",
|
|
54126
|
+
".heic": "image",
|
|
54127
|
+
".tif": "image",
|
|
54128
|
+
".tiff": "image",
|
|
54129
|
+
".gif": "image"
|
|
54130
|
+
};
|
|
54131
|
+
function referencedByBody(assets, row) {
|
|
54132
|
+
return assets.orderSource === "body" ? row.bodyIndex !== null : void 0;
|
|
54133
|
+
}
|
|
54134
|
+
function storedInsertion(manager, id2, before, bytes, name, returnedId) {
|
|
54122
54135
|
let added = [];
|
|
54136
|
+
let assets;
|
|
54123
54137
|
for (let attempt = 0; attempt < 8; attempt++) {
|
|
54124
54138
|
if (attempt > 0) pause(250);
|
|
54125
54139
|
try {
|
|
54126
|
-
|
|
54140
|
+
assets = manager.getAttachmentAssetsById(id2);
|
|
54141
|
+
added = assets.attachments.filter(
|
|
54127
54142
|
(item) => item.parentIdentifier === null && !before.has(item.identifier.toLowerCase())
|
|
54128
54143
|
);
|
|
54129
54144
|
} catch {
|
|
54130
54145
|
added = [];
|
|
54131
54146
|
}
|
|
54132
|
-
if (added.length === 1 && added[0].assetPaths.length > 0)
|
|
54147
|
+
if (added.length === 1 && added[0].assetPaths.length > 0 && referencedByBody(assets, added[0]) !== false)
|
|
54148
|
+
break;
|
|
54133
54149
|
}
|
|
54134
54150
|
if (added.length === 0) return null;
|
|
54135
54151
|
if (added.length > 1) throw new Error(UNCERTAIN);
|
|
@@ -54137,6 +54153,15 @@ function storedInsertion(manager, id2, before, bytes, returnedId) {
|
|
|
54137
54153
|
const attachmentId = attachmentCoreDataId(id2, row.pk);
|
|
54138
54154
|
if (returnedId && /\/ICAttachment\/p\d+$/.test(returnedId) && returnedId !== attachmentId)
|
|
54139
54155
|
throw new Error(UNCERTAIN);
|
|
54156
|
+
const expectedKind = KIND_BY_EXTENSION[extname7(name).toLowerCase()];
|
|
54157
|
+
if (expectedKind && row.kind !== expectedKind)
|
|
54158
|
+
throw new Error(
|
|
54159
|
+
`Notes' database shows new attachment ${attachmentId} on this note, but its type (${row.uti ?? "unknown"}) does not fit ${name}; read the exact note and do not attach the file again`
|
|
54160
|
+
);
|
|
54161
|
+
if (referencedByBody(assets, row) === false)
|
|
54162
|
+
throw new Error(
|
|
54163
|
+
`Notes' database shows new attachment ${attachmentId} on this note, but the note body does not reference it; read the exact note and do not attach the file again`
|
|
54164
|
+
);
|
|
54140
54165
|
const expected = sha256(bytes);
|
|
54141
54166
|
const matches = row.assetPaths.some((path10) => fileMatches(path10, bytes.length, expected));
|
|
54142
54167
|
if (!matches)
|
|
@@ -54188,7 +54213,7 @@ function attachFile(manager, args, checked, progress = { insertionStarted: false
|
|
|
54188
54213
|
if (!saved.success || !fileMatches(saved.savedPath ?? verifyPath, bytes.length, sha256(bytes)))
|
|
54189
54214
|
throw new Error("Attachment bytes were not verified; read the exact note before retrying");
|
|
54190
54215
|
} else {
|
|
54191
|
-
const stored = inserted.length === 0 && beforeStored ? storedInsertion(manager, id2, beforeStored, bytes, returnedId) : null;
|
|
54216
|
+
const stored = inserted.length === 0 && beforeStored ? storedInsertion(manager, id2, beforeStored, bytes, name, returnedId) : null;
|
|
54192
54217
|
if (!stored)
|
|
54193
54218
|
throw new Error(
|
|
54194
54219
|
inserted.length === 0 && !beforeStored ? `${UNCERTAIN}. Notes' AppleScript does not list some attachments (PDFs on macOS 27); grant Full Disk Access so the server can verify through the Notes database` : UNCERTAIN
|
|
@@ -54198,11 +54223,17 @@ function attachFile(manager, args, checked, progress = { insertionStarted: false
|
|
|
54198
54223
|
verifiedBy = "database";
|
|
54199
54224
|
}
|
|
54200
54225
|
const nameVerified = reportedName === name;
|
|
54226
|
+
let contentHash = after.hash;
|
|
54227
|
+
if (verifiedBy === "database") {
|
|
54228
|
+
const final = readSnapshot(manager, id2);
|
|
54229
|
+
assertExistingContentPreserved(before, final);
|
|
54230
|
+
contentHash = final.hash;
|
|
54231
|
+
}
|
|
54201
54232
|
return {
|
|
54202
54233
|
ok: true,
|
|
54203
54234
|
id: id2,
|
|
54204
54235
|
attachmentId,
|
|
54205
|
-
contentHash
|
|
54236
|
+
contentHash,
|
|
54206
54237
|
bytes: bytes.length,
|
|
54207
54238
|
name: reportedName,
|
|
54208
54239
|
...verifiedBy === "database" ? { verifiedBy } : {},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apple-notes-mcp",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.35",
|
|
4
4
|
"description": "MCP server for Apple Notes - read, search, create, edit, organize, and export notes on macOS via Claude and other AI assistants",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|