apple-notes-mcp 2.8.24 → 2.8.25
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 +29 -0
- package/build/index.js +95 -51
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -201,6 +201,35 @@ for the investigation and verification behind each:
|
|
|
201
201
|
|
|
202
202
|
This section documents all available tools. AI agents should use these tool names and parameters exactly as specified.
|
|
203
203
|
|
|
204
|
+
### Error results
|
|
205
|
+
|
|
206
|
+
A failed call returns `isError: true` with the same human-readable text as
|
|
207
|
+
before, plus `structuredContent` carrying a stable machine-readable `code`.
|
|
208
|
+
Branch on `code`, not on the prose, which may be reworded.
|
|
209
|
+
|
|
210
|
+
| `code` | Meaning |
|
|
211
|
+
|--------|---------|
|
|
212
|
+
| `not_found` | The note, folder, account, attachment, or checklist does not exist |
|
|
213
|
+
| `ambiguous` | More than one item matched; use an exact id |
|
|
214
|
+
| `permission_denied` | macOS refused Automation access to Notes.app |
|
|
215
|
+
| `full_disk_access_missing` | The Notes database is not readable; grant Full Disk Access |
|
|
216
|
+
| `shortcut_not_installed` | A native-write bridge Shortcut is not installed exactly once |
|
|
217
|
+
| `timeout_indeterminate` | The operation timed out; for a write, the outcome is unknown |
|
|
218
|
+
| `verification_failed` | The write ran, but exact-ID readback did not confirm it |
|
|
219
|
+
| `revision_conflict` | The note changed since it was read |
|
|
220
|
+
| `validation_error` | The request was rejected before anything ran |
|
|
221
|
+
| `unsupported` | Not supported for this note or in this mode, such as a locked note |
|
|
222
|
+
| `notes_unavailable` | Notes.app is not running, busy, or not responding |
|
|
223
|
+
| `operation_failed` | The server could not classify the failure; read the text |
|
|
224
|
+
|
|
225
|
+
Two optional booleans describe a write's outcome when it is known.
|
|
226
|
+
`indeterminate: true` means the outcome is uncertain: read the target by exact
|
|
227
|
+
id before any retry, and never retry blindly. `committed: true` means the write
|
|
228
|
+
took effect even though its verification failed; `committed: false` means
|
|
229
|
+
nothing was written (for example a `revision_conflict`). An absent flag means
|
|
230
|
+
unknown. Errors the MCP SDK raises itself before a tool runs, such as an
|
|
231
|
+
argument that fails the input schema, carry no `structuredContent`.
|
|
232
|
+
|
|
204
233
|
### Note Operations
|
|
205
234
|
|
|
206
235
|
#### `create-note`
|
package/build/index.js
CHANGED
|
@@ -1105,11 +1105,11 @@ var require_util = __commonJS({
|
|
|
1105
1105
|
return false;
|
|
1106
1106
|
}
|
|
1107
1107
|
exports.schemaHasRules = schemaHasRules;
|
|
1108
|
-
function schemaHasRulesButRef(schema,
|
|
1108
|
+
function schemaHasRulesButRef(schema, RULES2) {
|
|
1109
1109
|
if (typeof schema == "boolean")
|
|
1110
1110
|
return !schema;
|
|
1111
1111
|
for (const key in schema)
|
|
1112
|
-
if (key !== "$ref" &&
|
|
1112
|
+
if (key !== "$ref" && RULES2.all[key])
|
|
1113
1113
|
return true;
|
|
1114
1114
|
return false;
|
|
1115
1115
|
}
|
|
@@ -2503,17 +2503,17 @@ var require_validate = __commonJS({
|
|
|
2503
2503
|
}
|
|
2504
2504
|
function schemaKeywords(it, types, typeErrors, errsCount) {
|
|
2505
2505
|
const { gen, schema, data, allErrors, opts, self } = it;
|
|
2506
|
-
const { RULES } = self;
|
|
2507
|
-
if (schema.$ref && (opts.ignoreKeywordsWithRef || !(0, util_1.schemaHasRulesButRef)(schema,
|
|
2508
|
-
gen.block(() => keywordCode(it, "$ref",
|
|
2506
|
+
const { RULES: RULES2 } = self;
|
|
2507
|
+
if (schema.$ref && (opts.ignoreKeywordsWithRef || !(0, util_1.schemaHasRulesButRef)(schema, RULES2))) {
|
|
2508
|
+
gen.block(() => keywordCode(it, "$ref", RULES2.all.$ref.definition));
|
|
2509
2509
|
return;
|
|
2510
2510
|
}
|
|
2511
2511
|
if (!opts.jtd)
|
|
2512
2512
|
checkStrictTypes(it, types);
|
|
2513
2513
|
gen.block(() => {
|
|
2514
|
-
for (const group of
|
|
2514
|
+
for (const group of RULES2.rules)
|
|
2515
2515
|
groupKeywords(group);
|
|
2516
|
-
groupKeywords(
|
|
2516
|
+
groupKeywords(RULES2.post);
|
|
2517
2517
|
});
|
|
2518
2518
|
function groupKeywords(group) {
|
|
2519
2519
|
if (!(0, applicability_1.shouldUseGroup)(schema, group))
|
|
@@ -4600,10 +4600,10 @@ var require_core = __commonJS({
|
|
|
4600
4600
|
}
|
|
4601
4601
|
// Remove keyword
|
|
4602
4602
|
removeKeyword(keyword) {
|
|
4603
|
-
const { RULES } = this;
|
|
4604
|
-
delete
|
|
4605
|
-
delete
|
|
4606
|
-
for (const group of
|
|
4603
|
+
const { RULES: RULES2 } = this;
|
|
4604
|
+
delete RULES2.keywords[keyword];
|
|
4605
|
+
delete RULES2.all[keyword];
|
|
4606
|
+
for (const group of RULES2.rules) {
|
|
4607
4607
|
const i = group.rules.findIndex((rule) => rule.keyword === keyword);
|
|
4608
4608
|
if (i >= 0)
|
|
4609
4609
|
group.rules.splice(i, 1);
|
|
@@ -4771,9 +4771,9 @@ var require_core = __commonJS({
|
|
|
4771
4771
|
}
|
|
4772
4772
|
var KEYWORD_NAME = /^[a-z_$][a-z0-9_$:-]*$/i;
|
|
4773
4773
|
function checkKeyword(keyword, def) {
|
|
4774
|
-
const { RULES } = this;
|
|
4774
|
+
const { RULES: RULES2 } = this;
|
|
4775
4775
|
(0, util_1.eachItem)(keyword, (kwd) => {
|
|
4776
|
-
if (
|
|
4776
|
+
if (RULES2.keywords[kwd])
|
|
4777
4777
|
throw new Error(`Keyword ${kwd} is already defined`);
|
|
4778
4778
|
if (!KEYWORD_NAME.test(kwd))
|
|
4779
4779
|
throw new Error(`Keyword ${kwd} has invalid name`);
|
|
@@ -4789,13 +4789,13 @@ var require_core = __commonJS({
|
|
|
4789
4789
|
const post = definition === null || definition === void 0 ? void 0 : definition.post;
|
|
4790
4790
|
if (dataType && post)
|
|
4791
4791
|
throw new Error('keyword with "post" flag cannot have "type"');
|
|
4792
|
-
const { RULES } = this;
|
|
4793
|
-
let ruleGroup = post ?
|
|
4792
|
+
const { RULES: RULES2 } = this;
|
|
4793
|
+
let ruleGroup = post ? RULES2.post : RULES2.rules.find(({ type: t }) => t === dataType);
|
|
4794
4794
|
if (!ruleGroup) {
|
|
4795
4795
|
ruleGroup = { type: dataType, rules: [] };
|
|
4796
|
-
|
|
4796
|
+
RULES2.rules.push(ruleGroup);
|
|
4797
4797
|
}
|
|
4798
|
-
|
|
4798
|
+
RULES2.keywords[keyword] = true;
|
|
4799
4799
|
if (!definition)
|
|
4800
4800
|
return;
|
|
4801
4801
|
const rule = {
|
|
@@ -4810,7 +4810,7 @@ var require_core = __commonJS({
|
|
|
4810
4810
|
addBeforeRule.call(this, ruleGroup, rule, definition.before);
|
|
4811
4811
|
else
|
|
4812
4812
|
ruleGroup.rules.push(rule);
|
|
4813
|
-
|
|
4813
|
+
RULES2.all[keyword] = rule;
|
|
4814
4814
|
(_a = definition.implements) === null || _a === void 0 ? void 0 : _a.forEach((kwd) => this.addKeyword(kwd));
|
|
4815
4815
|
}
|
|
4816
4816
|
function addBeforeRule(ruleGroup, rule, before) {
|
|
@@ -44727,6 +44727,77 @@ function withJsonSchema2020_12(transport2) {
|
|
|
44727
44727
|
return transport2;
|
|
44728
44728
|
}
|
|
44729
44729
|
|
|
44730
|
+
// src/utils/errorCodes.ts
|
|
44731
|
+
var CodedError = class extends Error {
|
|
44732
|
+
envelope;
|
|
44733
|
+
constructor(message, envelope) {
|
|
44734
|
+
super(message);
|
|
44735
|
+
this.name = "CodedError";
|
|
44736
|
+
this.envelope = envelope;
|
|
44737
|
+
}
|
|
44738
|
+
};
|
|
44739
|
+
var RULES = [
|
|
44740
|
+
{ code: "timeout_indeterminate", pattern: /timed out|\bETIMEDOUT\b/i },
|
|
44741
|
+
{
|
|
44742
|
+
code: "verification_failed",
|
|
44743
|
+
pattern: /\buncertain\b|may have (?:been|succeeded)|\baccepted (?:the|an) \w+, but|\bnot verified\b|Do not retry automatically|before any retry|read (?:the )?(?:exact )?(?:note|ID)\b[^.]*before retr/i
|
|
44744
|
+
},
|
|
44745
|
+
{
|
|
44746
|
+
code: "revision_conflict",
|
|
44747
|
+
pattern: /changed after it was read|revision changed|(?:pinned|note) state changed|changed during (?:read|preflight)|changed; read (?:it|the note) again|rich text do not match/i
|
|
44748
|
+
},
|
|
44749
|
+
{ code: "full_disk_access_missing", pattern: /Full Disk Access/i },
|
|
44750
|
+
{
|
|
44751
|
+
code: "shortcut_not_installed",
|
|
44752
|
+
pattern: /(?:Install|Import) the supplied|no such shortcut|Run apple-notes-mcp setup/i
|
|
44753
|
+
},
|
|
44754
|
+
{
|
|
44755
|
+
code: "not_found",
|
|
44756
|
+
pattern: /not found|does not exist|\bNo \w+ found\b|does not contain any checklist items|Can[’']t get (?:note|folder|account|attachment)|Cannot find note|Scope is absent/i
|
|
44757
|
+
},
|
|
44758
|
+
{ code: "ambiguous", pattern: /ambiguous|more than one|exactly once|Duplicate note IDs/i },
|
|
44759
|
+
{
|
|
44760
|
+
code: "notes_unavailable",
|
|
44761
|
+
pattern: /Notes\.app is (?:not responding|busy)|Lost connection to Notes|isn't running/i
|
|
44762
|
+
},
|
|
44763
|
+
{
|
|
44764
|
+
code: "unsupported",
|
|
44765
|
+
pattern: /password-protected|Locked notes|unsupported|not supported|is blocked|blocked because|has not passed live|refuses to sign|No (?:supported )?background|only one where|Real Notes link unavailable/i
|
|
44766
|
+
},
|
|
44767
|
+
{
|
|
44768
|
+
code: "validation_error",
|
|
44769
|
+
pattern: /\bis required\b|required\b|\bInvalid\b|\bmust\b|\bProvide\b|No (?:note IDs|reviewed notes) provided|response limit|Refusing to write|cannot be resolved|at most \d|between \d+ and \d+|supports the (?:end|default)|Use a distinctive|Use create-table|too large|equal cell counts|Folder path is empty/i
|
|
44770
|
+
}
|
|
44771
|
+
];
|
|
44772
|
+
var NOTHING_WRITTEN = /nothing (?:was )?(?:changed|created|written)|no replacement started|No content was (?:replaced|appended)|Nothing was created/i;
|
|
44773
|
+
var WRITE_ACCEPTED = /\baccepted (?:the|an) \w+, but/i;
|
|
44774
|
+
function classifyError(message, cause) {
|
|
44775
|
+
if (cause instanceof CodedError) return { ...cause.envelope };
|
|
44776
|
+
const text = cause instanceof Error && cause.message && !message.includes(cause.message) ? `${message}
|
|
44777
|
+
${cause.message}` : message;
|
|
44778
|
+
const timeoutCause = typeof cause === "object" && cause !== null && cause.code === "ETIMEDOUT";
|
|
44779
|
+
let code = "operation_failed";
|
|
44780
|
+
if (timeoutCause) code = "timeout_indeterminate";
|
|
44781
|
+
else if (isPermissionDenied(text)) code = "permission_denied";
|
|
44782
|
+
else code = RULES.find((rule) => rule.pattern.test(text))?.code ?? "operation_failed";
|
|
44783
|
+
const envelope = { code };
|
|
44784
|
+
if (code === "timeout_indeterminate" || code === "verification_failed") {
|
|
44785
|
+
envelope.indeterminate = true;
|
|
44786
|
+
if (WRITE_ACCEPTED.test(text)) envelope.committed = true;
|
|
44787
|
+
} else if (code === "revision_conflict" || NOTHING_WRITTEN.test(text)) {
|
|
44788
|
+
envelope.committed = false;
|
|
44789
|
+
envelope.indeterminate = false;
|
|
44790
|
+
}
|
|
44791
|
+
return envelope;
|
|
44792
|
+
}
|
|
44793
|
+
function errorResult(message, cause) {
|
|
44794
|
+
return {
|
|
44795
|
+
content: [{ type: "text", text: message }],
|
|
44796
|
+
structuredContent: classifyError(message, cause),
|
|
44797
|
+
isError: true
|
|
44798
|
+
};
|
|
44799
|
+
}
|
|
44800
|
+
|
|
44730
44801
|
// src/utils/shutdown.ts
|
|
44731
44802
|
var SHUTDOWN_DRAIN_TIMEOUT_MS = 2e3;
|
|
44732
44803
|
function createShutdown(stream, exit, timeoutMs = SHUTDOWN_DRAIN_TIMEOUT_MS) {
|
|
@@ -45047,15 +45118,7 @@ function registerDirectOperations(server2, manager) {
|
|
|
45047
45118
|
structuredContent: result
|
|
45048
45119
|
};
|
|
45049
45120
|
} catch (error2) {
|
|
45050
|
-
return
|
|
45051
|
-
content: [
|
|
45052
|
-
{
|
|
45053
|
-
type: "text",
|
|
45054
|
-
text: error2 instanceof Error ? error2.message : String(error2)
|
|
45055
|
-
}
|
|
45056
|
-
],
|
|
45057
|
-
isError: true
|
|
45058
|
-
};
|
|
45121
|
+
return errorResult(error2 instanceof Error ? error2.message : String(error2), error2);
|
|
45059
45122
|
}
|
|
45060
45123
|
})
|
|
45061
45124
|
);
|
|
@@ -45162,15 +45225,7 @@ function registerNativeTagsBridge(server2, manager) {
|
|
|
45162
45225
|
structuredContent: result
|
|
45163
45226
|
};
|
|
45164
45227
|
} catch (error2) {
|
|
45165
|
-
return
|
|
45166
|
-
content: [
|
|
45167
|
-
{
|
|
45168
|
-
type: "text",
|
|
45169
|
-
text: error2 instanceof Error ? error2.message : String(error2)
|
|
45170
|
-
}
|
|
45171
|
-
],
|
|
45172
|
-
isError: true
|
|
45173
|
-
};
|
|
45228
|
+
return errorResult(error2 instanceof Error ? error2.message : String(error2), error2);
|
|
45174
45229
|
}
|
|
45175
45230
|
})
|
|
45176
45231
|
);
|
|
@@ -45357,15 +45412,7 @@ function registerNativeOperations(server2, manager) {
|
|
|
45357
45412
|
structuredContent: result
|
|
45358
45413
|
};
|
|
45359
45414
|
} catch (error2) {
|
|
45360
|
-
return
|
|
45361
|
-
content: [
|
|
45362
|
-
{
|
|
45363
|
-
type: "text",
|
|
45364
|
-
text: error2 instanceof Error ? error2.message : "Operation failed"
|
|
45365
|
-
}
|
|
45366
|
-
],
|
|
45367
|
-
isError: true
|
|
45368
|
-
};
|
|
45415
|
+
return errorResult(error2 instanceof Error ? error2.message : "Operation failed", error2);
|
|
45369
45416
|
}
|
|
45370
45417
|
})
|
|
45371
45418
|
);
|
|
@@ -45759,11 +45806,8 @@ function successResponse(message, structured) {
|
|
|
45759
45806
|
if (structured) res.structuredContent = structured;
|
|
45760
45807
|
return res;
|
|
45761
45808
|
}
|
|
45762
|
-
function errorResponse(message) {
|
|
45763
|
-
return
|
|
45764
|
-
content: [{ type: "text", text: message }],
|
|
45765
|
-
isError: true
|
|
45766
|
-
};
|
|
45809
|
+
function errorResponse(message, cause) {
|
|
45810
|
+
return errorResult(message, cause);
|
|
45767
45811
|
}
|
|
45768
45812
|
function withErrorHandling(handler, errorPrefix) {
|
|
45769
45813
|
return async (params) => {
|
|
@@ -45771,7 +45815,7 @@ function withErrorHandling(handler, errorPrefix) {
|
|
|
45771
45815
|
return handler(params);
|
|
45772
45816
|
} catch (error2) {
|
|
45773
45817
|
const message = error2 instanceof Error ? error2.message : "Unknown error";
|
|
45774
|
-
return errorResponse(`${errorPrefix}: ${message}
|
|
45818
|
+
return errorResponse(`${errorPrefix}: ${message}`, error2);
|
|
45775
45819
|
}
|
|
45776
45820
|
};
|
|
45777
45821
|
}
|
package/package.json
CHANGED