@noteplanco/noteplan-mcp 1.1.7 → 1.1.9
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/dist/noteplan/embeddings.d.ts +8 -0
- package/dist/noteplan/embeddings.d.ts.map +1 -1
- package/dist/noteplan/embeddings.js +3 -3
- package/dist/noteplan/embeddings.js.map +1 -1
- package/dist/noteplan/file-reader.d.ts +6 -0
- package/dist/noteplan/file-reader.d.ts.map +1 -1
- package/dist/noteplan/file-reader.js +15 -0
- package/dist/noteplan/file-reader.js.map +1 -1
- package/dist/noteplan/file-writer.d.ts.map +1 -1
- package/dist/noteplan/file-writer.js +13 -1
- package/dist/noteplan/file-writer.js.map +1 -1
- package/dist/noteplan/file-writer.test.js +4 -0
- package/dist/noteplan/file-writer.test.js.map +1 -1
- package/dist/noteplan/frontmatter-parser.d.ts +4 -4
- package/dist/noteplan/frontmatter-parser.d.ts.map +1 -1
- package/dist/noteplan/frontmatter-parser.js +11 -14
- package/dist/noteplan/frontmatter-parser.js.map +1 -1
- package/dist/noteplan/frontmatter-parser.test.js +92 -0
- package/dist/noteplan/frontmatter-parser.test.js.map +1 -1
- package/dist/noteplan/markdown-parser.d.ts.map +1 -1
- package/dist/noteplan/markdown-parser.js +4 -2
- package/dist/noteplan/markdown-parser.js.map +1 -1
- package/dist/noteplan/markdown-parser.test.js +129 -0
- package/dist/noteplan/markdown-parser.test.js.map +1 -1
- package/dist/noteplan/sqlite-loader.d.ts +11 -2
- package/dist/noteplan/sqlite-loader.d.ts.map +1 -1
- package/dist/noteplan/sqlite-loader.js +143 -15
- package/dist/noteplan/sqlite-loader.js.map +1 -1
- package/dist/noteplan/sqlite-writer.d.ts.map +1 -1
- package/dist/noteplan/sqlite-writer.js +3 -0
- package/dist/noteplan/sqlite-writer.js.map +1 -1
- package/dist/noteplan/template-docs.d.ts +35 -0
- package/dist/noteplan/template-docs.d.ts.map +1 -0
- package/dist/noteplan/template-docs.js +184 -0
- package/dist/noteplan/template-docs.js.map +1 -0
- package/dist/noteplan/unified-store.d.ts +2 -0
- package/dist/noteplan/unified-store.d.ts.map +1 -1
- package/dist/noteplan/unified-store.js +30 -7
- package/dist/noteplan/unified-store.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +307 -65
- package/dist/server.js.map +1 -1
- package/dist/tools/calendar.d.ts +2 -2
- package/dist/tools/events.d.ts +16 -16
- package/dist/tools/events.d.ts.map +1 -1
- package/dist/tools/events.js +17 -2
- package/dist/tools/events.js.map +1 -1
- package/dist/tools/notes.d.ts +327 -45
- package/dist/tools/notes.d.ts.map +1 -1
- package/dist/tools/notes.js +391 -51
- package/dist/tools/notes.js.map +1 -1
- package/dist/tools/notes.test.js +959 -1
- package/dist/tools/notes.test.js.map +1 -1
- package/dist/tools/plugins.d.ts.map +1 -1
- package/dist/tools/plugins.js +1 -0
- package/dist/tools/plugins.js.map +1 -1
- package/dist/tools/search.d.ts +2 -2
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +32 -4
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/tasks.d.ts +86 -10
- package/dist/tools/tasks.d.ts.map +1 -1
- package/dist/tools/tasks.js +84 -25
- package/dist/tools/tasks.js.map +1 -1
- package/dist/tools/templates.d.ts +64 -3
- package/dist/tools/templates.d.ts.map +1 -1
- package/dist/tools/templates.js +73 -1
- package/dist/tools/templates.js.map +1 -1
- package/dist/tools/ui-automation.d.ts +74 -0
- package/dist/tools/ui-automation.d.ts.map +1 -0
- package/dist/tools/ui-automation.js +209 -0
- package/dist/tools/ui-automation.js.map +1 -0
- package/dist/utils/version.d.ts +1 -0
- package/dist/utils/version.d.ts.map +1 -1
- package/dist/utils/version.js +89 -27
- package/dist/utils/version.js.map +1 -1
- package/docs/templates.db.gz +0 -0
- package/docs/x-callback-url.md +318 -0
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -24,9 +24,14 @@ import * as attachmentTools from './tools/attachments.js';
|
|
|
24
24
|
import { parseFlexibleDate } from './utils/date-utils.js';
|
|
25
25
|
import { upgradeMessage, getNotePlanVersion, getMcpServerVersion, MIN_BUILD_ADVANCED_FEATURES, MIN_BUILD_CREATE_BACKUP } from './utils/version.js';
|
|
26
26
|
import { initSqlite } from './noteplan/sqlite-loader.js';
|
|
27
|
+
import { getDatabase, getDatabasePath, listSpaces as listSpacesFromDb } from './noteplan/sqlite-reader.js';
|
|
27
28
|
const __filename = fileURLToPath(import.meta.url);
|
|
28
29
|
const __dirname = path.dirname(__filename);
|
|
29
30
|
const PLUGIN_API_DOCS_DIR = path.join(__dirname, '../docs/plugin-api');
|
|
31
|
+
const DOCS_DIR = path.join(__dirname, '../docs');
|
|
32
|
+
const GENERAL_DOC_RESOURCES = [
|
|
33
|
+
{ file: 'x-callback-url.md', name: 'x-callback-url Reference', desc: 'NotePlan URL scheme — all actions (openNote, addText, addNote, addQuickTask, search, runPlugin, etc.), parameters, and encoding examples' },
|
|
34
|
+
];
|
|
30
35
|
const PLUGIN_API_RESOURCES = [
|
|
31
36
|
{ file: 'plugin-api-condensed.md', name: 'Plugin API Reference (Condensed)', desc: 'Complete NotePlan plugin API — all signatures, types, and patterns in one reference. Read this first.' },
|
|
32
37
|
{ file: 'getting-started.md', name: 'Getting Started Guide', desc: 'How to create NotePlan plugins — structure, setup, first plugin, testing, HTML views' },
|
|
@@ -818,12 +823,59 @@ function withDuration(result, durationMs, includeTiming) {
|
|
|
818
823
|
export function createServer() {
|
|
819
824
|
const server = new Server({
|
|
820
825
|
name: 'NotePlan',
|
|
821
|
-
version: '1.1.
|
|
826
|
+
version: '1.1.7',
|
|
822
827
|
}, {
|
|
823
828
|
capabilities: {
|
|
824
829
|
tools: {},
|
|
825
830
|
resources: {},
|
|
826
831
|
},
|
|
832
|
+
instructions: [
|
|
833
|
+
'You have access to NotePlan — a markdown-based note-taking and task management app for macOS/iOS.',
|
|
834
|
+
'All tools use action-based dispatch: one tool per domain, with an `action` parameter to select the operation.',
|
|
835
|
+
'',
|
|
836
|
+
'## Workflow',
|
|
837
|
+
'',
|
|
838
|
+
'Prefer granular edits over full-note rewrites to avoid large context payloads and accidental data loss.',
|
|
839
|
+
'',
|
|
840
|
+
'1. **Find** the note: `noteplan_get_notes` (by id/title/filename/date) or `noteplan_search`',
|
|
841
|
+
'2. **Inspect** content: `noteplan_paragraphs(action: get)` for line metadata, `noteplan_paragraphs(action: search)` for text lookup',
|
|
842
|
+
'3. **Edit** with targeted mutations:',
|
|
843
|
+
' - `noteplan_edit_content(action: edit_line)` — single-line change',
|
|
844
|
+
' - `noteplan_edit_content(action: insert/append)` — add content at a position or heading',
|
|
845
|
+
' - `noteplan_edit_content(action: delete_lines)` — remove lines',
|
|
846
|
+
'4. Only use `noteplan_manage_note(action: update)` for intentional full-note rewrites',
|
|
847
|
+
'',
|
|
848
|
+
'## Tasks',
|
|
849
|
+
'',
|
|
850
|
+
'- Add tasks via `noteplan_paragraphs(action: add)` — the server auto-formats the task marker to match the user\'s NotePlan settings. Never write raw markers like `- [ ]` or `* [ ]`; just pass the task text.',
|
|
851
|
+
'- Find tasks: `noteplan_paragraphs(action: search)` in one note, or `search_global` across all notes',
|
|
852
|
+
'- Complete/update: `noteplan_paragraphs(action: complete/update)`',
|
|
853
|
+
'- Use `heading` parameter to target a specific section (e.g., heading: "Tasks")',
|
|
854
|
+
'',
|
|
855
|
+
'## Destructive Operations',
|
|
856
|
+
'',
|
|
857
|
+
'Delete, move, rename, and restore use a 2-step safety flow:',
|
|
858
|
+
'1. Call with `dryRun=true` → get a preview and `confirmationToken`',
|
|
859
|
+
'2. Call again with that `confirmationToken` to execute',
|
|
860
|
+
'',
|
|
861
|
+
'## Key Behaviors',
|
|
862
|
+
'',
|
|
863
|
+
'- Calendar notes (daily/weekly/etc.) are auto-created when targeted by date — no need to create them first',
|
|
864
|
+
'- Notes can be targeted by `id`, `filename`, `title`, `date`, or `query` — prefer `id` or `filename` when available for precision',
|
|
865
|
+
'- Errors include a `hint` and often a `suggestedTool` to guide recovery',
|
|
866
|
+
'- The `noteplan_memory` tool stores user preferences (formatting, style, workflow) persistently across sessions',
|
|
867
|
+
'',
|
|
868
|
+
'## Templates',
|
|
869
|
+
'',
|
|
870
|
+
'- IMPORTANT: Before writing or editing templates, ALWAYS search the built-in documentation first: `noteplan_templates(action: "search_docs", query: "your topic")`',
|
|
871
|
+
'- Use `get_doc` to read the full text of a doc chunk returned by `search_docs`',
|
|
872
|
+
'- Then use `render` to test/debug your template code',
|
|
873
|
+
'',
|
|
874
|
+
'## Action Discovery',
|
|
875
|
+
'',
|
|
876
|
+
'- Every tool supports `action: "list_actions"` — call it to get a list of all available actions with descriptions',
|
|
877
|
+
'- Use `list_actions` when you are unsure what a tool can do or need to discover capabilities',
|
|
878
|
+
].join('\n'),
|
|
827
879
|
});
|
|
828
880
|
let embeddingsToolsEnabled = false;
|
|
829
881
|
try {
|
|
@@ -842,6 +894,19 @@ export function createServer() {
|
|
|
842
894
|
console.error('[noteplan-mcp] Failed to detect NotePlan version:', err);
|
|
843
895
|
}
|
|
844
896
|
console.error(`[noteplan-mcp] Detected NotePlan ${versionInfo.version} (build ${versionInfo.build}, source: ${versionInfo.source}). Advanced features: ${advancedFeaturesEnabled ? 'enabled' : 'disabled'}.`);
|
|
897
|
+
// Startup diagnostics: HOME, database, spaces
|
|
898
|
+
console.error(`[noteplan-mcp] HOME: ${process.env.HOME ?? '(unset)'}`);
|
|
899
|
+
const dbPath = getDatabasePath();
|
|
900
|
+
if (dbPath) {
|
|
901
|
+
const database = getDatabase();
|
|
902
|
+
const writable = database ? 'read-write' : 'unavailable';
|
|
903
|
+
console.error(`[noteplan-mcp] Space database: ${dbPath} (${writable})`);
|
|
904
|
+
const spaces = listSpacesFromDb();
|
|
905
|
+
console.error(`[noteplan-mcp] Spaces discovered: ${spaces.length}`);
|
|
906
|
+
}
|
|
907
|
+
else {
|
|
908
|
+
console.error('[noteplan-mcp] Space database: not found');
|
|
909
|
+
}
|
|
845
910
|
const toolDefinitions = [
|
|
846
911
|
// ── Consolidated tools (16 — action/param-based dispatch) ──
|
|
847
912
|
{
|
|
@@ -997,18 +1062,18 @@ export function createServer() {
|
|
|
997
1062
|
},
|
|
998
1063
|
{
|
|
999
1064
|
name: 'noteplan_manage_note',
|
|
1000
|
-
description: 'Manage notes: create, update, delete, move, restore, rename, or manage frontmatter properties.\n\nActions:\n- create: Create a project note (requires title). Set noteType="template" to create in @Templates with proper frontmatter. After creating a template, verify it with noteplan_templates(action: "render").\n- update: Replace note content (requires filename, content, fullReplace + confirmationToken)\n- delete/move/restore: Lifecycle ops (requires id or filename + dryRun/confirmationToken)\n- rename: Rename a note (accepts id, filename, title, or query to find the note + newTitle for the new name + dryRun/confirmationToken)\n- set_property/remove_property: Frontmatter (requires filename + key)',
|
|
1065
|
+
description: 'Manage notes: create, update, delete, move, restore, rename, or manage frontmatter properties.\n\nActions:\n- create: Create a project note (requires title). Set noteType="template" to create in @Templates with proper frontmatter. After creating a template, verify it with noteplan_templates(action: "render").\n- update: Replace note content (requires note ref via id/filename/title/date/query, content, fullReplace + confirmationToken)\n- delete/move/restore: Lifecycle ops (requires id or filename + dryRun/confirmationToken)\n- rename: Rename a note (accepts id, filename, title, or query to find the note + newTitle for the new name + dryRun/confirmationToken)\n- set_property/remove_property: Frontmatter (requires note ref via id/filename/title/date/query + key)',
|
|
1001
1066
|
inputSchema: {
|
|
1002
1067
|
type: 'object',
|
|
1003
1068
|
properties: {
|
|
1004
1069
|
action: {
|
|
1005
1070
|
type: 'string',
|
|
1006
|
-
enum: ['create', 'update', 'delete', 'move', 'restore', 'rename', 'set_property', 'remove_property'],
|
|
1007
|
-
description: 'Action: create | update | delete | move | restore | rename | set_property | remove_property',
|
|
1071
|
+
enum: ['create', 'update', 'delete', 'move', 'restore', 'rename', 'set_property', 'remove_property', 'list_actions'],
|
|
1072
|
+
description: 'Action: create | update | delete | move | restore | rename | set_property | remove_property | list_actions (discover all actions)',
|
|
1008
1073
|
},
|
|
1009
1074
|
id: {
|
|
1010
1075
|
type: 'string',
|
|
1011
|
-
description: 'Note ID — used by delete, move, rename, restore (preferred for TeamSpace notes)',
|
|
1076
|
+
description: 'Note ID — used by delete, move, rename, restore, set_property, remove_property (preferred for TeamSpace notes)',
|
|
1012
1077
|
},
|
|
1013
1078
|
filename: {
|
|
1014
1079
|
type: 'string',
|
|
@@ -1016,11 +1081,15 @@ export function createServer() {
|
|
|
1016
1081
|
},
|
|
1017
1082
|
title: {
|
|
1018
1083
|
type: 'string',
|
|
1019
|
-
description: 'Note title — required for create. Also used by rename to find the note by title (fuzzy matched).',
|
|
1084
|
+
description: 'Note title — required for create. Also used by rename, move, set_property, remove_property to find the note by title (fuzzy matched).',
|
|
1085
|
+
},
|
|
1086
|
+
date: {
|
|
1087
|
+
type: 'string',
|
|
1088
|
+
description: 'Calendar note date (YYYYMMDD, YYYY-MM-DD, today, tomorrow, yesterday) — used by set_property, remove_property, move',
|
|
1020
1089
|
},
|
|
1021
1090
|
query: {
|
|
1022
1091
|
type: 'string',
|
|
1023
|
-
description: 'Fuzzy search query to find the note — used by rename',
|
|
1092
|
+
description: 'Fuzzy search query to find the note — used by rename, move, set_property, remove_property',
|
|
1024
1093
|
},
|
|
1025
1094
|
content: {
|
|
1026
1095
|
type: 'string',
|
|
@@ -1100,8 +1169,8 @@ export function createServer() {
|
|
|
1100
1169
|
properties: {
|
|
1101
1170
|
action: {
|
|
1102
1171
|
type: 'string',
|
|
1103
|
-
enum: ['insert', 'append', 'delete_lines', 'edit_line', 'replace_lines'],
|
|
1104
|
-
description: 'Action: insert | append | delete_lines | edit_line | replace_lines',
|
|
1172
|
+
enum: ['insert', 'append', 'delete_lines', 'edit_line', 'replace_lines', 'list_actions'],
|
|
1173
|
+
description: 'Action: insert | append | delete_lines | edit_line | replace_lines | list_actions (discover all actions)',
|
|
1105
1174
|
},
|
|
1106
1175
|
id: {
|
|
1107
1176
|
type: 'string',
|
|
@@ -1201,18 +1270,18 @@ export function createServer() {
|
|
|
1201
1270
|
},
|
|
1202
1271
|
{
|
|
1203
1272
|
name: 'noteplan_paragraphs',
|
|
1204
|
-
description: 'Task lifecycle and paragraph inspection.\n\nParagraph actions:\n- get: Get note lines with metadata (requires filename). Returns line, lineIndex, content, type, etc.\n- search: Search for matching lines in a note (requires query + note ref via id/filename/title/date)\n\nTask actions:\n- search_global: Search tasks across all notes (requires query, supports "*" wildcard)\n- add: Add a task (requires target + content). Target is a date ("today", "tomorrow", "YYYY-MM-DD") for daily notes or a filename for project notes. Pass only the task text as content — formatting auto-matches user settings. Position+heading combos: position="start"+heading inserts right after the heading, position="end"+heading appends at end of that section, position="after-heading" inserts right after heading, position="in-section" appends at end of section. Default position is "end" (bottom of note). Use scheduleDate for >YYYY-MM-DD, [[Note Name]] to link, #tag for tags, @person for mentions.\n- complete: Mark task done (requires filename + lineIndex or
|
|
1273
|
+
description: 'Task lifecycle and paragraph inspection.\n\nParagraph actions:\n- get: Get note lines with metadata (requires filename). Returns line, lineIndex, content, type, etc.\n- search: Search for matching lines in a note (requires query + note ref via id/filename/title/date)\n\nTask actions:\n- search_global: Search tasks across all notes (requires query, supports "*" wildcard)\n- add: Add a task (requires target + content). Target is a date ("today", "tomorrow", "YYYY-MM-DD") for daily notes or a filename for project notes. Pass only the task text as content — formatting auto-matches user settings. Position+heading combos: position="start"+heading inserts right after the heading, position="end"+heading appends at end of that section, position="after-heading" inserts right after heading, position="in-section" appends at end of section. Default position is "end" (bottom of note). Use scheduleDate for >YYYY-MM-DD, [[Note Name]] to link, #tag for tags, @person for mentions.\n- complete: Mark task done (requires note ref via id/filename/title/date + lineIndex/line or taskQuery to find by text)\n- update: Update task content/status (requires note ref via id/filename/title/date + lineIndex or line)',
|
|
1205
1274
|
inputSchema: {
|
|
1206
1275
|
type: 'object',
|
|
1207
1276
|
properties: {
|
|
1208
1277
|
action: {
|
|
1209
1278
|
type: 'string',
|
|
1210
|
-
enum: ['get', 'search', 'search_global', 'add', 'complete', 'update'],
|
|
1211
|
-
description: 'Action: get | search | search_global | add | complete | update',
|
|
1279
|
+
enum: ['get', 'search', 'search_global', 'add', 'complete', 'update', 'list_actions'],
|
|
1280
|
+
description: 'Action: get | search | search_global | add | complete | update | list_actions (discover all actions)',
|
|
1212
1281
|
},
|
|
1213
1282
|
id: {
|
|
1214
1283
|
type: 'string',
|
|
1215
|
-
description: 'Note ID — used by search',
|
|
1284
|
+
description: 'Note ID — used by get, search, complete, update',
|
|
1216
1285
|
},
|
|
1217
1286
|
filename: {
|
|
1218
1287
|
type: 'string',
|
|
@@ -1220,11 +1289,11 @@ export function createServer() {
|
|
|
1220
1289
|
},
|
|
1221
1290
|
title: {
|
|
1222
1291
|
type: 'string',
|
|
1223
|
-
description: 'Note title — used by search',
|
|
1292
|
+
description: 'Note title — used by get, search, complete, update',
|
|
1224
1293
|
},
|
|
1225
1294
|
date: {
|
|
1226
1295
|
type: 'string',
|
|
1227
|
-
description: 'Calendar date — used by search',
|
|
1296
|
+
description: 'Calendar date (e.g. today, YYYY-MM-DD) — used by get, search, complete, update',
|
|
1228
1297
|
},
|
|
1229
1298
|
space: {
|
|
1230
1299
|
type: 'string',
|
|
@@ -1289,6 +1358,10 @@ export function createServer() {
|
|
|
1289
1358
|
type: 'number',
|
|
1290
1359
|
description: 'Task line number (1-based) — used by complete, update',
|
|
1291
1360
|
},
|
|
1361
|
+
taskQuery: {
|
|
1362
|
+
type: 'string',
|
|
1363
|
+
description: 'Find task by content text instead of line number (completes first matching open task) — used by complete',
|
|
1364
|
+
},
|
|
1292
1365
|
priority: {
|
|
1293
1366
|
type: 'number',
|
|
1294
1367
|
description: 'Priority 1-3 — used by add',
|
|
@@ -1354,8 +1427,8 @@ export function createServer() {
|
|
|
1354
1427
|
properties: {
|
|
1355
1428
|
action: {
|
|
1356
1429
|
type: 'string',
|
|
1357
|
-
enum: ['list', 'find', 'resolve', 'create', 'move', 'rename', 'delete', 'list_spaces'],
|
|
1358
|
-
description: 'Action: list | find | resolve | create | move | rename | delete | list_spaces',
|
|
1430
|
+
enum: ['list', 'find', 'resolve', 'create', 'move', 'rename', 'delete', 'list_spaces', 'list_actions'],
|
|
1431
|
+
description: 'Action: list | find | resolve | create | move | rename | delete | list_spaces | list_actions (discover all actions)',
|
|
1359
1432
|
},
|
|
1360
1433
|
path: {
|
|
1361
1434
|
type: 'string',
|
|
@@ -1457,8 +1530,8 @@ export function createServer() {
|
|
|
1457
1530
|
properties: {
|
|
1458
1531
|
action: {
|
|
1459
1532
|
type: 'string',
|
|
1460
|
-
enum: ['list', 'get', 'get_tasks', 'list_parameters', 'save', 'rename'],
|
|
1461
|
-
description: 'Action: list | get | get_tasks | list_parameters | save | rename',
|
|
1533
|
+
enum: ['list', 'get', 'get_tasks', 'list_parameters', 'save', 'rename', 'list_actions'],
|
|
1534
|
+
description: 'Action: list | get | get_tasks | list_parameters | save | rename | list_actions (discover all actions)',
|
|
1462
1535
|
},
|
|
1463
1536
|
name: {
|
|
1464
1537
|
type: 'string',
|
|
@@ -1542,8 +1615,8 @@ export function createServer() {
|
|
|
1542
1615
|
},
|
|
1543
1616
|
action: {
|
|
1544
1617
|
type: 'string',
|
|
1545
|
-
enum: ['get_events', 'list_calendars', 'create_event', 'update_event', 'delete_event', 'get', 'list_lists', 'create', 'complete', 'update', 'delete'],
|
|
1546
|
-
description: 'Action: get_events | list_calendars | create_event | update_event | delete_event | get | list_lists | create | complete | update | delete',
|
|
1618
|
+
enum: ['get_events', 'list_calendars', 'create_event', 'update_event', 'delete_event', 'get', 'list_lists', 'create', 'complete', 'update', 'delete', 'list_actions'],
|
|
1619
|
+
description: 'Action: get_events | list_calendars | create_event | update_event | delete_event | get | list_lists | create | complete | update | delete | list_actions (discover all actions)',
|
|
1547
1620
|
},
|
|
1548
1621
|
// Calendar params
|
|
1549
1622
|
eventId: {
|
|
@@ -1644,8 +1717,8 @@ export function createServer() {
|
|
|
1644
1717
|
properties: {
|
|
1645
1718
|
action: {
|
|
1646
1719
|
type: 'string',
|
|
1647
|
-
enum: ['list', 'save', 'update', 'delete'],
|
|
1648
|
-
description: 'Action: list | save | update | delete',
|
|
1720
|
+
enum: ['list', 'save', 'update', 'delete', 'list_actions'],
|
|
1721
|
+
description: 'Action: list | save | update | delete | list_actions (discover all actions)',
|
|
1649
1722
|
},
|
|
1650
1723
|
id: {
|
|
1651
1724
|
type: 'string',
|
|
@@ -1691,8 +1764,8 @@ export function createServer() {
|
|
|
1691
1764
|
properties: {
|
|
1692
1765
|
action: {
|
|
1693
1766
|
type: 'string',
|
|
1694
|
-
enum: ['search', 'list_tags'],
|
|
1695
|
-
description: 'Action to perform (default: search)',
|
|
1767
|
+
enum: ['search', 'list_tags', 'list_actions'],
|
|
1768
|
+
description: 'Action to perform (default: search) | list_actions (discover all actions)',
|
|
1696
1769
|
},
|
|
1697
1770
|
query: {
|
|
1698
1771
|
type: 'string',
|
|
@@ -1780,8 +1853,8 @@ export function createServer() {
|
|
|
1780
1853
|
properties: {
|
|
1781
1854
|
action: {
|
|
1782
1855
|
type: 'string',
|
|
1783
|
-
enum: ['status', 'search', 'sync', 'reset'],
|
|
1784
|
-
description: 'Action: status | search | sync | reset',
|
|
1856
|
+
enum: ['status', 'search', 'sync', 'reset', 'list_actions'],
|
|
1857
|
+
description: 'Action: status | search | sync | reset | list_actions (discover all actions)',
|
|
1785
1858
|
},
|
|
1786
1859
|
query: {
|
|
1787
1860
|
type: 'string',
|
|
@@ -1861,14 +1934,14 @@ export function createServer() {
|
|
|
1861
1934
|
// noteplan_ui is always available — basic AppleScript commands work on all NotePlan versions
|
|
1862
1935
|
toolDefinitions.push({
|
|
1863
1936
|
name: 'noteplan_ui',
|
|
1864
|
-
description: 'NotePlan UI control via AppleScript.\n\nActions:\n- open_note: Open a note (title or filename)\n- open_today: Open today\'s note\n- search: Search in UI\n- run_plugin: Run a plugin command (requires pluginId + command)\n- open_view: Open a named view\n- toggle_sidebar: Toggle sidebar visibility\n- close_plugin_window: Close plugin window (by windowID/title, or omit both to close all)\n- list_plugin_windows: List open plugin windows\n- backup: Create a full backup
|
|
1937
|
+
description: 'NotePlan UI control via AppleScript.\n\nActions:\n- open_note: Open a note (title or filename)\n- open_today: Open today\'s note\n- search: Search in UI\n- run_plugin: Run a plugin command (requires pluginId + command)\n- open_view: Open a named view\n- toggle_sidebar: Toggle sidebar visibility\n- close_plugin_window: Close plugin window (by windowID/title, or omit both to close all)\n- list_plugin_windows: List open plugin windows\n- backup: Create a full backup',
|
|
1865
1938
|
inputSchema: {
|
|
1866
1939
|
type: 'object',
|
|
1867
1940
|
properties: {
|
|
1868
1941
|
action: {
|
|
1869
1942
|
type: 'string',
|
|
1870
|
-
enum: ['open_note', 'open_today', 'search', 'run_plugin', 'open_view', 'toggle_sidebar', 'close_plugin_window', 'list_plugin_windows', 'backup'],
|
|
1871
|
-
description: 'Action: open_note | open_today | search | run_plugin | open_view | toggle_sidebar | close_plugin_window | list_plugin_windows | backup',
|
|
1943
|
+
enum: ['open_note', 'open_today', 'search', 'run_plugin', 'open_view', 'toggle_sidebar', 'close_plugin_window', 'list_plugin_windows', 'backup', 'list_actions'],
|
|
1944
|
+
description: 'Action: open_note | open_today | search | run_plugin | open_view | toggle_sidebar | close_plugin_window | list_plugin_windows | backup | list_actions (discover all actions)',
|
|
1872
1945
|
},
|
|
1873
1946
|
title: {
|
|
1874
1947
|
type: 'string',
|
|
@@ -1924,8 +1997,8 @@ export function createServer() {
|
|
|
1924
1997
|
properties: {
|
|
1925
1998
|
action: {
|
|
1926
1999
|
type: 'string',
|
|
1927
|
-
enum: ['list', 'list_available', 'create', 'delete', 'install', 'log', 'source', 'update_html', 'screenshot'],
|
|
1928
|
-
description: 'Action: list | list_available | create | delete | install | log | source | update_html | screenshot',
|
|
2000
|
+
enum: ['list', 'list_available', 'create', 'delete', 'install', 'log', 'source', 'update_html', 'screenshot', 'list_actions'],
|
|
2001
|
+
description: 'Action: list | list_available | create | delete | install | log | source | update_html | screenshot | list_actions (discover all actions)',
|
|
1929
2002
|
},
|
|
1930
2003
|
pluginId: {
|
|
1931
2004
|
type: 'string',
|
|
@@ -2015,8 +2088,8 @@ export function createServer() {
|
|
|
2015
2088
|
properties: {
|
|
2016
2089
|
action: {
|
|
2017
2090
|
type: 'string',
|
|
2018
|
-
enum: ['list', 'get', 'save', 'set_active'],
|
|
2019
|
-
description: 'Action: list | get | save | set_active',
|
|
2091
|
+
enum: ['list', 'get', 'save', 'set_active', 'list_actions'],
|
|
2092
|
+
description: 'Action: list | get | save | set_active | list_actions (discover all actions)',
|
|
2020
2093
|
},
|
|
2021
2094
|
filename: {
|
|
2022
2095
|
type: 'string',
|
|
@@ -2051,14 +2124,14 @@ export function createServer() {
|
|
|
2051
2124
|
},
|
|
2052
2125
|
}, {
|
|
2053
2126
|
name: 'noteplan_templates',
|
|
2054
|
-
description: 'Template operations: list available templates
|
|
2127
|
+
description: 'Template operations: list available templates, render a template, or search template documentation.\n\nActions:\n- list: List templates from @Templates folder with their types and preview\n- render: Render a template by title (saved template) or raw content string (for debugging). Rendering requires a recent NotePlan build.\n- search_docs: Semantic search over bundled NotePlan template documentation. Requires query param. Uses embeddings API or NotePlan built-in embedding. Returns matched doc chunks ranked by relevance — use this to look up template syntax, helpers, and examples before writing templates.\n- get_doc: Retrieve the full text of a doc chunk by noteTitle and chunkIndex (from search_docs results). Use this to read complete method signatures, format tokens, and examples that may be truncated in search_docs previews.\n\nDebugging workflow: After creating or editing a template, use render with its title or raw content to verify the output. Check variables, date formatting, and logic. If rendering fails or produces unexpected output, read the plugin log via noteplan_plugins(action: "log", pluginId: "np.Templating") for error details.\n\nTemplate syntax: <%- expr %> (output), <% code %> (logic), <%= expr %> (escaped output). Common helpers: date.now("YYYY-MM-DD"), web.weather(), date.tomorrow("format").',
|
|
2055
2128
|
inputSchema: {
|
|
2056
2129
|
type: 'object',
|
|
2057
2130
|
properties: {
|
|
2058
2131
|
action: {
|
|
2059
2132
|
type: 'string',
|
|
2060
|
-
enum: ['list', 'render'],
|
|
2061
|
-
description: 'Action: list | render',
|
|
2133
|
+
enum: ['list', 'render', 'search_docs', 'get_doc', 'list_actions'],
|
|
2134
|
+
description: 'Action: list | render | search_docs | get_doc | list_actions (discover all actions)',
|
|
2062
2135
|
},
|
|
2063
2136
|
templateTitle: {
|
|
2064
2137
|
type: 'string',
|
|
@@ -2084,6 +2157,22 @@ export function createServer() {
|
|
|
2084
2157
|
type: 'string',
|
|
2085
2158
|
description: 'Cursor from previous page — used by list',
|
|
2086
2159
|
},
|
|
2160
|
+
query: {
|
|
2161
|
+
type: 'string',
|
|
2162
|
+
description: 'Search query — used by search_docs',
|
|
2163
|
+
},
|
|
2164
|
+
includeContent: {
|
|
2165
|
+
type: 'boolean',
|
|
2166
|
+
description: 'Include full chunk text in results — used by search_docs',
|
|
2167
|
+
},
|
|
2168
|
+
noteTitle: {
|
|
2169
|
+
type: 'string',
|
|
2170
|
+
description: 'Doc note title — used by get_doc (from search_docs results)',
|
|
2171
|
+
},
|
|
2172
|
+
chunkIndex: {
|
|
2173
|
+
type: 'number',
|
|
2174
|
+
description: 'Chunk index — used by get_doc (from search_docs results, default 0)',
|
|
2175
|
+
},
|
|
2087
2176
|
},
|
|
2088
2177
|
required: ['action'],
|
|
2089
2178
|
},
|
|
@@ -2095,8 +2184,8 @@ export function createServer() {
|
|
|
2095
2184
|
properties: {
|
|
2096
2185
|
action: {
|
|
2097
2186
|
type: 'string',
|
|
2098
|
-
enum: ['add', 'list', 'get', 'move'],
|
|
2099
|
-
description: 'Action: add | list | get | move',
|
|
2187
|
+
enum: ['add', 'list', 'get', 'move', 'list_actions'],
|
|
2188
|
+
description: 'Action: add | list | get | move | list_actions (discover all actions)',
|
|
2100
2189
|
},
|
|
2101
2190
|
id: { type: 'string', description: 'Source note ID — used by all actions' },
|
|
2102
2191
|
filename: { type: 'string', description: 'Source note filename/path — used by all actions' },
|
|
@@ -2134,42 +2223,178 @@ export function createServer() {
|
|
|
2134
2223
|
});
|
|
2135
2224
|
// Register resource listing handler
|
|
2136
2225
|
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2226
|
+
const pluginResources = PLUGIN_API_RESOURCES.map((r) => ({
|
|
2227
|
+
uri: `noteplan://plugin-api/${r.file}`,
|
|
2228
|
+
name: r.name,
|
|
2229
|
+
description: r.desc,
|
|
2230
|
+
mimeType: r.file.endsWith('.md') ? 'text/markdown' : r.file.endsWith('.json') ? 'application/json' : 'text/javascript',
|
|
2231
|
+
}));
|
|
2232
|
+
const generalResources = GENERAL_DOC_RESOURCES.map((r) => ({
|
|
2233
|
+
uri: `noteplan://docs/${r.file}`,
|
|
2234
|
+
name: r.name,
|
|
2235
|
+
description: r.desc,
|
|
2236
|
+
mimeType: 'text/markdown',
|
|
2237
|
+
}));
|
|
2238
|
+
return { resources: [...pluginResources, ...generalResources] };
|
|
2145
2239
|
});
|
|
2146
2240
|
// Register resource read handler
|
|
2147
2241
|
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
2148
2242
|
const uri = request.params.uri;
|
|
2149
|
-
const
|
|
2150
|
-
|
|
2151
|
-
|
|
2243
|
+
const pluginPrefix = 'noteplan://plugin-api/';
|
|
2244
|
+
const docsPrefix = 'noteplan://docs/';
|
|
2245
|
+
let filePath;
|
|
2246
|
+
if (uri.startsWith(pluginPrefix)) {
|
|
2247
|
+
const filename = uri.slice(pluginPrefix.length);
|
|
2248
|
+
const entry = PLUGIN_API_RESOURCES.find((r) => r.file === filename);
|
|
2249
|
+
if (!entry) {
|
|
2250
|
+
throw new Error(`Unknown resource: ${filename}. Available: ${PLUGIN_API_RESOURCES.map((r) => r.file).join(', ')}`);
|
|
2251
|
+
}
|
|
2252
|
+
filePath = path.join(PLUGIN_API_DOCS_DIR, entry.file);
|
|
2152
2253
|
}
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2254
|
+
else if (uri.startsWith(docsPrefix)) {
|
|
2255
|
+
const filename = uri.slice(docsPrefix.length);
|
|
2256
|
+
const entry = GENERAL_DOC_RESOURCES.find((r) => r.file === filename);
|
|
2257
|
+
if (!entry) {
|
|
2258
|
+
throw new Error(`Unknown resource: ${filename}. Available: ${GENERAL_DOC_RESOURCES.map((r) => r.file).join(', ')}`);
|
|
2259
|
+
}
|
|
2260
|
+
filePath = path.join(DOCS_DIR, entry.file);
|
|
2261
|
+
}
|
|
2262
|
+
else {
|
|
2263
|
+
throw new Error(`Unknown resource URI: ${uri}`);
|
|
2157
2264
|
}
|
|
2158
|
-
const filePath = path.join(PLUGIN_API_DOCS_DIR, entry.file);
|
|
2159
2265
|
if (!fs.existsSync(filePath)) {
|
|
2160
2266
|
throw new Error(`Resource file not found on disk: ${filePath}`);
|
|
2161
2267
|
}
|
|
2162
2268
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
2269
|
+
const mimeType = filePath.endsWith('.md') ? 'text/markdown' : filePath.endsWith('.json') ? 'application/json' : 'text/javascript';
|
|
2163
2270
|
return {
|
|
2164
|
-
contents: [
|
|
2165
|
-
{
|
|
2166
|
-
uri,
|
|
2167
|
-
mimeType: entry.file.endsWith('.md') ? 'text/markdown' : entry.file.endsWith('.json') ? 'application/json' : 'text/javascript',
|
|
2168
|
-
text: content,
|
|
2169
|
-
},
|
|
2170
|
-
],
|
|
2271
|
+
contents: [{ uri, mimeType, text: content }],
|
|
2171
2272
|
};
|
|
2172
2273
|
});
|
|
2274
|
+
// ── Action registry for list_actions discovery ──
|
|
2275
|
+
const TOOL_ACTIONS = {
|
|
2276
|
+
noteplan_get_notes: [
|
|
2277
|
+
{ action: 'get', description: 'Get a single note by id, filename, title, date, or query' },
|
|
2278
|
+
{ action: 'list', description: 'List notes with optional folder/type/date filtering' },
|
|
2279
|
+
{ action: 'resolve', description: 'Resolve a reference (title, filename, query) to a single note' },
|
|
2280
|
+
{ action: 'today', description: 'Get today\'s daily note' },
|
|
2281
|
+
{ action: 'calendar', description: 'Get a calendar note by date' },
|
|
2282
|
+
{ action: 'periodic', description: 'Get a periodic note (week, month, quarter, year)' },
|
|
2283
|
+
{ action: 'range', description: 'Get calendar notes in a date range' },
|
|
2284
|
+
],
|
|
2285
|
+
noteplan_search: [
|
|
2286
|
+
{ action: 'search', description: 'Full-text or metadata search across notes' },
|
|
2287
|
+
{ action: 'list_tags', description: 'List all tags/hashtags with optional filtering' },
|
|
2288
|
+
],
|
|
2289
|
+
noteplan_manage_note: [
|
|
2290
|
+
{ action: 'create', description: 'Create a project note (requires title)' },
|
|
2291
|
+
{ action: 'update', description: 'Replace note content (requires filename, content, fullReplace + confirmationToken)' },
|
|
2292
|
+
{ action: 'delete', description: 'Delete a note (requires dryRun/confirmationToken)' },
|
|
2293
|
+
{ action: 'move', description: 'Move a note to another folder (requires dryRun/confirmationToken)' },
|
|
2294
|
+
{ action: 'restore', description: 'Restore a trashed note (requires dryRun/confirmationToken)' },
|
|
2295
|
+
{ action: 'rename', description: 'Rename a note (requires newTitle)' },
|
|
2296
|
+
{ action: 'set_property', description: 'Set a frontmatter property (requires key + value)' },
|
|
2297
|
+
{ action: 'remove_property', description: 'Remove a frontmatter property (requires key)' },
|
|
2298
|
+
],
|
|
2299
|
+
noteplan_edit_content: [
|
|
2300
|
+
{ action: 'insert', description: 'Insert content at a position. Use heading param to scope to a section' },
|
|
2301
|
+
{ action: 'append', description: 'Append content at end of note or section' },
|
|
2302
|
+
{ action: 'delete_lines', description: 'Delete a line range (requires startLine + endLine, 1-indexed)' },
|
|
2303
|
+
{ action: 'edit_line', description: 'Edit a single line (requires line + content)' },
|
|
2304
|
+
{ action: 'replace_lines', description: 'Replace a line range (requires startLine + endLine + content)' },
|
|
2305
|
+
],
|
|
2306
|
+
noteplan_paragraphs: [
|
|
2307
|
+
{ action: 'get', description: 'Get note lines with metadata (requires filename)' },
|
|
2308
|
+
{ action: 'search', description: 'Search for matching lines in a note (requires query + note ref)' },
|
|
2309
|
+
{ action: 'search_global', description: 'Search tasks across all notes (requires query, supports "*" wildcard)' },
|
|
2310
|
+
{ action: 'add', description: 'Add a task (requires target + content)' },
|
|
2311
|
+
{ action: 'complete', description: 'Mark task done (requires filename + lineIndex or line)' },
|
|
2312
|
+
{ action: 'update', description: 'Update task content/status (requires filename + lineIndex or line)' },
|
|
2313
|
+
],
|
|
2314
|
+
noteplan_folders: [
|
|
2315
|
+
{ action: 'list', description: 'List folders with optional filtering' },
|
|
2316
|
+
{ action: 'find', description: 'Find folder matches for exploration' },
|
|
2317
|
+
{ action: 'resolve', description: 'Resolve to one canonical folder path' },
|
|
2318
|
+
{ action: 'create', description: 'Create a folder' },
|
|
2319
|
+
{ action: 'move', description: 'Move a folder (requires dryRun/confirmationToken)' },
|
|
2320
|
+
{ action: 'rename', description: 'Rename a folder (requires dryRun/confirmationToken)' },
|
|
2321
|
+
{ action: 'delete', description: 'Delete folder to trash (requires dryRun/confirmationToken)' },
|
|
2322
|
+
{ action: 'list_spaces', description: 'List spaces/workspaces' },
|
|
2323
|
+
],
|
|
2324
|
+
noteplan_filters: [
|
|
2325
|
+
{ action: 'list', description: 'List saved filters' },
|
|
2326
|
+
{ action: 'get', description: 'Get one filter with parsed params (requires name)' },
|
|
2327
|
+
{ action: 'get_tasks', description: 'Execute a filter against tasks (requires name)' },
|
|
2328
|
+
{ action: 'list_parameters', description: 'List supported filter parameter keys' },
|
|
2329
|
+
{ action: 'save', description: 'Create or update a filter (requires name + items)' },
|
|
2330
|
+
{ action: 'rename', description: 'Rename a filter (requires oldName + newName)' },
|
|
2331
|
+
],
|
|
2332
|
+
noteplan_eventkit: [
|
|
2333
|
+
{ action: 'get_events', description: 'Get events for a date/range (source: calendar)' },
|
|
2334
|
+
{ action: 'list_calendars', description: 'List all calendars (source: calendar)' },
|
|
2335
|
+
{ action: 'create_event', description: 'Create event (source: calendar, requires title + startDate)' },
|
|
2336
|
+
{ action: 'update_event', description: 'Update event (source: calendar, requires eventId)' },
|
|
2337
|
+
{ action: 'delete_event', description: 'Delete event (source: calendar, requires eventId + dryRun/confirmationToken)' },
|
|
2338
|
+
{ action: 'get', description: 'Get reminders (source: reminders, optional list/query filter)' },
|
|
2339
|
+
{ action: 'list_lists', description: 'List reminder lists (source: reminders)' },
|
|
2340
|
+
{ action: 'create', description: 'Create reminder (source: reminders, requires title)' },
|
|
2341
|
+
{ action: 'complete', description: 'Mark reminder done (source: reminders, requires reminderId)' },
|
|
2342
|
+
{ action: 'update', description: 'Update reminder (source: reminders, requires reminderId)' },
|
|
2343
|
+
{ action: 'delete', description: 'Delete reminder (source: reminders, requires reminderId + dryRun/confirmationToken)' },
|
|
2344
|
+
],
|
|
2345
|
+
noteplan_memory: [
|
|
2346
|
+
{ action: 'list', description: 'List/search stored memories' },
|
|
2347
|
+
{ action: 'save', description: 'Save a new memory (requires content)' },
|
|
2348
|
+
{ action: 'update', description: 'Update memory content/tags (requires id)' },
|
|
2349
|
+
{ action: 'delete', description: 'Delete a memory (requires id)' },
|
|
2350
|
+
],
|
|
2351
|
+
noteplan_ui: [
|
|
2352
|
+
{ action: 'open_note', description: 'Open a note by title or filename' },
|
|
2353
|
+
{ action: 'open_today', description: 'Open today\'s note' },
|
|
2354
|
+
{ action: 'search', description: 'Search in UI' },
|
|
2355
|
+
{ action: 'run_plugin', description: 'Run a plugin command (requires pluginId + command)' },
|
|
2356
|
+
{ action: 'open_view', description: 'Open a named view' },
|
|
2357
|
+
{ action: 'toggle_sidebar', description: 'Toggle sidebar visibility' },
|
|
2358
|
+
{ action: 'close_plugin_window', description: 'Close plugin window (by windowID/title, or omit both to close all)' },
|
|
2359
|
+
{ action: 'list_plugin_windows', description: 'List open plugin windows' },
|
|
2360
|
+
{ action: 'backup', description: 'Create a full backup of all notes, calendars, themes, filters, and plugin data' },
|
|
2361
|
+
],
|
|
2362
|
+
noteplan_plugins: [
|
|
2363
|
+
{ action: 'list', description: 'List installed plugins' },
|
|
2364
|
+
{ action: 'list_available', description: 'List plugins from online repository' },
|
|
2365
|
+
{ action: 'create', description: 'Create plugin with HTML view (requires pluginId, pluginName, commandName, html)' },
|
|
2366
|
+
{ action: 'delete', description: 'Delete plugin (requires pluginId + confirmationToken)' },
|
|
2367
|
+
{ action: 'install', description: 'Install from repository (requires pluginId)' },
|
|
2368
|
+
{ action: 'log', description: 'Read plugin console log (requires pluginId)' },
|
|
2369
|
+
{ action: 'source', description: 'Read plugin source (requires pluginId)' },
|
|
2370
|
+
{ action: 'update_html', description: 'Apply find/replace patches (requires pluginId + patches)' },
|
|
2371
|
+
{ action: 'screenshot', description: 'Capture plugin WebView screenshot (requires pluginId)' },
|
|
2372
|
+
],
|
|
2373
|
+
noteplan_themes: [
|
|
2374
|
+
{ action: 'list', description: 'List all themes and active theme names' },
|
|
2375
|
+
{ action: 'get', description: 'Read a custom theme JSON (requires filename)' },
|
|
2376
|
+
{ action: 'save', description: 'Create/update a custom theme (requires filename + theme)' },
|
|
2377
|
+
{ action: 'set_active', description: 'Activate a theme (requires name)' },
|
|
2378
|
+
],
|
|
2379
|
+
noteplan_embeddings: [
|
|
2380
|
+
{ action: 'status', description: 'Get embeddings config and index status' },
|
|
2381
|
+
{ action: 'search', description: 'Semantic search over indexed notes (requires query)' },
|
|
2382
|
+
{ action: 'sync', description: 'Build/refresh embeddings index' },
|
|
2383
|
+
{ action: 'reset', description: 'Delete index rows (requires dryRun/confirmationToken)' },
|
|
2384
|
+
],
|
|
2385
|
+
noteplan_templates: [
|
|
2386
|
+
{ action: 'list', description: 'List templates from @Templates folder with types and preview' },
|
|
2387
|
+
{ action: 'render', description: 'Render a template by title or raw content string' },
|
|
2388
|
+
{ action: 'search_docs', description: 'Semantic search over bundled template documentation (requires query). Use this to look up template syntax, helpers, and examples before writing templates' },
|
|
2389
|
+
{ action: 'get_doc', description: 'Get full text of a doc chunk by noteTitle + chunkIndex (from search_docs results)' },
|
|
2390
|
+
],
|
|
2391
|
+
noteplan_attachments: [
|
|
2392
|
+
{ action: 'add', description: 'Write a file to the note\'s _attachments folder (requires data + attachmentFilename)' },
|
|
2393
|
+
{ action: 'list', description: 'List all attachments for a note' },
|
|
2394
|
+
{ action: 'get', description: 'Get attachment metadata. Set includeData=true for base64 content' },
|
|
2395
|
+
{ action: 'move', description: 'Move an attachment between notes' },
|
|
2396
|
+
],
|
|
2397
|
+
};
|
|
2173
2398
|
// Register tool call handler
|
|
2174
2399
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
2175
2400
|
const { name, arguments: args } = request.params;
|
|
@@ -2178,6 +2403,12 @@ export function createServer() {
|
|
|
2178
2403
|
const startTime = Date.now();
|
|
2179
2404
|
try {
|
|
2180
2405
|
let result;
|
|
2406
|
+
// ── Intercept list_actions for any tool with an action registry ──
|
|
2407
|
+
if (args?.action === 'list_actions' && TOOL_ACTIONS[normalizedName]) {
|
|
2408
|
+
result = { success: true, tool: normalizedName, actions: TOOL_ACTIONS[normalizedName] };
|
|
2409
|
+
const resultWithDuration = withDuration(result, Date.now() - startTime, includeTiming);
|
|
2410
|
+
return { content: [{ type: 'text', text: JSON.stringify(resultWithDuration, null, 2) }] };
|
|
2411
|
+
}
|
|
2181
2412
|
switch (normalizedName) {
|
|
2182
2413
|
// ── Primary consolidated tools ──
|
|
2183
2414
|
case 'noteplan_get_notes':
|
|
@@ -2283,7 +2514,7 @@ export function createServer() {
|
|
|
2283
2514
|
result = noteTools.searchParagraphs(a);
|
|
2284
2515
|
break;
|
|
2285
2516
|
case 'search_global':
|
|
2286
|
-
result =
|
|
2517
|
+
result = noteTools.searchParagraphsGlobal(a);
|
|
2287
2518
|
break;
|
|
2288
2519
|
case 'add':
|
|
2289
2520
|
result = taskTools.addTaskToNote(a);
|
|
@@ -2599,6 +2830,12 @@ export function createServer() {
|
|
|
2599
2830
|
case 'render':
|
|
2600
2831
|
result = templateTools.renderTemplate(args);
|
|
2601
2832
|
break;
|
|
2833
|
+
case 'search_docs':
|
|
2834
|
+
result = await templateTools.searchDocs(args);
|
|
2835
|
+
break;
|
|
2836
|
+
case 'get_doc':
|
|
2837
|
+
result = templateTools.getDoc(args);
|
|
2838
|
+
break;
|
|
2602
2839
|
default: throw new Error(`Unknown action: ${action}`);
|
|
2603
2840
|
}
|
|
2604
2841
|
break;
|
|
@@ -2662,7 +2899,12 @@ export function createServer() {
|
|
|
2662
2899
|
};
|
|
2663
2900
|
}
|
|
2664
2901
|
catch (error) {
|
|
2665
|
-
|
|
2902
|
+
let errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
2903
|
+
// Append list_actions hint for unknown action errors
|
|
2904
|
+
if (errorMessage.includes('Unknown action') && TOOL_ACTIONS[normalizedName]) {
|
|
2905
|
+
const validActions = TOOL_ACTIONS[normalizedName].map(a => a.action).join(', ');
|
|
2906
|
+
errorMessage += `. Valid actions: ${validActions}. Tip: use action "list_actions" to discover all actions with descriptions.`;
|
|
2907
|
+
}
|
|
2666
2908
|
const meta = inferToolErrorMeta(normalizedName, errorMessage, registeredToolNames);
|
|
2667
2909
|
const errorResult = {
|
|
2668
2910
|
success: false,
|
|
@@ -2690,7 +2932,7 @@ export function createServer() {
|
|
|
2690
2932
|
}
|
|
2691
2933
|
// Start the server with stdio transport
|
|
2692
2934
|
export async function startServer() {
|
|
2693
|
-
console.error(`[noteplan-mcp] Starting v${getMcpServerVersion()} (Node ${process.version}, ${process.platform} ${process.arch})`);
|
|
2935
|
+
console.error(`[noteplan-mcp] Starting v${getMcpServerVersion()} (Node ${process.version}, ${process.platform} ${process.arch}, pid ${process.pid})`);
|
|
2694
2936
|
await initSqlite();
|
|
2695
2937
|
const server = createServer();
|
|
2696
2938
|
const transport = new StdioServerTransport();
|