apple-notes-mcp 2.5.2 → 2.5.4

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 CHANGED
@@ -6,6 +6,7 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that e
6
6
  [![npm downloads](https://img.shields.io/npm/dm/apple-notes-mcp)](https://www.npmjs.com/package/apple-notes-mcp)
7
7
  [![node](https://img.shields.io/node/v/apple-notes-mcp)](https://www.npmjs.com/package/apple-notes-mcp)
8
8
  [![CI](https://github.com/sweetrb/apple-notes-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/sweetrb/apple-notes-mcp/actions/workflows/ci.yml)
9
+ [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/sweetrb/apple-notes-mcp/badge)](https://scorecard.dev/viewer/?uri=github.com/sweetrb/apple-notes-mcp)
9
10
  [![platform: macOS](https://img.shields.io/badge/platform-macOS-111?logo=apple&logoColor=white)](https://www.apple.com/macos/)
10
11
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
11
12
  [![MCP](https://img.shields.io/badge/MCP-server-blue)](https://modelcontextprotocol.io)
package/build/index.js CHANGED
@@ -1303,5 +1303,16 @@ server.registerTool("get-note-metadata", {
1303
1303
  */
1304
1304
  // Register read-only resources and workflow prompts (#23).
1305
1305
  registerResourcesAndPrompts(server, notesManager);
1306
+ // Defense-in-depth: an unhandled rejection or a stray EventEmitter "error" must
1307
+ // never take down this long-lived MCP server. EPIPE on stdout means the MCP
1308
+ // client disconnected — exit cleanly rather than crash.
1309
+ process.on("uncaughtException", (err) => {
1310
+ if (err?.code === "EPIPE")
1311
+ process.exit(0);
1312
+ console.error("[uncaughtException]", err);
1313
+ });
1314
+ process.on("unhandledRejection", (reason) => {
1315
+ console.error("[unhandledRejection]", reason);
1316
+ });
1306
1317
  const transport = new StdioServerTransport();
1307
1318
  await server.connect(transport);
@@ -2436,11 +2436,21 @@ export class AppleNotesManager {
2436
2436
  * Simple HTML to plaintext conversion for export.
2437
2437
  */
2438
2438
  htmlToPlaintext(html) {
2439
- return (html
2439
+ // Convert block/line breaks to newlines first.
2440
+ let text = html
2440
2441
  .replace(/<br\s*\/?>/gi, "\n")
2441
2442
  .replace(/<\/div>/gi, "\n")
2442
- .replace(/<\/p>/gi, "\n")
2443
- .replace(/<[^>]+>/g, "")
2443
+ .replace(/<\/p>/gi, "\n");
2444
+ // Strip any remaining tags, looping until the string stabilizes. A single
2445
+ // pass can leave residue when removing one tag re-forms another (e.g.
2446
+ // "<<i>>"), so we repeat until there are no more matches — the recognized
2447
+ // fix for CodeQL js/incomplete-multi-character-sanitization.
2448
+ let prev;
2449
+ do {
2450
+ prev = text;
2451
+ text = text.replace(/<[^>]*>/g, "");
2452
+ } while (text !== prev);
2453
+ return (text
2444
2454
  .replace(/&nbsp;/g, " ")
2445
2455
  .replace(/&lt;/g, "<")
2446
2456
  .replace(/&gt;/g, ">")
@@ -2402,4 +2402,11 @@ describe("htmlToPlaintext (export helper)", () => {
2402
2402
  expect(toPlaintext("a<br><br><br><br>b")).toBe("a\n\nb");
2403
2403
  expect(toPlaintext(" <div>x</div> ")).toBe("x");
2404
2404
  });
2405
+ it("strips nested/overlapping tags without leaving a tag (iterated strip)", () => {
2406
+ // A single pass can leave residue when removing one tag re-forms another;
2407
+ // the loop keeps stripping until no <...> remains.
2408
+ expect(toPlaintext("a<<i>>b")).not.toMatch(/<[^>]*>/);
2409
+ expect(toPlaintext("<x<y>z>")).not.toMatch(/<[^>]*>/);
2410
+ expect(toPlaintext("plain <b>text</b> here")).toBe("plain text here");
2411
+ });
2405
2412
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apple-notes-mcp",
3
- "version": "2.5.2",
3
+ "version": "2.5.4",
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",