apple-notes-mcp 2.8.5 → 2.8.6
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 +20 -0
- package/build/index.js +231 -40
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -303,6 +303,26 @@ attachment-bearing notes; edit them in Notes.app.
|
|
|
303
303
|
|
|
304
304
|
---
|
|
305
305
|
|
|
306
|
+
#### `get-native-objects`
|
|
307
|
+
|
|
308
|
+
Reads native object identities and ranges, checklist item IDs and state, actual
|
|
309
|
+
native tags, and native table data from one exact note ID. Table output includes
|
|
310
|
+
stable row and column identifiers. `tableCellsComplete` is false when Notes
|
|
311
|
+
metadata cannot be decoded completely. This tool is read-only and requires Full
|
|
312
|
+
Disk Access.
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
#### `list-native-tags`
|
|
317
|
+
|
|
318
|
+
Lists actual native Notes tags used within one explicit `account` and `folder`,
|
|
319
|
+
mapping each tag to its matching note IDs. This differs from textual hashtag
|
|
320
|
+
search. The response reports `complete: false` and per-note errors when some
|
|
321
|
+
native metadata is unavailable. This tool is read-only and requires Full Disk
|
|
322
|
+
Access.
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
306
326
|
#### `get-note-plaintext`
|
|
307
327
|
|
|
308
328
|
Retrieves a note's body as plain text, with no HTML markup.
|
package/build/index.js
CHANGED
|
@@ -3358,9 +3358,9 @@ var require_utils = __commonJS({
|
|
|
3358
3358
|
let output = "";
|
|
3359
3359
|
for (let i = 0; i < input.length; i++) {
|
|
3360
3360
|
if (input[i] === "%" && i + 2 < input.length) {
|
|
3361
|
-
const
|
|
3362
|
-
if (isHexPair(
|
|
3363
|
-
const normalizedHex =
|
|
3361
|
+
const hex2 = input.slice(i + 1, i + 3);
|
|
3362
|
+
if (isHexPair(hex2)) {
|
|
3363
|
+
const normalizedHex = hex2.toUpperCase();
|
|
3364
3364
|
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
3365
3365
|
if (decodeUnreserved && isUnreserved(decoded)) {
|
|
3366
3366
|
output += decoded;
|
|
@@ -3380,9 +3380,9 @@ var require_utils = __commonJS({
|
|
|
3380
3380
|
for (let i = 0; i < input.length; i++) {
|
|
3381
3381
|
const ch = input[i];
|
|
3382
3382
|
if (ch === "%" && i + 2 < input.length) {
|
|
3383
|
-
const
|
|
3384
|
-
if (isHexPair(
|
|
3385
|
-
const normalizedHex =
|
|
3383
|
+
const hex2 = input.slice(i + 1, i + 3);
|
|
3384
|
+
if (isHexPair(hex2)) {
|
|
3385
|
+
const normalizedHex = hex2.toUpperCase();
|
|
3386
3386
|
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
3387
3387
|
if (decoded !== "." && isUnreserved(decoded)) {
|
|
3388
3388
|
output += decoded;
|
|
@@ -3422,9 +3422,9 @@ var require_utils = __commonJS({
|
|
|
3422
3422
|
for (let i = 0; i < input.length; i++) {
|
|
3423
3423
|
const ch = input[i];
|
|
3424
3424
|
if (ch === "%" && i + 2 < input.length) {
|
|
3425
|
-
const
|
|
3426
|
-
if (isHexPair(
|
|
3427
|
-
output += "%" +
|
|
3425
|
+
const hex2 = input.slice(i + 1, i + 3);
|
|
3426
|
+
if (isHexPair(hex2)) {
|
|
3427
|
+
output += "%" + hex2.toUpperCase();
|
|
3428
3428
|
i += 2;
|
|
3429
3429
|
continue;
|
|
3430
3430
|
}
|
|
@@ -3460,9 +3460,9 @@ var require_utils = __commonJS({
|
|
|
3460
3460
|
for (let i = 0; i < input.length; i++) {
|
|
3461
3461
|
const ch = input[i];
|
|
3462
3462
|
if (ch === "%" && i + 2 < input.length) {
|
|
3463
|
-
const
|
|
3464
|
-
if (isHexPair(
|
|
3465
|
-
output += "%" +
|
|
3463
|
+
const hex2 = input.slice(i + 1, i + 3);
|
|
3464
|
+
if (isHexPair(hex2)) {
|
|
3465
|
+
output += "%" + hex2.toUpperCase();
|
|
3466
3466
|
i += 2;
|
|
3467
3467
|
continue;
|
|
3468
3468
|
}
|
|
@@ -3507,9 +3507,9 @@ var require_utils = __commonJS({
|
|
|
3507
3507
|
for (let i = 0; i < input.length; i++) {
|
|
3508
3508
|
const ch = input[i];
|
|
3509
3509
|
if (ch === "%" && i + 2 < input.length) {
|
|
3510
|
-
const
|
|
3511
|
-
if (isHexPair(
|
|
3512
|
-
const normalizedHex =
|
|
3510
|
+
const hex2 = input.slice(i + 1, i + 3);
|
|
3511
|
+
if (isHexPair(hex2)) {
|
|
3512
|
+
const normalizedHex = hex2.toUpperCase();
|
|
3513
3513
|
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
3514
3514
|
if (isUnreserved(decoded)) {
|
|
3515
3515
|
output += decoded;
|
|
@@ -3547,9 +3547,9 @@ var require_utils = __commonJS({
|
|
|
3547
3547
|
let output = "";
|
|
3548
3548
|
for (let i = 0; i < input.length; i++) {
|
|
3549
3549
|
if (input[i] === "%" && i + 2 < input.length) {
|
|
3550
|
-
const
|
|
3551
|
-
if (isHexPair(
|
|
3552
|
-
output += "%" +
|
|
3550
|
+
const hex2 = input.slice(i + 1, i + 3);
|
|
3551
|
+
if (isHexPair(hex2)) {
|
|
3552
|
+
output += "%" + hex2.toUpperCase();
|
|
3553
3553
|
i += 2;
|
|
3554
3554
|
continue;
|
|
3555
3555
|
}
|
|
@@ -9329,8 +9329,8 @@ var require_select = __commonJS({
|
|
|
9329
9329
|
regex = regex.replace(name, val.source || val);
|
|
9330
9330
|
return new RegExp(regex);
|
|
9331
9331
|
};
|
|
9332
|
-
var truncateUrl = function(url,
|
|
9333
|
-
return url.replace(/^(?:\w+:\/\/|\/+)/, "").replace(/(?:\/+|\/*#.*?)$/, "").split("/",
|
|
9332
|
+
var truncateUrl = function(url, num2) {
|
|
9333
|
+
return url.replace(/^(?:\w+:\/\/|\/+)/, "").replace(/(?:\/+|\/*#.*?)$/, "").split("/", num2).join("/");
|
|
9334
9334
|
};
|
|
9335
9335
|
var parseNth = function(param_, test) {
|
|
9336
9336
|
var param = param_.replace(/\s+/g, ""), cap;
|
|
@@ -24777,8 +24777,8 @@ var ZodError = class _ZodError extends Error {
|
|
|
24777
24777
|
constructor(issues) {
|
|
24778
24778
|
super();
|
|
24779
24779
|
this.issues = [];
|
|
24780
|
-
this.addIssue = (
|
|
24781
|
-
this.issues = [...this.issues,
|
|
24780
|
+
this.addIssue = (sub2) => {
|
|
24781
|
+
this.issues = [...this.issues, sub2];
|
|
24782
24782
|
};
|
|
24783
24783
|
this.addIssues = (subs = []) => {
|
|
24784
24784
|
this.issues = [...this.issues, ...subs];
|
|
@@ -24845,13 +24845,13 @@ var ZodError = class _ZodError extends Error {
|
|
|
24845
24845
|
flatten(mapper = (issue2) => issue2.message) {
|
|
24846
24846
|
const fieldErrors = {};
|
|
24847
24847
|
const formErrors = [];
|
|
24848
|
-
for (const
|
|
24849
|
-
if (
|
|
24850
|
-
const firstEl =
|
|
24848
|
+
for (const sub2 of this.issues) {
|
|
24849
|
+
if (sub2.path.length > 0) {
|
|
24850
|
+
const firstEl = sub2.path[0];
|
|
24851
24851
|
fieldErrors[firstEl] = fieldErrors[firstEl] || [];
|
|
24852
|
-
fieldErrors[firstEl].push(mapper(
|
|
24852
|
+
fieldErrors[firstEl].push(mapper(sub2));
|
|
24853
24853
|
} else {
|
|
24854
|
-
formErrors.push(mapper(
|
|
24854
|
+
formErrors.push(mapper(sub2));
|
|
24855
24855
|
}
|
|
24856
24856
|
}
|
|
24857
24857
|
return { formErrors, fieldErrors };
|
|
@@ -29150,12 +29150,12 @@ var $ZodRealError = $constructor("$ZodError", initializer, { Parent: Error });
|
|
|
29150
29150
|
function flattenError(error2, mapper = (issue2) => issue2.message) {
|
|
29151
29151
|
const fieldErrors = {};
|
|
29152
29152
|
const formErrors = [];
|
|
29153
|
-
for (const
|
|
29154
|
-
if (
|
|
29155
|
-
fieldErrors[
|
|
29156
|
-
fieldErrors[
|
|
29153
|
+
for (const sub2 of error2.issues) {
|
|
29154
|
+
if (sub2.path.length > 0) {
|
|
29155
|
+
fieldErrors[sub2.path[0]] = fieldErrors[sub2.path[0]] || [];
|
|
29156
|
+
fieldErrors[sub2.path[0]].push(mapper(sub2));
|
|
29157
29157
|
} else {
|
|
29158
|
-
formErrors.push(mapper(
|
|
29158
|
+
formErrors.push(mapper(sub2));
|
|
29159
29159
|
}
|
|
29160
29160
|
}
|
|
29161
29161
|
return { formErrors, fieldErrors };
|
|
@@ -39364,9 +39364,9 @@ function queryNoteData(noteId) {
|
|
|
39364
39364
|
timeout: 5e3,
|
|
39365
39365
|
stdio: ["pipe", "pipe", "pipe"]
|
|
39366
39366
|
});
|
|
39367
|
-
const
|
|
39368
|
-
if (!
|
|
39369
|
-
return { hex };
|
|
39367
|
+
const hex2 = result.trim();
|
|
39368
|
+
if (!hex2) return { hex: null };
|
|
39369
|
+
return { hex: hex2 };
|
|
39370
39370
|
} catch (error2) {
|
|
39371
39371
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
39372
39372
|
console.error(`Failed to query NoteStore database: ${message}`);
|
|
@@ -39376,10 +39376,10 @@ function queryNoteData(noteId) {
|
|
|
39376
39376
|
return { hex: null };
|
|
39377
39377
|
}
|
|
39378
39378
|
}
|
|
39379
|
-
function hexToBytes(
|
|
39380
|
-
const bytes = new Uint8Array(
|
|
39381
|
-
for (let i = 0; i <
|
|
39382
|
-
bytes[i / 2] = parseInt(
|
|
39379
|
+
function hexToBytes(hex2) {
|
|
39380
|
+
const bytes = new Uint8Array(hex2.length / 2);
|
|
39381
|
+
for (let i = 0; i < hex2.length; i += 2) {
|
|
39382
|
+
bytes[i / 2] = parseInt(hex2.substring(i, i + 2), 16);
|
|
39383
39383
|
}
|
|
39384
39384
|
return bytes;
|
|
39385
39385
|
}
|
|
@@ -42511,7 +42511,7 @@ function decodeHtmlEntities(text) {
|
|
|
42511
42511
|
}
|
|
42512
42512
|
return String.fromCodePoint(codePoint);
|
|
42513
42513
|
};
|
|
42514
|
-
return text.replace(/&#x([0-9a-f]+);?/gi, (match,
|
|
42514
|
+
return text.replace(/&#x([0-9a-f]+);?/gi, (match, hex2) => decodeCodePoint(match, hex2, 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, "&");
|
|
42515
42515
|
}
|
|
42516
42516
|
function firstVisibleHtmlLine(html) {
|
|
42517
42517
|
let text = html;
|
|
@@ -42852,6 +42852,103 @@ function comparableVisibleText(html) {
|
|
|
42852
42852
|
).replace(/\s+/g, " ").trim();
|
|
42853
42853
|
}
|
|
42854
42854
|
|
|
42855
|
+
// src/utils/noteTables.ts
|
|
42856
|
+
import { gunzipSync as gunzipSync3 } from "node:zlib";
|
|
42857
|
+
var sub = (f, n) => {
|
|
42858
|
+
const value = embeddedMessage(getField(f, n));
|
|
42859
|
+
if (!value) throw new Error(`Missing table field ${n}`);
|
|
42860
|
+
return value;
|
|
42861
|
+
};
|
|
42862
|
+
var num = (f, n) => {
|
|
42863
|
+
const v = varintValue(getField(f, n));
|
|
42864
|
+
if (v === void 0) throw new Error(`Missing table index ${n}`);
|
|
42865
|
+
return v;
|
|
42866
|
+
};
|
|
42867
|
+
var many = (f, n) => getFields(f, n).map((v) => {
|
|
42868
|
+
const m = embeddedMessage(v);
|
|
42869
|
+
if (!m) throw new Error("Invalid table entry");
|
|
42870
|
+
return m;
|
|
42871
|
+
});
|
|
42872
|
+
var hex = (f) => {
|
|
42873
|
+
if (!(f?.value instanceof Uint8Array)) throw new Error("Missing table UUID");
|
|
42874
|
+
return Buffer.from(f.value).toString("hex");
|
|
42875
|
+
};
|
|
42876
|
+
function parseNoteTable(compressed) {
|
|
42877
|
+
const root = decodeMessage(gunzipSync3(compressed, { maxOutputLength: 16 * 1024 * 1024 }));
|
|
42878
|
+
const data = sub(sub(root, 2), 3), entries = many(data, 3);
|
|
42879
|
+
if (entries.length > 1e5) throw new Error("Table too large");
|
|
42880
|
+
const keys = getFields(data, 4).map(stringValue), types = getFields(data, 5).map(stringValue), uuids = getFields(data, 6).map(hex);
|
|
42881
|
+
const entry = (index) => {
|
|
42882
|
+
if (!entries[index]) throw new Error("Invalid table reference");
|
|
42883
|
+
return entries[index];
|
|
42884
|
+
};
|
|
42885
|
+
const uuidIndex = (index) => num(sub(many(sub(entry(index), 13), 3)[0], 2), 2);
|
|
42886
|
+
const roots = entries.filter((e) => {
|
|
42887
|
+
const map = embeddedMessage(getField(e, 13));
|
|
42888
|
+
return map && types[num(map, 1)] === "com.apple.notes.ICTable";
|
|
42889
|
+
});
|
|
42890
|
+
if (roots.length !== 1) throw new Error("Ambiguous native table root");
|
|
42891
|
+
const refs = new Map(
|
|
42892
|
+
many(sub(roots[0], 13), 3).filter((m) => ["crRows", "crColumns", "cellColumns"].includes(keys[num(m, 1)] || "")).map((m) => [keys[num(m, 1)], num(sub(m, 2), 6)])
|
|
42893
|
+
);
|
|
42894
|
+
const ordered = (key) => {
|
|
42895
|
+
const ref = refs.get(key);
|
|
42896
|
+
if (ref === void 0) throw new Error("Missing table dimension");
|
|
42897
|
+
const ordering = sub(sub(entry(ref), 16), 1), array2 = sub(ordering, 1);
|
|
42898
|
+
const ids = many(array2, 2).map((a) => hex(getField(a, 2)));
|
|
42899
|
+
const map = /* @__PURE__ */ new Map();
|
|
42900
|
+
ids.forEach((id, i) => {
|
|
42901
|
+
const index = uuids.indexOf(id);
|
|
42902
|
+
if (index < 0) throw new Error("Missing dimension UUID");
|
|
42903
|
+
map.set(index, i);
|
|
42904
|
+
});
|
|
42905
|
+
const aliases = many(sub(ordering, 2), 1).map((pair) => [
|
|
42906
|
+
uuidIndex(num(sub(pair, 1), 6)),
|
|
42907
|
+
uuidIndex(num(sub(pair, 2), 6))
|
|
42908
|
+
]);
|
|
42909
|
+
for (let pass = 0; pass < aliases.length + 1; pass++) {
|
|
42910
|
+
let changed = false;
|
|
42911
|
+
for (const [key2, value] of aliases)
|
|
42912
|
+
if (map.has(key2) && !map.has(value)) {
|
|
42913
|
+
map.set(value, map.get(key2));
|
|
42914
|
+
changed = true;
|
|
42915
|
+
}
|
|
42916
|
+
if (!changed) break;
|
|
42917
|
+
}
|
|
42918
|
+
return { ids, map };
|
|
42919
|
+
};
|
|
42920
|
+
const rows = ordered("crRows"), columns = ordered("crColumns");
|
|
42921
|
+
if (!rows.ids.length || !columns.ids.length || rows.ids.length * columns.ids.length > 1e5)
|
|
42922
|
+
throw new Error("Unsupported table size");
|
|
42923
|
+
const values = rows.ids.map(() => columns.ids.map(() => ""));
|
|
42924
|
+
const cellRef = refs.get("cellColumns");
|
|
42925
|
+
if (cellRef === void 0) throw new Error("Missing table cells");
|
|
42926
|
+
for (const column of many(sub(entry(cellRef), 6), 1)) {
|
|
42927
|
+
const ci = columns.map.get(uuidIndex(num(sub(column, 1), 6)));
|
|
42928
|
+
const cells = entry(num(sub(column, 2), 6));
|
|
42929
|
+
for (const row of many(sub(cells, 6), 1)) {
|
|
42930
|
+
const ri = rows.map.get(uuidIndex(num(sub(row, 1), 6)));
|
|
42931
|
+
if (ri === void 0 || ci === void 0) continue;
|
|
42932
|
+
const note = sub(entry(num(sub(row, 2), 6)), 10);
|
|
42933
|
+
const text = stringValue(getField(note, 2));
|
|
42934
|
+
if (text === void 0 || text.includes("\uFFFC"))
|
|
42935
|
+
throw new Error("Embedded or unsupported table cell");
|
|
42936
|
+
values[ri][ci] = text.replace(/\n$/u, "");
|
|
42937
|
+
}
|
|
42938
|
+
}
|
|
42939
|
+
const rtl = entries.some((e) => {
|
|
42940
|
+
const map = embeddedMessage(getField(e, 13));
|
|
42941
|
+
return map && many(map, 3).some(
|
|
42942
|
+
(m) => stringValue(getField(sub(m, 2), 4)) === "CRTableColumnDirectionRightToLeft"
|
|
42943
|
+
);
|
|
42944
|
+
});
|
|
42945
|
+
if (rtl) {
|
|
42946
|
+
for (const row of values) row.reverse();
|
|
42947
|
+
columns.ids.reverse();
|
|
42948
|
+
}
|
|
42949
|
+
return { rows: values, rowIds: rows.ids, columnIds: columns.ids };
|
|
42950
|
+
}
|
|
42951
|
+
|
|
42855
42952
|
// src/index.ts
|
|
42856
42953
|
loadFileConfig();
|
|
42857
42954
|
var require2 = createRequire(import.meta.url);
|
|
@@ -43406,6 +43503,100 @@ registerTool(
|
|
|
43406
43503
|
return successResponse(`Shown account with ID "${id}" in Notes.app`, { id, separately });
|
|
43407
43504
|
}, "Error showing account")
|
|
43408
43505
|
);
|
|
43506
|
+
registerTool(
|
|
43507
|
+
"get-native-objects",
|
|
43508
|
+
{
|
|
43509
|
+
description: "Use when: inspecting native objects, checklist identities, or tables in one exact note.\nReturns: native object IDs and ranges, checklist IDs and state, actual native tags, decoded tables, and the current rich content hash.\nDo not use when: you only need the note body (get-note-content) or AppleScript attachment metadata (list-attachments).\nSafety: read-only; requires Full Disk Access and reports incomplete table metadata instead of guessing.",
|
|
43510
|
+
inputSchema: { id: noteIdInput },
|
|
43511
|
+
outputSchema: {
|
|
43512
|
+
id: external_exports.string().optional(),
|
|
43513
|
+
contentHash: external_exports.string().optional(),
|
|
43514
|
+
objects: external_exports.array(external_exports.record(external_exports.unknown())).optional(),
|
|
43515
|
+
checklistItems: external_exports.array(external_exports.record(external_exports.unknown())).optional(),
|
|
43516
|
+
nativeTags: external_exports.array(external_exports.string()).optional(),
|
|
43517
|
+
tables: external_exports.array(external_exports.record(external_exports.unknown())).optional(),
|
|
43518
|
+
tableCellsComplete: external_exports.boolean().optional()
|
|
43519
|
+
},
|
|
43520
|
+
annotations: { readOnlyHint: true }
|
|
43521
|
+
},
|
|
43522
|
+
withErrorHandling(({ id }) => {
|
|
43523
|
+
const note = notesManager.getNoteById(id);
|
|
43524
|
+
if (!note) return errorResponse(`Note with ID "${id}" not found`);
|
|
43525
|
+
const body = notesManager.getNoteContentById(id);
|
|
43526
|
+
if (!body) return errorResponse(`Failed to read content of note "${note.title}"`);
|
|
43527
|
+
const rich = readRichNote(id);
|
|
43528
|
+
const tables = (rich.objectData || []).filter((object3) => object3.type?.includes("table")).map((object3) => {
|
|
43529
|
+
try {
|
|
43530
|
+
return {
|
|
43531
|
+
id: object3.id,
|
|
43532
|
+
attachmentId: id.replace(/ICNote\/p\d+$/, `ICAttachment/p${object3.pk}`),
|
|
43533
|
+
complete: true,
|
|
43534
|
+
...parseNoteTable(Buffer.from(object3.mergeable, "hex"))
|
|
43535
|
+
};
|
|
43536
|
+
} catch (error2) {
|
|
43537
|
+
return { id: object3.id, complete: false, reason: String(error2) };
|
|
43538
|
+
}
|
|
43539
|
+
});
|
|
43540
|
+
for (const object3 of rich.objects || []) {
|
|
43541
|
+
if (object3.type.includes("table") && !tables.some((table) => table.id === object3.id)) {
|
|
43542
|
+
tables.push({
|
|
43543
|
+
id: object3.id,
|
|
43544
|
+
complete: false,
|
|
43545
|
+
reason: "Native table metadata is unavailable"
|
|
43546
|
+
});
|
|
43547
|
+
}
|
|
43548
|
+
}
|
|
43549
|
+
const richRead = {
|
|
43550
|
+
content: body,
|
|
43551
|
+
links: rich.links,
|
|
43552
|
+
nativeTags: rich.nativeTags,
|
|
43553
|
+
complete: true,
|
|
43554
|
+
writable: !rich.hasNativeObjects && !rich.hasChecklist,
|
|
43555
|
+
revision: rich.revision
|
|
43556
|
+
};
|
|
43557
|
+
return successResponse("Native objects read from the exact note", {
|
|
43558
|
+
id,
|
|
43559
|
+
contentHash: richContentHash(body, richRead),
|
|
43560
|
+
objects: rich.objects,
|
|
43561
|
+
checklistItems: rich.checklistItems,
|
|
43562
|
+
nativeTags: rich.nativeTags,
|
|
43563
|
+
tables,
|
|
43564
|
+
tableCellsComplete: tables.every((table) => table.complete)
|
|
43565
|
+
});
|
|
43566
|
+
}, "Error reading native objects")
|
|
43567
|
+
);
|
|
43568
|
+
registerTool(
|
|
43569
|
+
"list-native-tags",
|
|
43570
|
+
{
|
|
43571
|
+
description: "Use when: listing actual native Notes tags used in one explicit account and folder.\nReturns: each native tag mapped to exact matching note IDs, plus completeness and per-note errors.\nDo not use when: searching textual #hashtags in note bodies (search-notes).\nSafety: read-only; requires Full Disk Access and discloses partial reads.",
|
|
43572
|
+
inputSchema: {
|
|
43573
|
+
account: external_exports.string().min(1).max(MAX.ACCOUNT),
|
|
43574
|
+
folder: external_exports.string().min(1).max(MAX.FOLDER)
|
|
43575
|
+
},
|
|
43576
|
+
outputSchema: {
|
|
43577
|
+
tags: external_exports.record(external_exports.array(external_exports.string())).optional(),
|
|
43578
|
+
complete: external_exports.boolean().optional(),
|
|
43579
|
+
errors: external_exports.record(external_exports.string()).optional()
|
|
43580
|
+
},
|
|
43581
|
+
annotations: { readOnlyHint: true }
|
|
43582
|
+
},
|
|
43583
|
+
withErrorHandling(({ account, folder }) => {
|
|
43584
|
+
const tags = {};
|
|
43585
|
+
const errors = {};
|
|
43586
|
+
for (const note of notesManager.listNoteRefs(account, folder)) {
|
|
43587
|
+
try {
|
|
43588
|
+
for (const tag of readRichNote(note.id).nativeTags) (tags[tag] ||= []).push(note.id);
|
|
43589
|
+
} catch {
|
|
43590
|
+
errors[note.id] = "Native metadata unavailable";
|
|
43591
|
+
}
|
|
43592
|
+
}
|
|
43593
|
+
return successResponse("Native tags read from the requested folder", {
|
|
43594
|
+
tags,
|
|
43595
|
+
complete: Object.keys(errors).length === 0,
|
|
43596
|
+
errors
|
|
43597
|
+
});
|
|
43598
|
+
}, "Error listing native tags")
|
|
43599
|
+
);
|
|
43409
43600
|
registerTool(
|
|
43410
43601
|
"update-note",
|
|
43411
43602
|
{
|
package/package.json
CHANGED