apple-notes-mcp 2.15.15 → 2.15.17
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 +106 -29
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -728,6 +728,8 @@ Retrieves the full content of a specific note.
|
|
|
728
728
|
|
|
729
729
|
**Note:** Either `id` or `title` must be provided. Using `id` is recommended as it's unique and avoids issues with duplicate titles.
|
|
730
730
|
|
|
731
|
+
**Busy Notes.app:** with an `id` and Full Disk Access, the note's existence and password flag are read from the NoteStore database (as `get-note-structure` does), so only the body read goes through Notes.app. A timeout is always reported as `timeout_indeterminate`, never as `not_found`, even when an automatic retry then fails differently; and when Notes.app cannot resolve an id the database still holds, the error is `notes_unavailable`. Retry in a moment, or use `get-note-structure` for a read that does not need Notes.app.
|
|
732
|
+
|
|
731
733
|
**Large images:** Notes.app returns images inside the body as base64, so a note holding a very large image (tens of MB) can take longer to read than the timeout allows. When the read times out or overflows the output buffer, the error says so and, with Full Disk Access, names the attachments of 5 MB or more. Retry with a larger `timeoutSeconds`; `delete-note` accepts the same argument, and it needs a successful read to verify the note before deleting it.
|
|
732
734
|
|
|
733
735
|
**Example - Using ID (recommended):**
|
package/build/index.js
CHANGED
|
@@ -45558,7 +45558,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
45558
45558
|
return run(schema);
|
|
45559
45559
|
}
|
|
45560
45560
|
|
|
45561
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
45561
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
|
|
45562
45562
|
function isZ4Schema(s) {
|
|
45563
45563
|
const schema = s;
|
|
45564
45564
|
return !!schema._zod;
|
|
@@ -48573,7 +48573,7 @@ function date4(params) {
|
|
|
48573
48573
|
return _coercedDate(ZodDate2, params);
|
|
48574
48574
|
}
|
|
48575
48575
|
|
|
48576
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
48576
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
|
|
48577
48577
|
var LATEST_PROTOCOL_VERSION = "2025-11-25";
|
|
48578
48578
|
var SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2025-06-18", "2025-03-26", "2024-11-05", "2024-10-07"];
|
|
48579
48579
|
var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
|
|
@@ -50104,7 +50104,7 @@ var UrlElicitationRequiredError = class extends McpError {
|
|
|
50104
50104
|
}
|
|
50105
50105
|
};
|
|
50106
50106
|
|
|
50107
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
50107
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
|
|
50108
50108
|
function isTerminal(status) {
|
|
50109
50109
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
50110
50110
|
}
|
|
@@ -51393,7 +51393,7 @@ var zodToJsonSchema = (schema, options) => {
|
|
|
51393
51393
|
return combined;
|
|
51394
51394
|
};
|
|
51395
51395
|
|
|
51396
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
51396
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
|
|
51397
51397
|
function mapMiniTarget(t) {
|
|
51398
51398
|
if (!t)
|
|
51399
51399
|
return "draft-7";
|
|
@@ -51435,7 +51435,7 @@ function parseWithCompat(schema, data) {
|
|
|
51435
51435
|
return result.data;
|
|
51436
51436
|
}
|
|
51437
51437
|
|
|
51438
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
51438
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
|
|
51439
51439
|
var DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
|
|
51440
51440
|
var Protocol = class {
|
|
51441
51441
|
constructor(_options) {
|
|
@@ -52412,7 +52412,7 @@ function mergeCapabilities(base, additional) {
|
|
|
52412
52412
|
return result;
|
|
52413
52413
|
}
|
|
52414
52414
|
|
|
52415
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
52415
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
|
|
52416
52416
|
var import_ajv = __toESM(require_ajv(), 1);
|
|
52417
52417
|
var import_ajv_formats = __toESM(require_dist(), 1);
|
|
52418
52418
|
function createDefaultAjvInstance() {
|
|
@@ -52480,7 +52480,7 @@ var AjvJsonSchemaValidator = class {
|
|
|
52480
52480
|
}
|
|
52481
52481
|
};
|
|
52482
52482
|
|
|
52483
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
52483
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
|
|
52484
52484
|
var ExperimentalServerTasks = class {
|
|
52485
52485
|
constructor(_server) {
|
|
52486
52486
|
this._server = _server;
|
|
@@ -52693,7 +52693,7 @@ var ExperimentalServerTasks = class {
|
|
|
52693
52693
|
}
|
|
52694
52694
|
};
|
|
52695
52695
|
|
|
52696
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
52696
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
|
|
52697
52697
|
function assertToolsCallTaskCapability(requests, method, entityName) {
|
|
52698
52698
|
if (!requests) {
|
|
52699
52699
|
throw new Error(`${entityName} does not support task creation (required for ${method})`);
|
|
@@ -52728,7 +52728,7 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
|
|
|
52728
52728
|
}
|
|
52729
52729
|
}
|
|
52730
52730
|
|
|
52731
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
52731
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
|
|
52732
52732
|
var Server = class extends Protocol {
|
|
52733
52733
|
/**
|
|
52734
52734
|
* Initializes this server with the given name and version information.
|
|
@@ -53099,7 +53099,7 @@ var Server = class extends Protocol {
|
|
|
53099
53099
|
}
|
|
53100
53100
|
};
|
|
53101
53101
|
|
|
53102
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
53102
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
|
|
53103
53103
|
var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
|
|
53104
53104
|
function isCompletable(schema) {
|
|
53105
53105
|
return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
|
|
@@ -53113,7 +53113,7 @@ var McpZodTypeKind;
|
|
|
53113
53113
|
McpZodTypeKind2["Completable"] = "McpCompletable";
|
|
53114
53114
|
})(McpZodTypeKind || (McpZodTypeKind = {}));
|
|
53115
53115
|
|
|
53116
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
53116
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/uriTemplate.js
|
|
53117
53117
|
var MAX_TEMPLATE_LENGTH = 1e6;
|
|
53118
53118
|
var MAX_VARIABLE_LENGTH = 1e6;
|
|
53119
53119
|
var MAX_TEMPLATE_EXPRESSIONS = 1e4;
|
|
@@ -53335,7 +53335,7 @@ var UriTemplate = class _UriTemplate {
|
|
|
53335
53335
|
}
|
|
53336
53336
|
};
|
|
53337
53337
|
|
|
53338
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
53338
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
|
|
53339
53339
|
var TOOL_NAME_REGEX = /^[A-Za-z0-9._-]{1,128}$/;
|
|
53340
53340
|
function validateToolName(name) {
|
|
53341
53341
|
const warnings = [];
|
|
@@ -53393,7 +53393,7 @@ function validateAndWarnToolName(name) {
|
|
|
53393
53393
|
return result.isValid;
|
|
53394
53394
|
}
|
|
53395
53395
|
|
|
53396
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
53396
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
|
|
53397
53397
|
var ExperimentalMcpServerTasks = class {
|
|
53398
53398
|
constructor(_mcpServer) {
|
|
53399
53399
|
this._mcpServer = _mcpServer;
|
|
@@ -53408,7 +53408,7 @@ var ExperimentalMcpServerTasks = class {
|
|
|
53408
53408
|
}
|
|
53409
53409
|
};
|
|
53410
53410
|
|
|
53411
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
53411
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
|
|
53412
53412
|
function toolInputElementCount(value, max) {
|
|
53413
53413
|
let count = 0;
|
|
53414
53414
|
const stack = [value];
|
|
@@ -53457,6 +53457,15 @@ var McpServer = class {
|
|
|
53457
53457
|
this._promptHandlersInitialized = false;
|
|
53458
53458
|
this.server = new Server(serverInfo, options);
|
|
53459
53459
|
this._maxToolInputElements = resolveMaxToolInputElements(options?.maxToolInputElements);
|
|
53460
|
+
if (options?.capabilities?.tools) {
|
|
53461
|
+
this.setToolRequestHandlers();
|
|
53462
|
+
}
|
|
53463
|
+
if (options?.capabilities?.resources) {
|
|
53464
|
+
this.setResourceRequestHandlers();
|
|
53465
|
+
}
|
|
53466
|
+
if (options?.capabilities?.prompts) {
|
|
53467
|
+
this.setPromptRequestHandlers();
|
|
53468
|
+
}
|
|
53460
53469
|
}
|
|
53461
53470
|
/**
|
|
53462
53471
|
* Access experimental features.
|
|
@@ -54264,10 +54273,10 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
54264
54273
|
}
|
|
54265
54274
|
};
|
|
54266
54275
|
|
|
54267
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
54276
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
54268
54277
|
import process2 from "node:process";
|
|
54269
54278
|
|
|
54270
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
54279
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
|
|
54271
54280
|
var STDIO_DEFAULT_MAX_BUFFER_SIZE = 10 * 1024 * 1024;
|
|
54272
54281
|
var ReadBuffer = class {
|
|
54273
54282
|
constructor(options) {
|
|
@@ -54304,7 +54313,7 @@ function serializeMessage(message) {
|
|
|
54304
54313
|
return JSON.stringify(message) + "\n";
|
|
54305
54314
|
}
|
|
54306
54315
|
|
|
54307
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.
|
|
54316
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.2_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
54308
54317
|
var StdioServerTransport = class {
|
|
54309
54318
|
constructor(_stdin = process2.stdin, _stdout = process2.stdout, options) {
|
|
54310
54319
|
this._stdin = _stdin;
|
|
@@ -54466,6 +54475,7 @@ var RETRYABLE_ERROR_PATTERNS = [
|
|
|
54466
54475
|
/busy/i,
|
|
54467
54476
|
/changed during listing/i
|
|
54468
54477
|
];
|
|
54478
|
+
var TIMED_OUT_PATTERN = /timed? out|\(-1712\)/i;
|
|
54469
54479
|
function isRetryableError(errorMessage) {
|
|
54470
54480
|
return RETRYABLE_ERROR_PATTERNS.some((pattern2) => pattern2.test(errorMessage));
|
|
54471
54481
|
}
|
|
@@ -54594,6 +54604,7 @@ function executeAppleScript(script, options = {}) {
|
|
|
54594
54604
|
maxRetries
|
|
54595
54605
|
});
|
|
54596
54606
|
let lastError = null;
|
|
54607
|
+
let timeoutDiagnostic;
|
|
54597
54608
|
const startTime = Date.now();
|
|
54598
54609
|
const deadline = startTime + timeoutMs;
|
|
54599
54610
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
@@ -54652,10 +54663,12 @@ function executeAppleScript(script, options = {}) {
|
|
|
54652
54663
|
errorMessage,
|
|
54653
54664
|
rawError: rawError?.substring(0, 500)
|
|
54654
54665
|
});
|
|
54666
|
+
const attemptTimedOut = isTimeout || TIMED_OUT_PATTERN.test(stripQuoted(errorMessage));
|
|
54667
|
+
if (attemptTimedOut) timeoutDiagnostic ??= errorMessage;
|
|
54655
54668
|
lastError = {
|
|
54656
54669
|
success: false,
|
|
54657
54670
|
output: "",
|
|
54658
|
-
error: errorMessage
|
|
54671
|
+
error: timeoutDiagnostic && !attemptTimedOut ? `${timeoutDiagnostic} A retry then failed: ${errorMessage}` : errorMessage
|
|
54659
54672
|
};
|
|
54660
54673
|
const canRetry = isTimeout || isRetryableError(errorMessage);
|
|
54661
54674
|
const hasAttemptsLeft = attempt < maxRetries;
|
|
@@ -67196,6 +67209,42 @@ function readNoteStructure(id2, { dbPath: dbPath2 = NOTES_DB_PATH8, includeText
|
|
|
67196
67209
|
};
|
|
67197
67210
|
}
|
|
67198
67211
|
|
|
67212
|
+
// src/utils/notePresence.ts
|
|
67213
|
+
var NOTE_ID3 = /^x-coredata:\/\/([0-9A-Fa-f-]+)\/ICNote\/p(\d+)$/;
|
|
67214
|
+
function readNotePresence(id2, dbPath2 = NOTES_DB_PATH8) {
|
|
67215
|
+
const match = NOTE_ID3.exec(id2);
|
|
67216
|
+
if (!match) return null;
|
|
67217
|
+
const [, store, pk] = match;
|
|
67218
|
+
try {
|
|
67219
|
+
const columns = readColumns(dbPath2);
|
|
67220
|
+
const c = (alias, name) => col(columns, alias, name);
|
|
67221
|
+
const sql = `SELECT json_object(
|
|
67222
|
+
'store', (SELECT Z_UUID FROM Z_METADATA LIMIT 1),
|
|
67223
|
+
'isNote', n.Z_ENT = ${entity("ICNote")},
|
|
67224
|
+
'live', ${notTombstonedSql(columns, "n")},
|
|
67225
|
+
'title', ${c("n", "ZTITLE1")},
|
|
67226
|
+
'locked', ${c("n", "ZISPASSWORDPROTECTED")},
|
|
67227
|
+
'encrypted', (SELECT d.ZCRYPTOINITIALIZATIONVECTOR IS NOT NULL FROM ZICNOTEDATA d WHERE d.ZNOTE = n.Z_PK),
|
|
67228
|
+
'inTrash', CASE WHEN f.Z_PK IS NULL THEN 0 ELSE ${trashFolderSql(columns, "f")} END)
|
|
67229
|
+
FROM ZICCLOUDSYNCINGOBJECT n
|
|
67230
|
+
LEFT JOIN ZICCLOUDSYNCINGOBJECT f ON f.Z_PK = ${c("n", "ZFOLDER")}
|
|
67231
|
+
WHERE n.Z_PK = @pk;`;
|
|
67232
|
+
const [row] = parseJsonLines(
|
|
67233
|
+
runReadOnlySql(dbPath2, sql, { pk: { int: Number(pk) } })
|
|
67234
|
+
);
|
|
67235
|
+
if (!row || typeof row.store !== "string" || row.store.toUpperCase() !== store.toUpperCase())
|
|
67236
|
+
return null;
|
|
67237
|
+
if (row.isNote !== 1 || row.live !== 1) return null;
|
|
67238
|
+
return {
|
|
67239
|
+
title: typeof row.title === "string" ? row.title : null,
|
|
67240
|
+
locked: row.locked === 1 || row.encrypted === 1,
|
|
67241
|
+
inRecentlyDeleted: row.inTrash === 1
|
|
67242
|
+
};
|
|
67243
|
+
} catch {
|
|
67244
|
+
return null;
|
|
67245
|
+
}
|
|
67246
|
+
}
|
|
67247
|
+
|
|
67199
67248
|
// src/utils/bodyReadFailure.ts
|
|
67200
67249
|
var LARGE_ATTACHMENT_BYTES = 5 * 1024 * 1024;
|
|
67201
67250
|
var OUTPUT_OVERFLOW = /Notes\.app returned more than [\d.]+ (?:MB|bytes) of output/;
|
|
@@ -67229,6 +67278,11 @@ function describeBodyReadFailure(title, error62, attachments) {
|
|
|
67229
67278
|
return `${base}
|
|
67230
67279
|
|
|
67231
67280
|
${cause2} ${remedy2}`;
|
|
67281
|
+
}
|
|
67282
|
+
if (attachments && attachments.length === 0) {
|
|
67283
|
+
return `${base}
|
|
67284
|
+
|
|
67285
|
+
The note has no attachments, so its size is not the cause: Notes.app was most likely busy (for example, syncing iCloud) and did not answer in time. Retry in a moment, or with a longer timeoutSeconds (up to 120). get-note-structure reads the note from the NoteStore database without Notes.app.`;
|
|
67232
67286
|
}
|
|
67233
67287
|
const cause = large.length > 0 ? `${holds}Notes.app returns images inside the note body as base64, so a large image makes the body too big to read in time.` : "Notes.app returns images inside the note body as base64, so a note with a very large image can take longer to read than the timeout allows.";
|
|
67234
67288
|
const remedy = "Retry with a longer timeoutSeconds (up to 120) or raise APPLE_NOTES_MCP_TIMEOUT_MS. If it still fails, delete or shrink the attachment in Notes.app; delete-note needs a successful read to verify the note first.";
|
|
@@ -79607,6 +79661,12 @@ function bodyReadFailureMessage(id2, title, error62) {
|
|
|
79607
79661
|
}
|
|
79608
79662
|
return describeBodyReadFailure(title, error62, attachments);
|
|
79609
79663
|
}
|
|
79664
|
+
function isExactIdNotFound(error62) {
|
|
79665
|
+
return error62 === NOTE_ID_NOT_FOUND_MESSAGE || error62 !== void 0 && /^Can[’']t get note id\b/i.test(error62);
|
|
79666
|
+
}
|
|
79667
|
+
function storedNoteUnresolvedMessage(id2, title, error62) {
|
|
79668
|
+
return `Failed to read content of note "${title}" (ID "${id2}"): Notes.app did not resolve the ID (${error62}), but the NoteStore database holds this note, so it is not reported as not found. Notes.app may be busy, for example syncing iCloud. Retry in a moment; get-note-structure reads the note from the database without Notes.app.`;
|
|
79669
|
+
}
|
|
79610
79670
|
var NOT_DELETED_MESSAGE = "Notes.app accepted the delete, but the note is still in its original folder, so it was not moved to Recently Deleted. Nothing was deleted; read the note again before retrying.";
|
|
79611
79671
|
function deleteUnverifiedMessage(title, id2) {
|
|
79612
79672
|
return `Notes.app accepted the delete for note "${title}", but its original folder could not be re-read to confirm the note left it. The outcome is uncertain; read exact ID ${id2} before retrying.`;
|
|
@@ -80098,19 +80158,36 @@ registerTool(
|
|
|
80098
80158
|
},
|
|
80099
80159
|
withErrorHandling(({ id: id2, title, account }) => {
|
|
80100
80160
|
if (id2) {
|
|
80101
|
-
const
|
|
80102
|
-
|
|
80103
|
-
|
|
80104
|
-
|
|
80105
|
-
|
|
80106
|
-
|
|
80107
|
-
|
|
80108
|
-
|
|
80109
|
-
|
|
80161
|
+
const stored = readNotePresence(id2);
|
|
80162
|
+
let noteTitle;
|
|
80163
|
+
if (stored && stored.title !== null) {
|
|
80164
|
+
if (stored.locked) {
|
|
80165
|
+
return errorResponse(
|
|
80166
|
+
`Note "${stored.title}" is password-protected and cannot be read. Unlock it in Notes.app first.`
|
|
80167
|
+
);
|
|
80168
|
+
}
|
|
80169
|
+
noteTitle = stored.title;
|
|
80170
|
+
} else {
|
|
80171
|
+
const { note: note2, error: metadataError } = notesManager.readNoteById(id2);
|
|
80172
|
+
if (!note2) {
|
|
80173
|
+
const message = `Failed to read metadata of note with ID "${id2}": ${metadataError}`;
|
|
80174
|
+
return metadataError === NOTE_ID_NOT_FOUND_MESSAGE ? notFoundResponse(message) : errorResponse(message);
|
|
80175
|
+
}
|
|
80176
|
+
if (note2.passwordProtected) {
|
|
80177
|
+
return errorResponse(
|
|
80178
|
+
`Note "${note2.title}" is password-protected and cannot be read. Unlock it in Notes.app first.`
|
|
80179
|
+
);
|
|
80180
|
+
}
|
|
80181
|
+
noteTitle = note2.title;
|
|
80110
80182
|
}
|
|
80111
80183
|
const { body: rawContent2, error: readError2 } = notesManager.readNoteBodyById(id2);
|
|
80112
80184
|
if (!rawContent2) {
|
|
80113
|
-
|
|
80185
|
+
if (isExactIdNotFound(readError2)) {
|
|
80186
|
+
if (!stored) return notFoundResponse(bodyReadFailureMessage(id2, noteTitle, readError2));
|
|
80187
|
+
const message = storedNoteUnresolvedMessage(id2, noteTitle, readError2);
|
|
80188
|
+
return errorResponse(message, new CodedError(message, { code: "notes_unavailable" }));
|
|
80189
|
+
}
|
|
80190
|
+
return errorResponse(bodyReadFailureMessage(id2, noteTitle, readError2));
|
|
80114
80191
|
}
|
|
80115
80192
|
const rich2 = enrichNoteRead(id2, rawContent2);
|
|
80116
80193
|
const stripped2 = stripLargeInlineImages(rich2.content);
|
|
@@ -80120,7 +80197,7 @@ registerTool(
|
|
|
80120
80197
|
return successResponse(warning2 ? content2 + warning2 : content2, {
|
|
80121
80198
|
id: id2,
|
|
80122
80199
|
...noteIdentifiers(id2),
|
|
80123
|
-
title:
|
|
80200
|
+
title: noteTitle,
|
|
80124
80201
|
content: content2,
|
|
80125
80202
|
contentHash: richContentHash(rawContent2, rich2),
|
|
80126
80203
|
links: rich2.links,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apple-notes-mcp",
|
|
3
|
-
"version": "2.15.
|
|
3
|
+
"version": "2.15.17",
|
|
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",
|