@goforgeit/mcp-apple-notes 0.5.2

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/LICENSE ADDED
@@ -0,0 +1,50 @@
1
+ Forge
2
+ Copyright (c) 2025 Prometheus Group LLC. All Rights Reserved.
3
+
4
+ PROPRIETARY LICENSE
5
+
6
+ This software and associated documentation files (the "Software") are the
7
+ exclusive property of Prometheus Group LLC. The Software is protected by
8
+ copyright laws and international treaty provisions.
9
+
10
+ GRANT OF ACCESS
11
+
12
+ Access to this Software is granted solely for the purpose of evaluation,
13
+ testing, and providing feedback to Prometheus Group LLC. This access does
14
+ not constitute a transfer of ownership, license to use commercially, or
15
+ any other rights not expressly stated herein.
16
+
17
+ RESTRICTIONS
18
+
19
+ You may NOT:
20
+ - Use the Software for commercial purposes without explicit written permission
21
+ - Copy, modify, merge, publish, distribute, sublicense, or sell copies of the Software
22
+ - Reverse engineer, decompile, or disassemble the Software
23
+ - Remove or alter any proprietary notices, labels, or marks on the Software
24
+ - Claim ownership or authorship of the Software or any derivative works
25
+
26
+ FEEDBACK
27
+
28
+ Any feedback, suggestions, ideas, or improvements you provide regarding the
29
+ Software shall become the exclusive property of Prometheus Group LLC. You
30
+ hereby assign all rights, title, and interest in such feedback to Prometheus
31
+ Group LLC without any obligation of compensation or attribution.
32
+
33
+ NO WARRANTY
34
+
35
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
38
+ PROMETHEUS GROUP LLC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
39
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
40
+ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41
+
42
+ TERMINATION
43
+
44
+ This access may be terminated at any time by Prometheus Group LLC without
45
+ prior notice. Upon termination, you must destroy all copies of the Software
46
+ in your possession.
47
+
48
+ CONTACT
49
+
50
+ For licensing inquiries, please visit: https://goforgeit.com
@@ -0,0 +1,18 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+
3
+ /**
4
+ * @goforgeit/mcp-apple-notes
5
+ *
6
+ * Forge MCP server for Apple Notes on macOS.
7
+ * Lists, searches, reads, and creates notes via AppleScript.
8
+ */
9
+
10
+ interface AppleNotesMCPServer {
11
+ server: McpServer;
12
+ getRegisteredTools(): string[];
13
+ start(): Promise<void>;
14
+ }
15
+ declare function runAppleScript(script: string): Promise<string>;
16
+ declare function createAppleNotesMCPServer(): AppleNotesMCPServer;
17
+
18
+ export { type AppleNotesMCPServer, createAppleNotesMCPServer, runAppleScript };
package/dist/index.js ADDED
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+ import { z } from "zod";
7
+ import { execFile } from "child_process";
8
+ import { promisify } from "util";
9
+ var execFileAsync = promisify(execFile);
10
+ async function runAppleScript(script) {
11
+ const { stdout } = await execFileAsync("osascript", ["-e", script]);
12
+ return stdout.trim();
13
+ }
14
+ function createAppleNotesMCPServer() {
15
+ const server = new McpServer({
16
+ name: "@goforgeit/mcp-apple-notes",
17
+ version: "0.1.0"
18
+ });
19
+ const registeredTools = [];
20
+ server.tool(
21
+ "list_notes",
22
+ "List notes from Apple Notes app with optional folder filtering",
23
+ {
24
+ folder: z.string().optional().describe('Folder name to filter notes (e.g., "Notes", "Work")'),
25
+ limit: z.number().optional().default(20).describe("Maximum number of notes to return")
26
+ },
27
+ async ({ folder, limit }) => {
28
+ const folderClause = folder ? `notes of folder ${JSON.stringify(folder)}` : "notes";
29
+ const script = `
30
+ tell application "Notes"
31
+ set notesList to {}
32
+ set targetNotes to ${folderClause}
33
+ set noteCount to 0
34
+ repeat with aNote in targetNotes
35
+ if noteCount < ${limit} then
36
+ set noteInfo to "{\\"name\\":\\"" & (name of aNote as string) & "\\",\\"id\\":\\"" & (id of aNote as string) & "\\",\\"creation_date\\":\\"" & (creation date of aNote as string) & "\\",\\"modification_date\\":\\"" & (modification date of aNote as string) & "\\"}"
37
+ set end of notesList to noteInfo
38
+ set noteCount to noteCount + 1
39
+ else
40
+ exit repeat
41
+ end if
42
+ end repeat
43
+ return "[" & my joinList(notesList, ",") & "]"
44
+ end tell
45
+
46
+ on joinList(theList, delimiter)
47
+ set AppleScript's text item delimiters to delimiter
48
+ set theString to theList as string
49
+ set AppleScript's text item delimiters to ""
50
+ return theString
51
+ end joinList
52
+ `;
53
+ try {
54
+ const results = await runAppleScript(script);
55
+ return { content: [{ type: "text", text: results }] };
56
+ } catch (error) {
57
+ return {
58
+ content: [
59
+ {
60
+ type: "text",
61
+ text: `Failed to list notes: ${error instanceof Error ? error.message : String(error)}`
62
+ }
63
+ ],
64
+ isError: true
65
+ };
66
+ }
67
+ }
68
+ );
69
+ registeredTools.push("list_notes");
70
+ server.tool(
71
+ "get_note",
72
+ "Get the full content of a specific note by name",
73
+ {
74
+ note_name: z.string().describe("Name of the note to retrieve"),
75
+ folder: z.string().optional().describe("Folder where the note is located")
76
+ },
77
+ async ({ note_name, folder }) => {
78
+ const targetClause = folder ? `first note of folder ${JSON.stringify(folder)} whose name is ${JSON.stringify(note_name)}` : `first note whose name is ${JSON.stringify(note_name)}`;
79
+ const script = `
80
+ tell application "Notes"
81
+ set targetNote to ${targetClause}
82
+ set noteName to name of targetNote as string
83
+ set noteBody to body of targetNote as string
84
+ set noteId to id of targetNote as string
85
+ set noteCreated to creation date of targetNote as string
86
+ set noteModified to modification date of targetNote as string
87
+ return "{\\"name\\":\\"" & noteName & "\\",\\"id\\":\\"" & noteId & "\\",\\"creation_date\\":\\"" & noteCreated & "\\",\\"modification_date\\":\\"" & noteModified & "\\",\\"body\\":\\"" & noteBody & "\\"}"
88
+ end tell
89
+ `;
90
+ try {
91
+ const result = await runAppleScript(script);
92
+ return { content: [{ type: "text", text: result }] };
93
+ } catch (error) {
94
+ return {
95
+ content: [
96
+ {
97
+ type: "text",
98
+ text: `Failed to get note: ${error instanceof Error ? error.message : String(error)}`
99
+ }
100
+ ],
101
+ isError: true
102
+ };
103
+ }
104
+ }
105
+ );
106
+ registeredTools.push("get_note");
107
+ server.tool(
108
+ "search_notes",
109
+ "Search notes by text query across all folders",
110
+ {
111
+ query: z.string().describe("Text to search for in note names and bodies"),
112
+ limit: z.number().optional().default(10).describe("Maximum number of results to return")
113
+ },
114
+ async ({ query, limit }) => {
115
+ const script = `
116
+ tell application "Notes"
117
+ set notesList to {}
118
+ set noteCount to 0
119
+ repeat with aNote in notes
120
+ if noteCount < ${limit} then
121
+ set noteName to name of aNote as string
122
+ set noteBody to plaintext of aNote as string
123
+ if noteName contains ${JSON.stringify(query)} or noteBody contains ${JSON.stringify(query)} then
124
+ set noteInfo to "{\\"name\\":\\"" & noteName & "\\",\\"id\\":\\"" & (id of aNote as string) & "\\",\\"creation_date\\":\\"" & (creation date of aNote as string) & "\\",\\"modification_date\\":\\"" & (modification date of aNote as string) & "\\"}"
125
+ set end of notesList to noteInfo
126
+ set noteCount to noteCount + 1
127
+ end if
128
+ else
129
+ exit repeat
130
+ end if
131
+ end repeat
132
+ return "[" & my joinList(notesList, ",") & "]"
133
+ end tell
134
+
135
+ on joinList(theList, delimiter)
136
+ set AppleScript's text item delimiters to delimiter
137
+ set theString to theList as string
138
+ set AppleScript's text item delimiters to ""
139
+ return theString
140
+ end joinList
141
+ `;
142
+ try {
143
+ const results = await runAppleScript(script);
144
+ return { content: [{ type: "text", text: results }] };
145
+ } catch (error) {
146
+ return {
147
+ content: [
148
+ {
149
+ type: "text",
150
+ text: `Failed to search notes: ${error instanceof Error ? error.message : String(error)}`
151
+ }
152
+ ],
153
+ isError: true
154
+ };
155
+ }
156
+ }
157
+ );
158
+ registeredTools.push("search_notes");
159
+ server.tool(
160
+ "create_note",
161
+ "Create a new note in Apple Notes",
162
+ {
163
+ title: z.string().describe("Title of the new note"),
164
+ body: z.string().describe("Content/body of the new note"),
165
+ folder: z.string().optional().default("Notes").describe("Folder to create the note in")
166
+ },
167
+ async ({ title, body, folder }) => {
168
+ const script = `
169
+ tell application "Notes"
170
+ set targetFolder to folder ${JSON.stringify(folder)}
171
+ set newNote to make new note at targetFolder with properties {name:${JSON.stringify(title)}, body:${JSON.stringify(body)}}
172
+ return "Note created successfully: " & (name of newNote as string)
173
+ end tell
174
+ `;
175
+ try {
176
+ const result = await runAppleScript(script);
177
+ return { content: [{ type: "text", text: result }] };
178
+ } catch (error) {
179
+ return {
180
+ content: [
181
+ {
182
+ type: "text",
183
+ text: `Failed to create note: ${error instanceof Error ? error.message : String(error)}`
184
+ }
185
+ ],
186
+ isError: true
187
+ };
188
+ }
189
+ }
190
+ );
191
+ registeredTools.push("create_note");
192
+ server.tool("list_folders", "List all folders in Apple Notes", {}, async () => {
193
+ const script = `
194
+ tell application "Notes"
195
+ set foldersList to {}
196
+ repeat with aFolder in folders
197
+ set folderInfo to "{\\"name\\":\\"" & (name of aFolder as string) & "\\",\\"id\\":\\"" & (id of aFolder as string) & "\\",\\"note_count\\":" & (count of notes of aFolder) & "}"
198
+ set end of foldersList to folderInfo
199
+ end repeat
200
+ return "[" & my joinList(foldersList, ",") & "]"
201
+ end tell
202
+
203
+ on joinList(theList, delimiter)
204
+ set AppleScript's text item delimiters to delimiter
205
+ set theString to theList as string
206
+ set AppleScript's text item delimiters to ""
207
+ return theString
208
+ end joinList
209
+ `;
210
+ try {
211
+ const results = await runAppleScript(script);
212
+ return { content: [{ type: "text", text: results }] };
213
+ } catch (error) {
214
+ return {
215
+ content: [
216
+ {
217
+ type: "text",
218
+ text: `Failed to list folders: ${error instanceof Error ? error.message : String(error)}`
219
+ }
220
+ ],
221
+ isError: true
222
+ };
223
+ }
224
+ });
225
+ registeredTools.push("list_folders");
226
+ return {
227
+ server,
228
+ getRegisteredTools() {
229
+ return [...registeredTools];
230
+ },
231
+ async start() {
232
+ const transport = new StdioServerTransport();
233
+ await server.connect(transport);
234
+ }
235
+ };
236
+ }
237
+ var isMainModule = process.argv[1] && import.meta.url.endsWith(process.argv[1].replace(/\\/g, "/"));
238
+ if (isMainModule || process.env.FORGE_MCP_START === "true") {
239
+ const mcpServer = createAppleNotesMCPServer();
240
+ mcpServer.start().catch((err) => {
241
+ console.error("Failed to start Apple Notes MCP server:", err);
242
+ process.exit(1);
243
+ });
244
+ }
245
+ export {
246
+ createAppleNotesMCPServer,
247
+ runAppleScript
248
+ };
249
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @goforgeit/mcp-apple-notes\n *\n * Forge MCP server for Apple Notes on macOS.\n * Lists, searches, reads, and creates notes via AppleScript.\n */\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport { execFile } from 'child_process';\nimport { promisify } from 'util';\n\nconst execFileAsync = promisify(execFile);\n\nexport interface AppleNotesMCPServer {\n server: McpServer;\n getRegisteredTools(): string[];\n start(): Promise<void>;\n}\n\nexport async function runAppleScript(script: string): Promise<string> {\n const { stdout } = await execFileAsync('osascript', ['-e', script]);\n return stdout.trim();\n}\n\nexport function createAppleNotesMCPServer(): AppleNotesMCPServer {\n const server = new McpServer({\n name: '@goforgeit/mcp-apple-notes',\n version: '0.1.0',\n });\n\n const registeredTools: string[] = [];\n\n // --- list_notes ---\n server.tool(\n 'list_notes',\n 'List notes from Apple Notes app with optional folder filtering',\n {\n folder: z.string().optional().describe('Folder name to filter notes (e.g., \"Notes\", \"Work\")'),\n limit: z.number().optional().default(20).describe('Maximum number of notes to return'),\n },\n async ({ folder, limit }) => {\n const folderClause = folder ? `notes of folder ${JSON.stringify(folder)}` : 'notes';\n\n const script = `\n tell application \"Notes\"\n set notesList to {}\n set targetNotes to ${folderClause}\n set noteCount to 0\n repeat with aNote in targetNotes\n if noteCount < ${limit} then\n set noteInfo to \"{\\\\\"name\\\\\":\\\\\"\" & (name of aNote as string) & \"\\\\\",\\\\\"id\\\\\":\\\\\"\" & (id of aNote as string) & \"\\\\\",\\\\\"creation_date\\\\\":\\\\\"\" & (creation date of aNote as string) & \"\\\\\",\\\\\"modification_date\\\\\":\\\\\"\" & (modification date of aNote as string) & \"\\\\\"}\"\n set end of notesList to noteInfo\n set noteCount to noteCount + 1\n else\n exit repeat\n end if\n end repeat\n return \"[\" & my joinList(notesList, \",\") & \"]\"\n end tell\n\n on joinList(theList, delimiter)\n set AppleScript's text item delimiters to delimiter\n set theString to theList as string\n set AppleScript's text item delimiters to \"\"\n return theString\n end joinList\n `;\n\n try {\n const results = await runAppleScript(script);\n return { content: [{ type: 'text' as const, text: results }] };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to list notes: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n registeredTools.push('list_notes');\n\n // --- get_note ---\n server.tool(\n 'get_note',\n 'Get the full content of a specific note by name',\n {\n note_name: z.string().describe('Name of the note to retrieve'),\n folder: z.string().optional().describe('Folder where the note is located'),\n },\n async ({ note_name, folder }) => {\n const targetClause = folder\n ? `first note of folder ${JSON.stringify(folder)} whose name is ${JSON.stringify(note_name)}`\n : `first note whose name is ${JSON.stringify(note_name)}`;\n\n const script = `\n tell application \"Notes\"\n set targetNote to ${targetClause}\n set noteName to name of targetNote as string\n set noteBody to body of targetNote as string\n set noteId to id of targetNote as string\n set noteCreated to creation date of targetNote as string\n set noteModified to modification date of targetNote as string\n return \"{\\\\\"name\\\\\":\\\\\"\" & noteName & \"\\\\\",\\\\\"id\\\\\":\\\\\"\" & noteId & \"\\\\\",\\\\\"creation_date\\\\\":\\\\\"\" & noteCreated & \"\\\\\",\\\\\"modification_date\\\\\":\\\\\"\" & noteModified & \"\\\\\",\\\\\"body\\\\\":\\\\\"\" & noteBody & \"\\\\\"}\"\n end tell\n `;\n\n try {\n const result = await runAppleScript(script);\n return { content: [{ type: 'text' as const, text: result }] };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to get note: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n registeredTools.push('get_note');\n\n // --- search_notes ---\n server.tool(\n 'search_notes',\n 'Search notes by text query across all folders',\n {\n query: z.string().describe('Text to search for in note names and bodies'),\n limit: z.number().optional().default(10).describe('Maximum number of results to return'),\n },\n async ({ query, limit }) => {\n const script = `\n tell application \"Notes\"\n set notesList to {}\n set noteCount to 0\n repeat with aNote in notes\n if noteCount < ${limit} then\n set noteName to name of aNote as string\n set noteBody to plaintext of aNote as string\n if noteName contains ${JSON.stringify(query)} or noteBody contains ${JSON.stringify(query)} then\n set noteInfo to \"{\\\\\"name\\\\\":\\\\\"\" & noteName & \"\\\\\",\\\\\"id\\\\\":\\\\\"\" & (id of aNote as string) & \"\\\\\",\\\\\"creation_date\\\\\":\\\\\"\" & (creation date of aNote as string) & \"\\\\\",\\\\\"modification_date\\\\\":\\\\\"\" & (modification date of aNote as string) & \"\\\\\"}\"\n set end of notesList to noteInfo\n set noteCount to noteCount + 1\n end if\n else\n exit repeat\n end if\n end repeat\n return \"[\" & my joinList(notesList, \",\") & \"]\"\n end tell\n\n on joinList(theList, delimiter)\n set AppleScript's text item delimiters to delimiter\n set theString to theList as string\n set AppleScript's text item delimiters to \"\"\n return theString\n end joinList\n `;\n\n try {\n const results = await runAppleScript(script);\n return { content: [{ type: 'text' as const, text: results }] };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to search notes: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n registeredTools.push('search_notes');\n\n // --- create_note ---\n server.tool(\n 'create_note',\n 'Create a new note in Apple Notes',\n {\n title: z.string().describe('Title of the new note'),\n body: z.string().describe('Content/body of the new note'),\n folder: z.string().optional().default('Notes').describe('Folder to create the note in'),\n },\n async ({ title, body, folder }) => {\n const script = `\n tell application \"Notes\"\n set targetFolder to folder ${JSON.stringify(folder)}\n set newNote to make new note at targetFolder with properties {name:${JSON.stringify(title)}, body:${JSON.stringify(body)}}\n return \"Note created successfully: \" & (name of newNote as string)\n end tell\n `;\n\n try {\n const result = await runAppleScript(script);\n return { content: [{ type: 'text' as const, text: result }] };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to create note: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n registeredTools.push('create_note');\n\n // --- list_folders ---\n server.tool('list_folders', 'List all folders in Apple Notes', {}, async () => {\n const script = `\n tell application \"Notes\"\n set foldersList to {}\n repeat with aFolder in folders\n set folderInfo to \"{\\\\\"name\\\\\":\\\\\"\" & (name of aFolder as string) & \"\\\\\",\\\\\"id\\\\\":\\\\\"\" & (id of aFolder as string) & \"\\\\\",\\\\\"note_count\\\\\":\" & (count of notes of aFolder) & \"}\"\n set end of foldersList to folderInfo\n end repeat\n return \"[\" & my joinList(foldersList, \",\") & \"]\"\n end tell\n\n on joinList(theList, delimiter)\n set AppleScript's text item delimiters to delimiter\n set theString to theList as string\n set AppleScript's text item delimiters to \"\"\n return theString\n end joinList\n `;\n\n try {\n const results = await runAppleScript(script);\n return { content: [{ type: 'text' as const, text: results }] };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to list folders: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n });\n registeredTools.push('list_folders');\n\n return {\n server,\n getRegisteredTools() {\n return [...registeredTools];\n },\n async start() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n },\n };\n}\n\n// CLI entry point\nconst isMainModule =\n process.argv[1] && import.meta.url.endsWith(process.argv[1].replace(/\\\\/g, '/'));\n\nif (isMainModule || process.env.FORGE_MCP_START === 'true') {\n const mcpServer = createAppleNotesMCPServer();\n mcpServer.start().catch((err) => {\n console.error('Failed to start Apple Notes MCP server:', err);\n process.exit(1);\n });\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@goforgeit/mcp-apple-notes",
3
+ "version": "0.5.2",
4
+ "type": "module",
5
+ "description": "Forge MCP server for Apple Notes — list, search, read, and create notes via macOS Notes app",
6
+ "bin": {
7
+ "mcp-apple-notes": "./dist/index.js"
8
+ },
9
+ "main": "dist/index.js",
10
+ "types": "dist/index.d.ts",
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "dependencies": {
19
+ "@modelcontextprotocol/sdk": "^1.12.1",
20
+ "zod": "^4.2.1"
21
+ },
22
+ "devDependencies": {
23
+ "@types/node": "^22.10.2",
24
+ "tsup": "^8.0.0",
25
+ "vitest": "^3.2.4"
26
+ },
27
+ "os": [
28
+ "darwin"
29
+ ],
30
+ "engines": {
31
+ "node": ">=18.0.0"
32
+ },
33
+ "scripts": {
34
+ "build": "tsup",
35
+ "typecheck": "tsc --noEmit",
36
+ "test": "vitest run"
37
+ }
38
+ }