apple-notes-mcp 2.8.41 → 2.8.42
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 +1 -1
- package/build/index.js +16 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1602,7 +1602,7 @@ Saves a note attachment to disk.
|
|
|
1602
1602
|
|-----------|------|----------|-------------|
|
|
1603
1603
|
| `noteId` | string | Yes | CoreData note ID (from `search-notes`/`list-notes`) |
|
|
1604
1604
|
| `attachmentId` | string | Yes | Attachment ID (from `list-attachments`) |
|
|
1605
|
-
| `savePath` | string | Yes | Absolute destination file path. Must be under your home directory, a temp directory, or `/Volumes` |
|
|
1605
|
+
| `savePath` | string | Yes | Absolute destination file path. Must be under your home directory, a temp directory, or `/Volumes`, and never inside the Notes data folder (`~/Library/Group Containers/group.com.apple.notes`), however it is reached (symlink or different letter case) |
|
|
1606
1606
|
|
|
1607
1607
|
**Returns:** Confirmation with the saved path, name, and content type (also in `structuredContent`).
|
|
1608
1608
|
|
package/build/index.js
CHANGED
|
@@ -40961,6 +40961,9 @@ function allowedSaveRoots() {
|
|
|
40961
40961
|
"/private/tmp"
|
|
40962
40962
|
];
|
|
40963
40963
|
}
|
|
40964
|
+
function deniedSaveRoots() {
|
|
40965
|
+
return [join6(homedir6(), "Library/Group Containers/group.com.apple.notes")];
|
|
40966
|
+
}
|
|
40964
40967
|
function canonicalize(path9) {
|
|
40965
40968
|
return realpathSync.native(path9);
|
|
40966
40969
|
}
|
|
@@ -41002,11 +41005,11 @@ function deepestExistingAncestor(abs) {
|
|
|
41002
41005
|
current = parent;
|
|
41003
41006
|
}
|
|
41004
41007
|
}
|
|
41005
|
-
function ensureParentDir(abs, roots = allowedSaveRoots()) {
|
|
41006
|
-
assertSafeSavePath(abs, roots);
|
|
41008
|
+
function ensureParentDir(abs, roots = allowedSaveRoots(), denied = deniedSaveRoots()) {
|
|
41009
|
+
assertSafeSavePath(abs, roots, denied);
|
|
41007
41010
|
mkdirSync(dirname(abs), { recursive: true });
|
|
41008
41011
|
}
|
|
41009
|
-
function assertSafeSavePath(p, roots = allowedSaveRoots()) {
|
|
41012
|
+
function assertSafeSavePath(p, roots = allowedSaveRoots(), denied = deniedSaveRoots()) {
|
|
41010
41013
|
if (!p || !p.trim()) throw new Error("A destination path is required.");
|
|
41011
41014
|
if (!isAbsolute(p)) throw new Error(`Destination path must be absolute: "${p}"`);
|
|
41012
41015
|
const abs = resolve(p);
|
|
@@ -41034,6 +41037,12 @@ function assertSafeSavePath(p, roots = allowedSaveRoots()) {
|
|
|
41034
41037
|
`Refusing to write outside allowed locations (home, temp, /Volumes): "${abs}" resolves to "${canonicalDest}" through a symbolic link.`
|
|
41035
41038
|
);
|
|
41036
41039
|
}
|
|
41040
|
+
const deniedForms = [
|
|
41041
|
+
.../* @__PURE__ */ new Set([...denied.map((d) => resolve(d)), ...canonicalRoots(denied)])
|
|
41042
|
+
].map((d) => d.toLowerCase());
|
|
41043
|
+
if ([abs, canonicalDest].some((form) => isWithinRoots(form.toLowerCase(), deniedForms))) {
|
|
41044
|
+
throw new Error(`Refusing to write inside the Notes library container: "${abs}"`);
|
|
41045
|
+
}
|
|
41037
41046
|
return abs;
|
|
41038
41047
|
}
|
|
41039
41048
|
var DEFAULT_MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
|
|
@@ -52764,13 +52773,15 @@ registerTool(
|
|
|
52764
52773
|
registerTool(
|
|
52765
52774
|
"save-attachment",
|
|
52766
52775
|
{
|
|
52767
|
-
description: "Use when: writing one note attachment to a file on disk.\nReturns: the saved path.\nDo not use when: you want the bytes in-memory as base64 (fetch-attachment).\nSafety: writes a file; savePath must be absolute and under the home directory, a temp dir, or /Volumes. Get the ids from list-attachments first.",
|
|
52776
|
+
description: "Use when: writing one note attachment to a file on disk.\nReturns: the saved path.\nDo not use when: you want the bytes in-memory as base64 (fetch-attachment).\nSafety: writes a file; savePath must be absolute and under the home directory, a temp dir, or /Volumes, and not inside the Notes data folder. Get the ids from list-attachments first.",
|
|
52768
52777
|
inputSchema: {
|
|
52769
52778
|
noteId: looseNoteId(external_exports.string().min(1, "noteId is required")).describe(
|
|
52770
52779
|
`Note id (from search/list): ${NOTE_ID_FORMS}`
|
|
52771
52780
|
),
|
|
52772
52781
|
attachmentId: external_exports.string().min(1, "attachmentId is required").max(MAX.ATTACHMENT_ID).describe("Attachment id (from list-attachments)"),
|
|
52773
|
-
savePath: external_exports.string().min(1, "savePath is required").max(MAX.SAVE_PATH).describe(
|
|
52782
|
+
savePath: external_exports.string().min(1, "savePath is required").max(MAX.SAVE_PATH).describe(
|
|
52783
|
+
"Absolute destination file path (must be under home, temp, or /Volumes; never inside the Notes data folder)"
|
|
52784
|
+
)
|
|
52774
52785
|
},
|
|
52775
52786
|
outputSchema: {
|
|
52776
52787
|
savedPath: external_exports.string().optional(),
|
package/package.json
CHANGED