apple-notes-mcp 2.7.1 → 2.7.3
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 +35 -5
- package/build/index.js +112 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1187,16 +1187,26 @@ When sending content containing backslashes (`\`) to this MCP server, **you must
|
|
|
1187
1187
|
```json
|
|
1188
1188
|
{
|
|
1189
1189
|
"title": "Install Script",
|
|
1190
|
-
"content": "cp ~/Library/Mobile
|
|
1190
|
+
"content": "cp ~/Library/Mobile\\ Documents/file.txt ~/.config/"
|
|
1191
1191
|
}
|
|
1192
1192
|
```
|
|
1193
|
+
→ arrives as: `cp ~/Library/Mobile\ Documents/file.txt ~/.config/`
|
|
1193
1194
|
|
|
1194
|
-
|
|
1195
|
+
In a JSON string literal the two characters `\\` denote **one** literal backslash. Doubling them to `\\\\` denotes *two* backslashes in the note, which is almost never what you want.
|
|
1196
|
+
|
|
1197
|
+
**Example - Literal double backslash:**
|
|
1198
|
+
```json
|
|
1199
|
+
{
|
|
1200
|
+
"title": "Escaping Notes",
|
|
1201
|
+
"content": "Send \\\\ only when you want two backslashes"
|
|
1202
|
+
}
|
|
1203
|
+
```
|
|
1204
|
+
→ arrives as: `Send \\ only when you want two backslashes`
|
|
1195
1205
|
|
|
1196
1206
|
**Common patterns requiring escaping:**
|
|
1197
|
-
- Shell escaped spaces: `Mobile\ Documents` → `Mobile
|
|
1198
|
-
-
|
|
1199
|
-
-
|
|
1207
|
+
- Shell escaped spaces: `Mobile\ Documents` → `Mobile\\ Documents` in JSON
|
|
1208
|
+
- Regex patterns: `\d+` → `\\d+` in JSON
|
|
1209
|
+
- Literal double backslash: `\\` → `\\\\` in JSON
|
|
1200
1210
|
|
|
1201
1211
|
**If you see errors** when creating/updating notes with backslashes, double-check that backslashes are properly escaped in the JSON payload.
|
|
1202
1212
|
|
|
@@ -1229,6 +1239,26 @@ The `\\\\` in JSON becomes `\\` in the actual string, which represents a single
|
|
|
1229
1239
|
- Apple Notes' internal HTML processing preserves empty divs from previous edits, so the gaps are baked into the note's internal representation and cannot be fixed through further updates
|
|
1230
1240
|
- Fix: delete the note with `delete-note` and create a fresh one with `create-note`
|
|
1231
1241
|
|
|
1242
|
+
### Every tool is refused: "invalid outputSchema … unsupported dialect"
|
|
1243
|
+
|
|
1244
|
+
If your client reports something like
|
|
1245
|
+
|
|
1246
|
+
```
|
|
1247
|
+
Tool 'list-notes' has an invalid outputSchema: JSON Schema declares an unsupported
|
|
1248
|
+
dialect ("$schema": "http://json-schema.org/draft-07/schema#"). The default
|
|
1249
|
+
validator supports JSON Schema 2020-12 only.
|
|
1250
|
+
```
|
|
1251
|
+
|
|
1252
|
+
you are on a version older than **2.7.2**. MCP standardized on JSON Schema
|
|
1253
|
+
2020-12, and every tool this server advertised carried the older draft-07
|
|
1254
|
+
dialect, so clients rejected all of them at once — nothing about your Notes
|
|
1255
|
+
library, permissions, or configuration is involved.
|
|
1256
|
+
|
|
1257
|
+
- Fix: upgrade to 2.7.2 or later. `npx -y apple-notes-mcp@latest` picks it up on
|
|
1258
|
+
the next launch; a marketplace install updates through the marketplace.
|
|
1259
|
+
- Running from a clone: `git pull && pnpm install && pnpm run build`, then
|
|
1260
|
+
restart the client.
|
|
1261
|
+
|
|
1232
1262
|
### `apple-notes` server fails to connect when run from a clone
|
|
1233
1263
|
- Launch `claude` from **inside the repo directory** so `CLAUDE_PROJECT_DIR` resolves to the repo root (the bare `.` fallback is unreliable — it points at the launching process's working directory)
|
|
1234
1264
|
- If you've been editing the source, rerun `pnpm run build` — the entrypoint is `${CLAUDE_PROJECT_DIR:-.}/build/index.js`, and the committed bundle only reflects your changes after a rebuild
|
package/build/index.js
CHANGED
|
@@ -42209,6 +42209,117 @@ function registerResourcesAndPrompts(server2, manager) {
|
|
|
42209
42209
|
);
|
|
42210
42210
|
}
|
|
42211
42211
|
|
|
42212
|
+
// src/utils/jsonSchemaDialect.ts
|
|
42213
|
+
var JSON_SCHEMA_2020_12 = "https://json-schema.org/draft/2020-12/schema";
|
|
42214
|
+
var DEFINITIONS_REF_PREFIX = "#/definitions/";
|
|
42215
|
+
var SCHEMA_MAP_KEYWORDS = /* @__PURE__ */ new Set([
|
|
42216
|
+
"properties",
|
|
42217
|
+
"patternProperties",
|
|
42218
|
+
"$defs",
|
|
42219
|
+
"dependentSchemas"
|
|
42220
|
+
]);
|
|
42221
|
+
var DATA_KEYWORDS = /* @__PURE__ */ new Set([
|
|
42222
|
+
"enum",
|
|
42223
|
+
"const",
|
|
42224
|
+
"default",
|
|
42225
|
+
"examples",
|
|
42226
|
+
"required",
|
|
42227
|
+
"dependentRequired"
|
|
42228
|
+
]);
|
|
42229
|
+
function isPlainObject3(value) {
|
|
42230
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
42231
|
+
}
|
|
42232
|
+
function convertSchemaMap(node) {
|
|
42233
|
+
if (!isPlainObject3(node)) return node;
|
|
42234
|
+
const out = {};
|
|
42235
|
+
for (const [name, subschema] of Object.entries(node)) out[name] = convertNode(subschema);
|
|
42236
|
+
return out;
|
|
42237
|
+
}
|
|
42238
|
+
function convertNode(node) {
|
|
42239
|
+
if (Array.isArray(node)) return node.map(convertNode);
|
|
42240
|
+
if (!isPlainObject3(node)) return node;
|
|
42241
|
+
const hasTupleItems = Array.isArray(node.items);
|
|
42242
|
+
const out = {};
|
|
42243
|
+
for (const [key, value] of Object.entries(node)) {
|
|
42244
|
+
switch (key) {
|
|
42245
|
+
case "$schema":
|
|
42246
|
+
break;
|
|
42247
|
+
case "definitions":
|
|
42248
|
+
out.$defs = convertSchemaMap(value);
|
|
42249
|
+
break;
|
|
42250
|
+
case "$ref":
|
|
42251
|
+
out.$ref = typeof value === "string" && value.startsWith(DEFINITIONS_REF_PREFIX) ? "#/$defs/" + value.slice(DEFINITIONS_REF_PREFIX.length) : value;
|
|
42252
|
+
break;
|
|
42253
|
+
case "items":
|
|
42254
|
+
if (hasTupleItems) out.prefixItems = value.map(convertNode);
|
|
42255
|
+
else out.items = convertNode(value);
|
|
42256
|
+
break;
|
|
42257
|
+
case "additionalItems":
|
|
42258
|
+
if (hasTupleItems) out.items = convertNode(value);
|
|
42259
|
+
break;
|
|
42260
|
+
case "dependencies": {
|
|
42261
|
+
const dependentRequired = {};
|
|
42262
|
+
const dependentSchemas = {};
|
|
42263
|
+
if (isPlainObject3(value)) {
|
|
42264
|
+
for (const [property, dependency] of Object.entries(value)) {
|
|
42265
|
+
if (Array.isArray(dependency)) dependentRequired[property] = dependency;
|
|
42266
|
+
else dependentSchemas[property] = convertNode(dependency);
|
|
42267
|
+
}
|
|
42268
|
+
}
|
|
42269
|
+
if (Object.keys(dependentRequired).length > 0) out.dependentRequired = dependentRequired;
|
|
42270
|
+
if (Object.keys(dependentSchemas).length > 0) out.dependentSchemas = dependentSchemas;
|
|
42271
|
+
break;
|
|
42272
|
+
}
|
|
42273
|
+
case "exclusiveMinimum":
|
|
42274
|
+
case "exclusiveMaximum": {
|
|
42275
|
+
const bound = key === "exclusiveMinimum" ? node.minimum : node.maximum;
|
|
42276
|
+
if (value === true && typeof bound === "number") out[key] = bound;
|
|
42277
|
+
else if (value !== false) out[key] = convertNode(value);
|
|
42278
|
+
break;
|
|
42279
|
+
}
|
|
42280
|
+
case "minimum":
|
|
42281
|
+
if (node.exclusiveMinimum === true) break;
|
|
42282
|
+
out.minimum = convertNode(value);
|
|
42283
|
+
break;
|
|
42284
|
+
case "maximum":
|
|
42285
|
+
if (node.exclusiveMaximum === true) break;
|
|
42286
|
+
out.maximum = convertNode(value);
|
|
42287
|
+
break;
|
|
42288
|
+
default:
|
|
42289
|
+
if (DATA_KEYWORDS.has(key)) out[key] = value;
|
|
42290
|
+
else if (SCHEMA_MAP_KEYWORDS.has(key)) out[key] = convertSchemaMap(value);
|
|
42291
|
+
else out[key] = convertNode(value);
|
|
42292
|
+
}
|
|
42293
|
+
}
|
|
42294
|
+
return out;
|
|
42295
|
+
}
|
|
42296
|
+
function toJsonSchema2020_12(schema) {
|
|
42297
|
+
if (!isPlainObject3(schema)) return schema;
|
|
42298
|
+
return {
|
|
42299
|
+
$schema: JSON_SCHEMA_2020_12,
|
|
42300
|
+
...convertNode(schema)
|
|
42301
|
+
};
|
|
42302
|
+
}
|
|
42303
|
+
function normalizeOutgoingMessage(message) {
|
|
42304
|
+
if (!isPlainObject3(message)) return message;
|
|
42305
|
+
const result = message.result;
|
|
42306
|
+
if (!isPlainObject3(result) || !Array.isArray(result.tools)) return message;
|
|
42307
|
+
const tools = result.tools.map((tool) => {
|
|
42308
|
+
if (!isPlainObject3(tool)) return tool;
|
|
42309
|
+
const next = { ...tool };
|
|
42310
|
+
if (isPlainObject3(tool.inputSchema)) next.inputSchema = toJsonSchema2020_12(tool.inputSchema);
|
|
42311
|
+
if (isPlainObject3(tool.outputSchema))
|
|
42312
|
+
next.outputSchema = toJsonSchema2020_12(tool.outputSchema);
|
|
42313
|
+
return next;
|
|
42314
|
+
});
|
|
42315
|
+
return { ...message, result: { ...result, tools } };
|
|
42316
|
+
}
|
|
42317
|
+
function withJsonSchema2020_12(transport2) {
|
|
42318
|
+
const originalSend = transport2.send.bind(transport2);
|
|
42319
|
+
transport2.send = (message, options) => originalSend(normalizeOutgoingMessage(message), options);
|
|
42320
|
+
return transport2;
|
|
42321
|
+
}
|
|
42322
|
+
|
|
42212
42323
|
// src/index.ts
|
|
42213
42324
|
loadFileConfig();
|
|
42214
42325
|
var require2 = createRequire(import.meta.url);
|
|
@@ -43747,7 +43858,7 @@ for (const sig of ["SIGINT", "SIGTERM"]) {
|
|
|
43747
43858
|
}
|
|
43748
43859
|
process.stdin.on("end", shutdown);
|
|
43749
43860
|
process.stdin.on("close", shutdown);
|
|
43750
|
-
var transport = new StdioServerTransport();
|
|
43861
|
+
var transport = withJsonSchema2020_12(new StdioServerTransport());
|
|
43751
43862
|
await server.connect(transport);
|
|
43752
43863
|
/*! Bundled license information:
|
|
43753
43864
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apple-notes-mcp",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.3",
|
|
4
4
|
"description": "MCP server for Apple Notes - create, search, update, and manage notes via Claude and other AI assistants",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
54
54
|
"@typescript-eslint/parser": "^8.0.0",
|
|
55
55
|
"@vitest/coverage-v8": "^3.2.6",
|
|
56
|
+
"ajv": "^8.17.1",
|
|
56
57
|
"esbuild": "^0.28.1",
|
|
57
58
|
"eslint": "^9.0.0",
|
|
58
59
|
"globals": "^17.0.0",
|