@noteplanco/noteplan-mcp 1.1.6 → 1.1.8
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 +86 -17
- package/dist/noteplan/file-writer.js.map +1 -1
- package/dist/noteplan/file-writer.test.d.ts +2 -0
- package/dist/noteplan/file-writer.test.d.ts.map +1 -0
- package/dist/noteplan/file-writer.test.js +896 -0
- package/dist/noteplan/file-writer.test.js.map +1 -0
- package/dist/noteplan/filter-store.d.ts.map +1 -1
- package/dist/noteplan/filter-store.js +13 -1
- package/dist/noteplan/filter-store.js.map +1 -1
- package/dist/noteplan/frontmatter-parser.d.ts +10 -1
- package/dist/noteplan/frontmatter-parser.d.ts.map +1 -1
- package/dist/noteplan/frontmatter-parser.js +59 -6
- package/dist/noteplan/frontmatter-parser.js.map +1 -1
- package/dist/noteplan/frontmatter-parser.test.js +576 -1
- package/dist/noteplan/frontmatter-parser.test.js.map +1 -1
- package/dist/noteplan/markdown-parser.d.ts +6 -1
- package/dist/noteplan/markdown-parser.d.ts.map +1 -1
- package/dist/noteplan/markdown-parser.js +25 -46
- package/dist/noteplan/markdown-parser.js.map +1 -1
- package/dist/noteplan/markdown-parser.test.d.ts +2 -0
- package/dist/noteplan/markdown-parser.test.d.ts.map +1 -0
- package/dist/noteplan/markdown-parser.test.js +690 -0
- package/dist/noteplan/markdown-parser.test.js.map +1 -0
- 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 +22 -6
- package/dist/noteplan/unified-store.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +661 -241
- package/dist/server.js.map +1 -1
- package/dist/tools/attachments.d.ts +151 -0
- package/dist/tools/attachments.d.ts.map +1 -0
- package/dist/tools/attachments.js +421 -0
- package/dist/tools/attachments.js.map +1 -0
- package/dist/tools/attachments.test.d.ts +2 -0
- package/dist/tools/attachments.test.d.ts.map +1 -0
- package/dist/tools/attachments.test.js +561 -0
- package/dist/tools/attachments.test.js.map +1 -0
- package/dist/tools/calendar.d.ts +7 -7
- package/dist/tools/notes.d.ts +148 -48
- package/dist/tools/notes.d.ts.map +1 -1
- package/dist/tools/notes.js +366 -29
- package/dist/tools/notes.js.map +1 -1
- package/dist/tools/notes.test.d.ts +2 -0
- package/dist/tools/notes.test.d.ts.map +1 -0
- package/dist/tools/notes.test.js +800 -0
- package/dist/tools/notes.test.js.map +1 -0
- 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/reminders.d.ts +4 -4
- 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 +10 -10
- package/dist/tools/tasks.d.ts.map +1 -1
- package/dist/tools/tasks.js +14 -27
- package/dist/tools/tasks.js.map +1 -1
- package/dist/tools/templates.d.ts +130 -0
- package/dist/tools/templates.d.ts.map +1 -0
- package/dist/tools/templates.js +217 -0
- package/dist/tools/templates.js.map +1 -0
- package/dist/tools/templates.test.d.ts +2 -0
- package/dist/tools/templates.test.d.ts.map +1 -0
- package/dist/tools/templates.test.js +48 -0
- package/dist/tools/templates.test.js.map +1 -0
- package/dist/tools/ui.d.ts +2 -0
- package/dist/tools/ui.d.ts.map +1 -1
- package/dist/tools/ui.js +24 -0
- package/dist/tools/ui.js.map +1 -1
- package/dist/utils/applescript.d.ts.map +1 -1
- package/dist/utils/applescript.js +21 -0
- package/dist/utils/applescript.js.map +1 -1
- package/dist/utils/confirmation-tokens.test.d.ts +2 -0
- package/dist/utils/confirmation-tokens.test.d.ts.map +1 -0
- package/dist/utils/confirmation-tokens.test.js +159 -0
- package/dist/utils/confirmation-tokens.test.js.map +1 -0
- package/dist/utils/version.d.ts +3 -0
- package/dist/utils/version.d.ts.map +1 -1
- package/dist/utils/version.js +71 -23
- 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
|
@@ -19,12 +19,18 @@ import * as memoryTools from './tools/memory.js';
|
|
|
19
19
|
import * as uiTools from './tools/ui.js';
|
|
20
20
|
import * as pluginTools from './tools/plugins.js';
|
|
21
21
|
import * as themeTools from './tools/themes.js';
|
|
22
|
+
import * as templateTools from './tools/templates.js';
|
|
23
|
+
import * as attachmentTools from './tools/attachments.js';
|
|
22
24
|
import { parseFlexibleDate } from './utils/date-utils.js';
|
|
23
|
-
import { upgradeMessage, getNotePlanVersion, getMcpServerVersion, MIN_BUILD_ADVANCED_FEATURES } from './utils/version.js';
|
|
25
|
+
import { upgradeMessage, getNotePlanVersion, getMcpServerVersion, MIN_BUILD_ADVANCED_FEATURES, MIN_BUILD_CREATE_BACKUP } from './utils/version.js';
|
|
24
26
|
import { initSqlite } from './noteplan/sqlite-loader.js';
|
|
25
27
|
const __filename = fileURLToPath(import.meta.url);
|
|
26
28
|
const __dirname = path.dirname(__filename);
|
|
27
29
|
const PLUGIN_API_DOCS_DIR = path.join(__dirname, '../docs/plugin-api');
|
|
30
|
+
const DOCS_DIR = path.join(__dirname, '../docs');
|
|
31
|
+
const GENERAL_DOC_RESOURCES = [
|
|
32
|
+
{ 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' },
|
|
33
|
+
];
|
|
28
34
|
const PLUGIN_API_RESOURCES = [
|
|
29
35
|
{ 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.' },
|
|
30
36
|
{ file: 'getting-started.md', name: 'Getting Started Guide', desc: 'How to create NotePlan plugins — structure, setup, first plugin, testing, HTML views' },
|
|
@@ -200,6 +206,8 @@ function getToolOutputSchema(toolName) {
|
|
|
200
206
|
case 'noteplan_plugins':
|
|
201
207
|
case 'noteplan_themes':
|
|
202
208
|
case 'noteplan_embeddings':
|
|
209
|
+
case 'noteplan_templates':
|
|
210
|
+
case 'noteplan_attachments':
|
|
203
211
|
return GENERIC_TOOL_OUTPUT_SCHEMA;
|
|
204
212
|
default:
|
|
205
213
|
return GENERIC_TOOL_OUTPUT_SCHEMA;
|
|
@@ -371,6 +379,7 @@ function getToolAnnotations(toolName) {
|
|
|
371
379
|
'noteplan_plugins',
|
|
372
380
|
'noteplan_themes',
|
|
373
381
|
'noteplan_embeddings',
|
|
382
|
+
'noteplan_attachments',
|
|
374
383
|
]);
|
|
375
384
|
const nonIdempotentTools = new Set([
|
|
376
385
|
'noteplan_manage_note',
|
|
@@ -384,11 +393,14 @@ function getToolAnnotations(toolName) {
|
|
|
384
393
|
'noteplan_plugins',
|
|
385
394
|
'noteplan_themes',
|
|
386
395
|
'noteplan_embeddings',
|
|
396
|
+
'noteplan_templates',
|
|
397
|
+
'noteplan_attachments',
|
|
387
398
|
]);
|
|
388
399
|
const openWorldTools = new Set([
|
|
389
400
|
'noteplan_eventkit',
|
|
390
401
|
'noteplan_embeddings',
|
|
391
402
|
'noteplan_plugins',
|
|
403
|
+
'noteplan_templates',
|
|
392
404
|
]);
|
|
393
405
|
return {
|
|
394
406
|
readOnlyHint: readOnlyTools.has(toolName),
|
|
@@ -459,6 +471,12 @@ function getToolSearchAliases(toolName) {
|
|
|
459
471
|
case 'noteplan_embeddings':
|
|
460
472
|
aliases.push('embeddings', 'semantic search', 'vector search', 'similarity');
|
|
461
473
|
break;
|
|
474
|
+
case 'noteplan_templates':
|
|
475
|
+
aliases.push('template', 'templates', 'render template', 'list templates', 'template types', 'meeting template', 'project template', 'debug template', 'test template');
|
|
476
|
+
break;
|
|
477
|
+
case 'noteplan_attachments':
|
|
478
|
+
aliases.push('attachment', 'attachments', 'image', 'file', 'upload', 'add image', 'add file', 'add attachment', 'list attachments', 'get attachment', 'base64', 'photo', 'screenshot');
|
|
479
|
+
break;
|
|
462
480
|
}
|
|
463
481
|
return aliases;
|
|
464
482
|
}
|
|
@@ -516,7 +534,7 @@ function searchToolDefinitions(tools, query, limit) {
|
|
|
516
534
|
function inferToolErrorMeta(toolName, errorMessage, registeredToolNames) {
|
|
517
535
|
const message = errorMessage.toLowerCase();
|
|
518
536
|
if (message.includes('unknown tool')) {
|
|
519
|
-
const toolList = registeredToolNames?.join(', ') ?? 'noteplan_get_notes, noteplan_search, noteplan_manage_note, noteplan_edit_content, noteplan_paragraphs, noteplan_folders, noteplan_filters, noteplan_eventkit, noteplan_memory';
|
|
537
|
+
const toolList = registeredToolNames?.join(', ') ?? 'noteplan_get_notes, noteplan_search, noteplan_manage_note, noteplan_edit_content, noteplan_paragraphs, noteplan_folders, noteplan_filters, noteplan_eventkit, noteplan_memory, noteplan_templates, noteplan_attachments';
|
|
520
538
|
return {
|
|
521
539
|
code: 'ERR_UNKNOWN_TOOL',
|
|
522
540
|
hint: `Check tool name spelling. Available tools: ${toolList}.`,
|
|
@@ -737,6 +755,12 @@ function withSuggestedNextTools(result, toolName, availableToolNames) {
|
|
|
737
755
|
case 'noteplan_themes':
|
|
738
756
|
suggestedNextTools = ['noteplan_themes'];
|
|
739
757
|
break;
|
|
758
|
+
case 'noteplan_templates':
|
|
759
|
+
suggestedNextTools = ['noteplan_templates', 'noteplan_manage_note', 'noteplan_edit_content'];
|
|
760
|
+
break;
|
|
761
|
+
case 'noteplan_attachments':
|
|
762
|
+
suggestedNextTools = ['noteplan_attachments', 'noteplan_edit_content', 'noteplan_get_notes'];
|
|
763
|
+
break;
|
|
740
764
|
default:
|
|
741
765
|
suggestedNextTools = [];
|
|
742
766
|
}
|
|
@@ -798,12 +822,59 @@ function withDuration(result, durationMs, includeTiming) {
|
|
|
798
822
|
export function createServer() {
|
|
799
823
|
const server = new Server({
|
|
800
824
|
name: 'NotePlan',
|
|
801
|
-
version: '1.1.
|
|
825
|
+
version: '1.1.7',
|
|
802
826
|
}, {
|
|
803
827
|
capabilities: {
|
|
804
828
|
tools: {},
|
|
805
829
|
resources: {},
|
|
806
830
|
},
|
|
831
|
+
instructions: [
|
|
832
|
+
'You have access to NotePlan — a markdown-based note-taking and task management app for macOS/iOS.',
|
|
833
|
+
'All tools use action-based dispatch: one tool per domain, with an `action` parameter to select the operation.',
|
|
834
|
+
'',
|
|
835
|
+
'## Workflow',
|
|
836
|
+
'',
|
|
837
|
+
'Prefer granular edits over full-note rewrites to avoid large context payloads and accidental data loss.',
|
|
838
|
+
'',
|
|
839
|
+
'1. **Find** the note: `noteplan_get_notes` (by id/title/filename/date) or `noteplan_search`',
|
|
840
|
+
'2. **Inspect** content: `noteplan_paragraphs(action: get)` for line metadata, `noteplan_paragraphs(action: search)` for text lookup',
|
|
841
|
+
'3. **Edit** with targeted mutations:',
|
|
842
|
+
' - `noteplan_edit_content(action: edit_line)` — single-line change',
|
|
843
|
+
' - `noteplan_edit_content(action: insert/append)` — add content at a position or heading',
|
|
844
|
+
' - `noteplan_edit_content(action: delete_lines)` — remove lines',
|
|
845
|
+
'4. Only use `noteplan_manage_note(action: update)` for intentional full-note rewrites',
|
|
846
|
+
'',
|
|
847
|
+
'## Tasks',
|
|
848
|
+
'',
|
|
849
|
+
'- 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.',
|
|
850
|
+
'- Find tasks: `noteplan_paragraphs(action: search)` in one note, or `search_global` across all notes',
|
|
851
|
+
'- Complete/update: `noteplan_paragraphs(action: complete/update)`',
|
|
852
|
+
'- Use `heading` parameter to target a specific section (e.g., heading: "Tasks")',
|
|
853
|
+
'',
|
|
854
|
+
'## Destructive Operations',
|
|
855
|
+
'',
|
|
856
|
+
'Delete, move, rename, and restore use a 2-step safety flow:',
|
|
857
|
+
'1. Call with `dryRun=true` → get a preview and `confirmationToken`',
|
|
858
|
+
'2. Call again with that `confirmationToken` to execute',
|
|
859
|
+
'',
|
|
860
|
+
'## Key Behaviors',
|
|
861
|
+
'',
|
|
862
|
+
'- Calendar notes (daily/weekly/etc.) are auto-created when targeted by date — no need to create them first',
|
|
863
|
+
'- Notes can be targeted by `id`, `filename`, `title`, `date`, or `query` — prefer `id` or `filename` when available for precision',
|
|
864
|
+
'- Errors include a `hint` and often a `suggestedTool` to guide recovery',
|
|
865
|
+
'- The `noteplan_memory` tool stores user preferences (formatting, style, workflow) persistently across sessions',
|
|
866
|
+
'',
|
|
867
|
+
'## Templates',
|
|
868
|
+
'',
|
|
869
|
+
'- IMPORTANT: Before writing or editing templates, ALWAYS search the built-in documentation first: `noteplan_templates(action: "search_docs", query: "your topic")`',
|
|
870
|
+
'- Use `get_doc` to read the full text of a doc chunk returned by `search_docs`',
|
|
871
|
+
'- Then use `render` to test/debug your template code',
|
|
872
|
+
'',
|
|
873
|
+
'## Action Discovery',
|
|
874
|
+
'',
|
|
875
|
+
'- Every tool supports `action: "list_actions"` — call it to get a list of all available actions with descriptions',
|
|
876
|
+
'- Use `list_actions` when you are unsure what a tool can do or need to discover capabilities',
|
|
877
|
+
].join('\n'),
|
|
807
878
|
});
|
|
808
879
|
let embeddingsToolsEnabled = false;
|
|
809
880
|
try {
|
|
@@ -977,14 +1048,14 @@ export function createServer() {
|
|
|
977
1048
|
},
|
|
978
1049
|
{
|
|
979
1050
|
name: 'noteplan_manage_note',
|
|
980
|
-
description: 'Manage notes: create, update, delete, move, restore, rename, or manage frontmatter properties.\n\nActions:\n- create: Create a project note (requires title)
|
|
1051
|
+
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)',
|
|
981
1052
|
inputSchema: {
|
|
982
1053
|
type: 'object',
|
|
983
1054
|
properties: {
|
|
984
1055
|
action: {
|
|
985
1056
|
type: 'string',
|
|
986
|
-
enum: ['create', 'update', 'delete', 'move', 'restore', 'rename', 'set_property', 'remove_property'],
|
|
987
|
-
description: 'Action
|
|
1057
|
+
enum: ['create', 'update', 'delete', 'move', 'restore', 'rename', 'set_property', 'remove_property', 'list_actions'],
|
|
1058
|
+
description: 'Action: create | update | delete | move | restore | rename | set_property | remove_property | list_actions (discover all actions)',
|
|
988
1059
|
},
|
|
989
1060
|
id: {
|
|
990
1061
|
type: 'string',
|
|
@@ -996,7 +1067,11 @@ export function createServer() {
|
|
|
996
1067
|
},
|
|
997
1068
|
title: {
|
|
998
1069
|
type: 'string',
|
|
999
|
-
description: 'Note title — required for create',
|
|
1070
|
+
description: 'Note title — required for create. Also used by rename to find the note by title (fuzzy matched).',
|
|
1071
|
+
},
|
|
1072
|
+
query: {
|
|
1073
|
+
type: 'string',
|
|
1074
|
+
description: 'Fuzzy search query to find the note — used by rename',
|
|
1000
1075
|
},
|
|
1001
1076
|
content: {
|
|
1002
1077
|
type: 'string',
|
|
@@ -1010,6 +1085,16 @@ export function createServer() {
|
|
|
1010
1085
|
type: 'boolean',
|
|
1011
1086
|
description: 'Bypass smart matching and create exact folder name — used by create',
|
|
1012
1087
|
},
|
|
1088
|
+
noteType: {
|
|
1089
|
+
type: 'string',
|
|
1090
|
+
enum: ['note', 'template'],
|
|
1091
|
+
description: 'Type of note to create. Use "template" to create in @Templates with proper frontmatter — used by create',
|
|
1092
|
+
},
|
|
1093
|
+
templateTypes: {
|
|
1094
|
+
type: 'array',
|
|
1095
|
+
items: { type: 'string', enum: ['empty-note', 'meeting-note', 'project-note', 'calendar-note'] },
|
|
1096
|
+
description: 'Template type tags — used by create with noteType="template"',
|
|
1097
|
+
},
|
|
1013
1098
|
space: {
|
|
1014
1099
|
type: 'string',
|
|
1015
1100
|
description: 'Space name or ID scope',
|
|
@@ -1036,11 +1121,11 @@ export function createServer() {
|
|
|
1036
1121
|
},
|
|
1037
1122
|
newFilename: {
|
|
1038
1123
|
type: 'string',
|
|
1039
|
-
description: 'New filename for local notes — used by rename',
|
|
1124
|
+
description: 'New filename for local notes — used by rename. Prefer newTitle instead.',
|
|
1040
1125
|
},
|
|
1041
1126
|
newTitle: {
|
|
1042
1127
|
type: 'string',
|
|
1043
|
-
description: 'New title for
|
|
1128
|
+
description: 'New title for the note — used by rename. Works for both local and TeamSpace notes. For local notes this renames the file and updates the # heading.',
|
|
1044
1129
|
},
|
|
1045
1130
|
keepExtension: {
|
|
1046
1131
|
type: 'boolean',
|
|
@@ -1060,14 +1145,14 @@ export function createServer() {
|
|
|
1060
1145
|
},
|
|
1061
1146
|
{
|
|
1062
1147
|
name: 'noteplan_edit_content',
|
|
1063
|
-
description: 'Edit note content:
|
|
1148
|
+
description: 'Edit note content. IMPORTANT: action values use snake_case.\n\nValid actions (exactly these strings):\n- "insert": Insert at position. Combine any position with heading="Section Name" to scope insertion to that section. position="start" + heading inserts right after the heading. position="end" + heading appends at end of the heading\'s section. position="after-heading" inserts right after a heading. position="in-section" appends at end of a heading\'s section. position="start" (no heading) inserts after frontmatter. position="at-line" inserts at a specific line number. position="end" (no heading) appends to note.\n- "append": Shorthand for insert at end. Supports heading="Section Name" to append at end of that section. Use date="today" to append to today\'s daily note.\n- "delete_lines": Delete a line range. Requires startLine + endLine (1-indexed). Use dryRun=true first, then confirmationToken to execute.\n- "edit_line": Edit a single line. Requires line (1-indexed) + content. Set content="" to clear a line.\n- "replace_lines": Replace a line range. Requires startLine + endLine + content. Use dryRun=true first, then confirmationToken to execute.\n\nTarget note via id, filename, title, date, or query. Calendar notes (date param) are auto-created if they don\'t exist yet. Always use tab characters for indentation.\n\nAdding tasks: When inserting a task, set type="task" and pass only the task text as content (e.g. content="Buy groceries", type="task"). Do NOT include raw markers like "* [ ]" or "- [ ]" in content — the type parameter handles formatting to match the user\'s configured style. For checklists use type="checklist". For task lifecycle (complete, update, search), use noteplan_paragraphs instead.\n\nSchedule tasks with >YYYY-MM-DD. Link to notes with [[Note Name]]. Never add block IDs (^id).\n\nUse scheduleDate to auto-append >YYYY-MM-DD to content.',
|
|
1064
1149
|
inputSchema: {
|
|
1065
1150
|
type: 'object',
|
|
1066
1151
|
properties: {
|
|
1067
1152
|
action: {
|
|
1068
1153
|
type: 'string',
|
|
1069
|
-
enum: ['insert', 'append', 'delete_lines', 'edit_line', 'replace_lines'],
|
|
1070
|
-
description: 'Action
|
|
1154
|
+
enum: ['insert', 'append', 'delete_lines', 'edit_line', 'replace_lines', 'list_actions'],
|
|
1155
|
+
description: 'Action: insert | append | delete_lines | edit_line | replace_lines | list_actions (discover all actions)',
|
|
1071
1156
|
},
|
|
1072
1157
|
id: {
|
|
1073
1158
|
type: 'string',
|
|
@@ -1095,16 +1180,16 @@ export function createServer() {
|
|
|
1095
1180
|
},
|
|
1096
1181
|
content: {
|
|
1097
1182
|
type: 'string',
|
|
1098
|
-
description: 'Content to insert/append/replace, or new line content for edit_line',
|
|
1183
|
+
description: 'Content to insert/append/replace, or new line content for edit_line. NEVER include task markers like "- [ ]", "* [ ]", or "* " — instead set type="task" and pass only the task text (e.g. content="Buy groceries", NOT content="- [ ] Buy groceries").',
|
|
1099
1184
|
},
|
|
1100
1185
|
position: {
|
|
1101
1186
|
type: 'string',
|
|
1102
1187
|
enum: ['start', 'end', 'after-heading', 'at-line', 'in-section'],
|
|
1103
|
-
description: 'Where to insert
|
|
1188
|
+
description: 'Where to insert. With heading: start=right after heading, end/in-section=end of section. Without heading: start=after frontmatter, end=bottom of note. at-line=specific line number — used by insert',
|
|
1104
1189
|
},
|
|
1105
1190
|
heading: {
|
|
1106
1191
|
type: 'string',
|
|
1107
|
-
description: 'Heading or section marker text (required for after-heading and in-section; matches both ## headings and **bold:** section markers) — used by insert',
|
|
1192
|
+
description: 'Heading or section marker text (required for after-heading and in-section; matches both ## headings and **bold:** section markers) — used by insert, append',
|
|
1108
1193
|
},
|
|
1109
1194
|
line: {
|
|
1110
1195
|
type: 'number',
|
|
@@ -1167,14 +1252,14 @@ export function createServer() {
|
|
|
1167
1252
|
},
|
|
1168
1253
|
{
|
|
1169
1254
|
name: 'noteplan_paragraphs',
|
|
1170
|
-
description: '
|
|
1255
|
+
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 line)\n- update: Update task content/status (requires filename + lineIndex or line)',
|
|
1171
1256
|
inputSchema: {
|
|
1172
1257
|
type: 'object',
|
|
1173
1258
|
properties: {
|
|
1174
1259
|
action: {
|
|
1175
1260
|
type: 'string',
|
|
1176
|
-
enum: ['get', 'search', 'search_global', 'add', 'complete', 'update'],
|
|
1177
|
-
description: 'Action
|
|
1261
|
+
enum: ['get', 'search', 'search_global', 'add', 'complete', 'update', 'list_actions'],
|
|
1262
|
+
description: 'Action: get | search | search_global | add | complete | update | list_actions (discover all actions)',
|
|
1178
1263
|
},
|
|
1179
1264
|
id: {
|
|
1180
1265
|
type: 'string',
|
|
@@ -1236,16 +1321,16 @@ export function createServer() {
|
|
|
1236
1321
|
},
|
|
1237
1322
|
target: {
|
|
1238
1323
|
type: 'string',
|
|
1239
|
-
description: 'Target for add: date (today
|
|
1324
|
+
description: 'Target note for add: use a date string (today, tomorrow, yesterday, YYYY-MM-DD, YYYYMMDD) for daily/calendar notes, or a filename path for project notes. Daily notes are auto-created if they don\'t exist.',
|
|
1240
1325
|
},
|
|
1241
1326
|
position: {
|
|
1242
1327
|
type: 'string',
|
|
1243
1328
|
enum: ['start', 'end', 'after-heading', 'in-section'],
|
|
1244
|
-
description: 'Where to add task (default: end) — used by add',
|
|
1329
|
+
description: 'Where to add task (default: end). With heading: start=right after heading, end/in-section=end of section. Without heading: start=top of note, end=bottom of note — used by add',
|
|
1245
1330
|
},
|
|
1246
1331
|
heading: {
|
|
1247
1332
|
type: 'string',
|
|
1248
|
-
description: 'Heading or section marker text (matches both ## headings and **bold:** section markers) — used by add',
|
|
1333
|
+
description: 'Heading or section marker text to scope insertion (matches both ## headings and **bold:** section markers). Combine with position to control placement — used by add',
|
|
1249
1334
|
},
|
|
1250
1335
|
lineIndex: {
|
|
1251
1336
|
type: 'number',
|
|
@@ -1320,8 +1405,8 @@ export function createServer() {
|
|
|
1320
1405
|
properties: {
|
|
1321
1406
|
action: {
|
|
1322
1407
|
type: 'string',
|
|
1323
|
-
enum: ['list', 'find', 'resolve', 'create', 'move', 'rename', 'delete', 'list_spaces'],
|
|
1324
|
-
description: 'Action
|
|
1408
|
+
enum: ['list', 'find', 'resolve', 'create', 'move', 'rename', 'delete', 'list_spaces', 'list_actions'],
|
|
1409
|
+
description: 'Action: list | find | resolve | create | move | rename | delete | list_spaces | list_actions (discover all actions)',
|
|
1325
1410
|
},
|
|
1326
1411
|
path: {
|
|
1327
1412
|
type: 'string',
|
|
@@ -1423,8 +1508,8 @@ export function createServer() {
|
|
|
1423
1508
|
properties: {
|
|
1424
1509
|
action: {
|
|
1425
1510
|
type: 'string',
|
|
1426
|
-
enum: ['list', 'get', 'get_tasks', 'list_parameters', 'save', 'rename'],
|
|
1427
|
-
description: 'Action
|
|
1511
|
+
enum: ['list', 'get', 'get_tasks', 'list_parameters', 'save', 'rename', 'list_actions'],
|
|
1512
|
+
description: 'Action: list | get | get_tasks | list_parameters | save | rename | list_actions (discover all actions)',
|
|
1428
1513
|
},
|
|
1429
1514
|
name: {
|
|
1430
1515
|
type: 'string',
|
|
@@ -1508,8 +1593,8 @@ export function createServer() {
|
|
|
1508
1593
|
},
|
|
1509
1594
|
action: {
|
|
1510
1595
|
type: 'string',
|
|
1511
|
-
enum: ['get_events', 'list_calendars', 'create_event', 'update_event', 'delete_event', 'get', 'list_lists', 'create', 'complete', 'update', 'delete'],
|
|
1512
|
-
description: 'Action
|
|
1596
|
+
enum: ['get_events', 'list_calendars', 'create_event', 'update_event', 'delete_event', 'get', 'list_lists', 'create', 'complete', 'update', 'delete', 'list_actions'],
|
|
1597
|
+
description: 'Action: get_events | list_calendars | create_event | update_event | delete_event | get | list_lists | create | complete | update | delete | list_actions (discover all actions)',
|
|
1513
1598
|
},
|
|
1514
1599
|
// Calendar params
|
|
1515
1600
|
eventId: {
|
|
@@ -1610,8 +1695,8 @@ export function createServer() {
|
|
|
1610
1695
|
properties: {
|
|
1611
1696
|
action: {
|
|
1612
1697
|
type: 'string',
|
|
1613
|
-
enum: ['list', 'save', 'update', 'delete'],
|
|
1614
|
-
description: 'Action
|
|
1698
|
+
enum: ['list', 'save', 'update', 'delete', 'list_actions'],
|
|
1699
|
+
description: 'Action: list | save | update | delete | list_actions (discover all actions)',
|
|
1615
1700
|
},
|
|
1616
1701
|
id: {
|
|
1617
1702
|
type: 'string',
|
|
@@ -1657,8 +1742,8 @@ export function createServer() {
|
|
|
1657
1742
|
properties: {
|
|
1658
1743
|
action: {
|
|
1659
1744
|
type: 'string',
|
|
1660
|
-
enum: ['search', 'list_tags'],
|
|
1661
|
-
description: 'Action to perform (default: search)',
|
|
1745
|
+
enum: ['search', 'list_tags', 'list_actions'],
|
|
1746
|
+
description: 'Action to perform (default: search) | list_actions (discover all actions)',
|
|
1662
1747
|
},
|
|
1663
1748
|
query: {
|
|
1664
1749
|
type: 'string',
|
|
@@ -1746,8 +1831,8 @@ export function createServer() {
|
|
|
1746
1831
|
properties: {
|
|
1747
1832
|
action: {
|
|
1748
1833
|
type: 'string',
|
|
1749
|
-
enum: ['status', 'search', 'sync', 'reset'],
|
|
1750
|
-
description: 'Action
|
|
1834
|
+
enum: ['status', 'search', 'sync', 'reset', 'list_actions'],
|
|
1835
|
+
description: 'Action: status | search | sync | reset | list_actions (discover all actions)',
|
|
1751
1836
|
},
|
|
1752
1837
|
query: {
|
|
1753
1838
|
type: 'string',
|
|
@@ -1824,196 +1909,282 @@ export function createServer() {
|
|
|
1824
1909
|
},
|
|
1825
1910
|
});
|
|
1826
1911
|
}
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
},
|
|
1839
|
-
title: {
|
|
1840
|
-
type: 'string',
|
|
1841
|
-
description: 'Note title — used by open_note; window title — used by close_plugin_window',
|
|
1842
|
-
},
|
|
1843
|
-
filename: {
|
|
1844
|
-
type: 'string',
|
|
1845
|
-
description: 'Filename — used by open_note',
|
|
1846
|
-
},
|
|
1847
|
-
inNewWindow: {
|
|
1848
|
-
type: 'boolean',
|
|
1849
|
-
description: 'Open in new window — used by open_note',
|
|
1850
|
-
},
|
|
1851
|
-
inSplitView: {
|
|
1852
|
-
type: 'boolean',
|
|
1853
|
-
description: 'Open in split view — used by open_note',
|
|
1854
|
-
},
|
|
1855
|
-
query: {
|
|
1856
|
-
type: 'string',
|
|
1857
|
-
description: 'Search text — used by search',
|
|
1858
|
-
},
|
|
1859
|
-
pluginId: {
|
|
1860
|
-
type: 'string',
|
|
1861
|
-
description: 'Plugin ID — used by run_plugin',
|
|
1862
|
-
},
|
|
1863
|
-
command: {
|
|
1864
|
-
type: 'string',
|
|
1865
|
-
description: 'Command name — used by run_plugin',
|
|
1866
|
-
},
|
|
1867
|
-
arguments: {
|
|
1868
|
-
type: 'string',
|
|
1869
|
-
description: 'JSON arguments string — used by run_plugin',
|
|
1870
|
-
},
|
|
1871
|
-
name: {
|
|
1872
|
-
type: 'string',
|
|
1873
|
-
description: 'View name — used by open_view',
|
|
1874
|
-
},
|
|
1875
|
-
windowID: {
|
|
1876
|
-
type: 'string',
|
|
1877
|
-
description: 'Window ID — used by close_plugin_window',
|
|
1878
|
-
},
|
|
1912
|
+
// noteplan_ui is always available — basic AppleScript commands work on all NotePlan versions
|
|
1913
|
+
toolDefinitions.push({
|
|
1914
|
+
name: 'noteplan_ui',
|
|
1915
|
+
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 of all notes, calendars, themes, filters, and plugin data. Old backups are pruned automatically.',
|
|
1916
|
+
inputSchema: {
|
|
1917
|
+
type: 'object',
|
|
1918
|
+
properties: {
|
|
1919
|
+
action: {
|
|
1920
|
+
type: 'string',
|
|
1921
|
+
enum: ['open_note', 'open_today', 'search', 'run_plugin', 'open_view', 'toggle_sidebar', 'close_plugin_window', 'list_plugin_windows', 'backup', 'list_actions'],
|
|
1922
|
+
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)',
|
|
1879
1923
|
},
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
enum: ['main', 'split', 'window'],
|
|
1920
|
-
description: 'Display mode (default: main) — used by create',
|
|
1921
|
-
},
|
|
1922
|
-
autoLaunch: {
|
|
1923
|
-
type: 'boolean',
|
|
1924
|
-
description: 'Auto-reload and run — used by create, update_html',
|
|
1925
|
-
},
|
|
1926
|
-
patches: {
|
|
1927
|
-
type: 'array',
|
|
1928
|
-
items: {
|
|
1929
|
-
type: 'object',
|
|
1930
|
-
properties: {
|
|
1931
|
-
find: { type: 'string' },
|
|
1932
|
-
replace: { type: 'string' },
|
|
1933
|
-
},
|
|
1934
|
-
required: ['find', 'replace'],
|
|
1935
|
-
},
|
|
1936
|
-
description: 'Find/replace patches — used by update_html',
|
|
1937
|
-
},
|
|
1938
|
-
query: {
|
|
1939
|
-
type: 'string',
|
|
1940
|
-
description: 'Filter/search — used by list, list_available, source',
|
|
1941
|
-
},
|
|
1942
|
-
includeBeta: {
|
|
1943
|
-
type: 'boolean',
|
|
1944
|
-
description: 'Include beta plugins — used by list_available',
|
|
1945
|
-
},
|
|
1946
|
-
tail: {
|
|
1947
|
-
type: 'integer',
|
|
1948
|
-
description: 'Return last N lines — used by log',
|
|
1949
|
-
},
|
|
1950
|
-
clear: {
|
|
1951
|
-
type: 'boolean',
|
|
1952
|
-
description: 'Clear log after reading — used by log',
|
|
1953
|
-
},
|
|
1954
|
-
startLine: {
|
|
1955
|
-
type: 'integer',
|
|
1956
|
-
description: 'Start line (1-based) — used by source',
|
|
1957
|
-
},
|
|
1958
|
-
endLine: {
|
|
1959
|
-
type: 'integer',
|
|
1960
|
-
description: 'End line (1-based) — used by source',
|
|
1961
|
-
},
|
|
1962
|
-
contextLines: {
|
|
1963
|
-
type: 'integer',
|
|
1964
|
-
description: 'Context lines around matches — used by source',
|
|
1965
|
-
},
|
|
1966
|
-
confirmationToken: {
|
|
1967
|
-
type: 'string',
|
|
1968
|
-
description: 'Token for confirmation — used by delete',
|
|
1969
|
-
},
|
|
1924
|
+
title: {
|
|
1925
|
+
type: 'string',
|
|
1926
|
+
description: 'Note title — used by open_note; window title — used by close_plugin_window',
|
|
1927
|
+
},
|
|
1928
|
+
filename: {
|
|
1929
|
+
type: 'string',
|
|
1930
|
+
description: 'Filename — used by open_note',
|
|
1931
|
+
},
|
|
1932
|
+
inNewWindow: {
|
|
1933
|
+
type: 'boolean',
|
|
1934
|
+
description: 'Open in new window — used by open_note',
|
|
1935
|
+
},
|
|
1936
|
+
inSplitView: {
|
|
1937
|
+
type: 'boolean',
|
|
1938
|
+
description: 'Open in split view — used by open_note',
|
|
1939
|
+
},
|
|
1940
|
+
query: {
|
|
1941
|
+
type: 'string',
|
|
1942
|
+
description: 'Search text — used by search',
|
|
1943
|
+
},
|
|
1944
|
+
pluginId: {
|
|
1945
|
+
type: 'string',
|
|
1946
|
+
description: 'Plugin ID — used by run_plugin',
|
|
1947
|
+
},
|
|
1948
|
+
command: {
|
|
1949
|
+
type: 'string',
|
|
1950
|
+
description: 'Command name — used by run_plugin',
|
|
1951
|
+
},
|
|
1952
|
+
arguments: {
|
|
1953
|
+
type: 'string',
|
|
1954
|
+
description: 'JSON arguments string — used by run_plugin',
|
|
1955
|
+
},
|
|
1956
|
+
name: {
|
|
1957
|
+
type: 'string',
|
|
1958
|
+
description: 'View name — used by open_view',
|
|
1959
|
+
},
|
|
1960
|
+
windowID: {
|
|
1961
|
+
type: 'string',
|
|
1962
|
+
description: 'Window ID — used by close_plugin_window',
|
|
1970
1963
|
},
|
|
1971
|
-
required: ['action'],
|
|
1972
1964
|
},
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1965
|
+
required: ['action'],
|
|
1966
|
+
},
|
|
1967
|
+
});
|
|
1968
|
+
// Always register all tools — if NotePlan is too old for a specific action,
|
|
1969
|
+
// the action handler returns a helpful upgrade message instead of hiding the tool entirely.
|
|
1970
|
+
toolDefinitions.push({
|
|
1971
|
+
name: 'noteplan_plugins',
|
|
1972
|
+
description: 'Plugin management: list, create, delete, install, read source/log, update HTML, screenshot.\n\nActions:\n- list: List installed plugins\n- list_available: List plugins from online repository\n- create: Create plugin with HTML view (requires pluginId, pluginName, commandName, html)\n- delete: Delete plugin (requires pluginId + confirmationToken)\n- install: Install from repository (requires pluginId)\n- log: Read plugin console log (requires pluginId)\n- source: Read plugin source (requires pluginId)\n- update_html: Apply find/replace patches (requires pluginId + patches)\n- screenshot: Capture plugin WebView screenshot (requires pluginId)',
|
|
1973
|
+
inputSchema: {
|
|
1974
|
+
type: 'object',
|
|
1975
|
+
properties: {
|
|
1976
|
+
action: {
|
|
1977
|
+
type: 'string',
|
|
1978
|
+
enum: ['list', 'list_available', 'create', 'delete', 'install', 'log', 'source', 'update_html', 'screenshot', 'list_actions'],
|
|
1979
|
+
description: 'Action: list | list_available | create | delete | install | log | source | update_html | screenshot | list_actions (discover all actions)',
|
|
1980
|
+
},
|
|
1981
|
+
pluginId: {
|
|
1982
|
+
type: 'string',
|
|
1983
|
+
description: 'Plugin ID — used by create, delete, install, log, source, update_html, screenshot',
|
|
1984
|
+
},
|
|
1985
|
+
pluginName: {
|
|
1986
|
+
type: 'string',
|
|
1987
|
+
description: 'Display name — used by create',
|
|
1988
|
+
},
|
|
1989
|
+
commandName: {
|
|
1990
|
+
type: 'string',
|
|
1991
|
+
description: 'Command name — used by create',
|
|
1992
|
+
},
|
|
1993
|
+
html: {
|
|
1994
|
+
type: 'string',
|
|
1995
|
+
description: 'HTML content — used by create',
|
|
1996
|
+
},
|
|
1997
|
+
icon: {
|
|
1998
|
+
type: 'string',
|
|
1999
|
+
description: 'Font Awesome icon name — used by create',
|
|
2000
|
+
},
|
|
2001
|
+
iconColor: {
|
|
2002
|
+
type: 'string',
|
|
2003
|
+
description: 'Tailwind color — used by create',
|
|
2004
|
+
},
|
|
2005
|
+
displayMode: {
|
|
2006
|
+
type: 'string',
|
|
2007
|
+
enum: ['main', 'split', 'window'],
|
|
2008
|
+
description: 'Display mode (default: main) — used by create',
|
|
2009
|
+
},
|
|
2010
|
+
autoLaunch: {
|
|
2011
|
+
type: 'boolean',
|
|
2012
|
+
description: 'Auto-reload and run — used by create, update_html',
|
|
2013
|
+
},
|
|
2014
|
+
patches: {
|
|
2015
|
+
type: 'array',
|
|
2016
|
+
items: {
|
|
1993
2017
|
type: 'object',
|
|
1994
|
-
description: 'Theme object — used by save',
|
|
1995
2018
|
properties: {
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
author: { type: 'object', properties: { name: { type: 'string' }, email: { type: 'string' } } },
|
|
1999
|
-
editor: { type: 'object' },
|
|
2000
|
-
styles: { type: 'object' },
|
|
2019
|
+
find: { type: 'string' },
|
|
2020
|
+
replace: { type: 'string' },
|
|
2001
2021
|
},
|
|
2022
|
+
required: ['find', 'replace'],
|
|
2002
2023
|
},
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2024
|
+
description: 'Find/replace patches — used by update_html',
|
|
2025
|
+
},
|
|
2026
|
+
query: {
|
|
2027
|
+
type: 'string',
|
|
2028
|
+
description: 'Filter/search — used by list, list_available, source',
|
|
2029
|
+
},
|
|
2030
|
+
includeBeta: {
|
|
2031
|
+
type: 'boolean',
|
|
2032
|
+
description: 'Include beta plugins — used by list_available',
|
|
2033
|
+
},
|
|
2034
|
+
tail: {
|
|
2035
|
+
type: 'integer',
|
|
2036
|
+
description: 'Return last N lines — used by log',
|
|
2037
|
+
},
|
|
2038
|
+
clear: {
|
|
2039
|
+
type: 'boolean',
|
|
2040
|
+
description: 'Clear log after reading — used by log',
|
|
2041
|
+
},
|
|
2042
|
+
startLine: {
|
|
2043
|
+
type: 'integer',
|
|
2044
|
+
description: 'Start line (1-based) — used by source',
|
|
2045
|
+
},
|
|
2046
|
+
endLine: {
|
|
2047
|
+
type: 'integer',
|
|
2048
|
+
description: 'End line (1-based) — used by source',
|
|
2049
|
+
},
|
|
2050
|
+
contextLines: {
|
|
2051
|
+
type: 'integer',
|
|
2052
|
+
description: 'Context lines around matches — used by source',
|
|
2053
|
+
},
|
|
2054
|
+
confirmationToken: {
|
|
2055
|
+
type: 'string',
|
|
2056
|
+
description: 'Token for confirmation — used by delete',
|
|
2057
|
+
},
|
|
2058
|
+
},
|
|
2059
|
+
required: ['action'],
|
|
2060
|
+
},
|
|
2061
|
+
}, {
|
|
2062
|
+
name: 'noteplan_themes',
|
|
2063
|
+
description: 'Theme management: list, get, save, set active.\n\nActions:\n- list: List all themes and active theme names\n- get: Read a custom theme JSON (requires filename)\n- save: Create/update a custom theme (requires filename + theme)\n- set_active: Activate a theme (requires name)',
|
|
2064
|
+
inputSchema: {
|
|
2065
|
+
type: 'object',
|
|
2066
|
+
properties: {
|
|
2067
|
+
action: {
|
|
2068
|
+
type: 'string',
|
|
2069
|
+
enum: ['list', 'get', 'save', 'set_active', 'list_actions'],
|
|
2070
|
+
description: 'Action: list | get | save | set_active | list_actions (discover all actions)',
|
|
2071
|
+
},
|
|
2072
|
+
filename: {
|
|
2073
|
+
type: 'string',
|
|
2074
|
+
description: 'Theme filename — used by get, save',
|
|
2075
|
+
},
|
|
2076
|
+
name: {
|
|
2077
|
+
type: 'string',
|
|
2078
|
+
description: 'Theme name — used by set_active',
|
|
2079
|
+
},
|
|
2080
|
+
theme: {
|
|
2081
|
+
type: 'object',
|
|
2082
|
+
description: 'Theme object — used by save',
|
|
2083
|
+
properties: {
|
|
2084
|
+
name: { type: 'string' },
|
|
2085
|
+
style: { type: 'string', enum: ['Light', 'Dark'] },
|
|
2086
|
+
author: { type: 'object', properties: { name: { type: 'string' }, email: { type: 'string' } } },
|
|
2087
|
+
editor: { type: 'object' },
|
|
2088
|
+
styles: { type: 'object' },
|
|
2011
2089
|
},
|
|
2012
2090
|
},
|
|
2013
|
-
|
|
2091
|
+
setActive: {
|
|
2092
|
+
type: 'boolean',
|
|
2093
|
+
description: 'Apply theme immediately — used by save (default: true)',
|
|
2094
|
+
},
|
|
2095
|
+
mode: {
|
|
2096
|
+
type: 'string',
|
|
2097
|
+
enum: ['light', 'dark', 'auto'],
|
|
2098
|
+
description: 'Mode to apply for — used by save, set_active',
|
|
2099
|
+
},
|
|
2014
2100
|
},
|
|
2015
|
-
|
|
2016
|
-
|
|
2101
|
+
required: ['action'],
|
|
2102
|
+
},
|
|
2103
|
+
}, {
|
|
2104
|
+
name: 'noteplan_templates',
|
|
2105
|
+
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").',
|
|
2106
|
+
inputSchema: {
|
|
2107
|
+
type: 'object',
|
|
2108
|
+
properties: {
|
|
2109
|
+
action: {
|
|
2110
|
+
type: 'string',
|
|
2111
|
+
enum: ['list', 'render', 'search_docs', 'get_doc', 'list_actions'],
|
|
2112
|
+
description: 'Action: list | render | search_docs | get_doc | list_actions (discover all actions)',
|
|
2113
|
+
},
|
|
2114
|
+
templateTitle: {
|
|
2115
|
+
type: 'string',
|
|
2116
|
+
description: 'Template title — used by render (loads a saved template by title)',
|
|
2117
|
+
},
|
|
2118
|
+
content: {
|
|
2119
|
+
type: 'string',
|
|
2120
|
+
description: 'Raw template content string — used by render (renders arbitrary template code for debugging)',
|
|
2121
|
+
},
|
|
2122
|
+
folder: {
|
|
2123
|
+
type: 'string',
|
|
2124
|
+
description: 'Template subfolder — used by list (default: @Templates)',
|
|
2125
|
+
},
|
|
2126
|
+
limit: {
|
|
2127
|
+
type: 'number',
|
|
2128
|
+
description: 'Maximum results — used by list',
|
|
2129
|
+
},
|
|
2130
|
+
offset: {
|
|
2131
|
+
type: 'number',
|
|
2132
|
+
description: 'Pagination offset — used by list',
|
|
2133
|
+
},
|
|
2134
|
+
cursor: {
|
|
2135
|
+
type: 'string',
|
|
2136
|
+
description: 'Cursor from previous page — used by list',
|
|
2137
|
+
},
|
|
2138
|
+
query: {
|
|
2139
|
+
type: 'string',
|
|
2140
|
+
description: 'Search query — used by search_docs',
|
|
2141
|
+
},
|
|
2142
|
+
includeContent: {
|
|
2143
|
+
type: 'boolean',
|
|
2144
|
+
description: 'Include full chunk text in results — used by search_docs',
|
|
2145
|
+
},
|
|
2146
|
+
noteTitle: {
|
|
2147
|
+
type: 'string',
|
|
2148
|
+
description: 'Doc note title — used by get_doc (from search_docs results)',
|
|
2149
|
+
},
|
|
2150
|
+
chunkIndex: {
|
|
2151
|
+
type: 'number',
|
|
2152
|
+
description: 'Chunk index — used by get_doc (from search_docs results, default 0)',
|
|
2153
|
+
},
|
|
2154
|
+
},
|
|
2155
|
+
required: ['action'],
|
|
2156
|
+
},
|
|
2157
|
+
}, {
|
|
2158
|
+
name: 'noteplan_attachments',
|
|
2159
|
+
description: 'Attachment operations: add files/images to notes, list attachments, get attachment data, or move between notes.\n\nActions:\n- add: Write a file to the note\'s _attachments folder. Requires data (base64) + attachmentFilename. Returns markdownLink — use noteplan_edit_content to place it in the note (insertLink defaults to false).\n- list: List all attachments for a note with filenames, sizes, and markdown links.\n- get: Get attachment metadata. Set includeData=true for base64 content. Use maxDataSize to cap large images.\n- move: Move an attachment between notes. Source note via id/filename/title/date, destination via destinationId/destinationFilename/destinationTitle/destinationDate. Moves file, removes old link from source, returns new markdownLink.\n\nAttachments are stored in {notename}_attachments/ sibling folder. Images: , files: . Use attachmentFilename for both add, get, and move.',
|
|
2160
|
+
inputSchema: {
|
|
2161
|
+
type: 'object',
|
|
2162
|
+
properties: {
|
|
2163
|
+
action: {
|
|
2164
|
+
type: 'string',
|
|
2165
|
+
enum: ['add', 'list', 'get', 'move', 'list_actions'],
|
|
2166
|
+
description: 'Action: add | list | get | move | list_actions (discover all actions)',
|
|
2167
|
+
},
|
|
2168
|
+
id: { type: 'string', description: 'Source note ID — used by all actions' },
|
|
2169
|
+
filename: { type: 'string', description: 'Source note filename/path — used by all actions' },
|
|
2170
|
+
title: { type: 'string', description: 'Source note title — used by all actions' },
|
|
2171
|
+
date: { type: 'string', description: 'Source calendar note date (YYYYMMDD or YYYY-MM-DD) — used by all actions' },
|
|
2172
|
+
query: { type: 'string', description: 'Search query to find the source note' },
|
|
2173
|
+
space: { type: 'string', description: 'Space name or ID' },
|
|
2174
|
+
data: { type: 'string', description: 'Base64-encoded file data — required for add' },
|
|
2175
|
+
attachmentFilename: { type: 'string', description: 'Attachment filename (e.g. "photo.png") — required for add, get, and move' },
|
|
2176
|
+
mimeType: { type: 'string', description: 'MIME type hint (e.g. "image/png") — used by add' },
|
|
2177
|
+
insertLink: { type: 'boolean', description: 'Auto-insert markdown link into note — used by add (default: false). Prefer placing links yourself via noteplan_edit_content.' },
|
|
2178
|
+
destinationId: { type: 'string', description: 'Destination note ID — used by move' },
|
|
2179
|
+
destinationFilename: { type: 'string', description: 'Destination note filename — used by move' },
|
|
2180
|
+
destinationTitle: { type: 'string', description: 'Destination note title — used by move' },
|
|
2181
|
+
destinationDate: { type: 'string', description: 'Destination calendar note date — used by move' },
|
|
2182
|
+
includeData: { type: 'boolean', description: 'Include base64 data in response — used by get (default: false)' },
|
|
2183
|
+
maxDataSize: { type: 'number', description: 'Max file size in bytes for data inclusion — used by get. Files exceeding this are skipped.' },
|
|
2184
|
+
},
|
|
2185
|
+
required: ['action'],
|
|
2186
|
+
},
|
|
2187
|
+
});
|
|
2017
2188
|
const annotatedToolDefinitions = toolDefinitions.map((tool) => ({
|
|
2018
2189
|
...tool,
|
|
2019
2190
|
inputSchema: withDebugTimingsInputSchema(tool.inputSchema),
|
|
@@ -2030,42 +2201,178 @@ export function createServer() {
|
|
|
2030
2201
|
});
|
|
2031
2202
|
// Register resource listing handler
|
|
2032
2203
|
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2204
|
+
const pluginResources = PLUGIN_API_RESOURCES.map((r) => ({
|
|
2205
|
+
uri: `noteplan://plugin-api/${r.file}`,
|
|
2206
|
+
name: r.name,
|
|
2207
|
+
description: r.desc,
|
|
2208
|
+
mimeType: r.file.endsWith('.md') ? 'text/markdown' : r.file.endsWith('.json') ? 'application/json' : 'text/javascript',
|
|
2209
|
+
}));
|
|
2210
|
+
const generalResources = GENERAL_DOC_RESOURCES.map((r) => ({
|
|
2211
|
+
uri: `noteplan://docs/${r.file}`,
|
|
2212
|
+
name: r.name,
|
|
2213
|
+
description: r.desc,
|
|
2214
|
+
mimeType: 'text/markdown',
|
|
2215
|
+
}));
|
|
2216
|
+
return { resources: [...pluginResources, ...generalResources] };
|
|
2041
2217
|
});
|
|
2042
2218
|
// Register resource read handler
|
|
2043
2219
|
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
2044
2220
|
const uri = request.params.uri;
|
|
2045
|
-
const
|
|
2046
|
-
|
|
2047
|
-
|
|
2221
|
+
const pluginPrefix = 'noteplan://plugin-api/';
|
|
2222
|
+
const docsPrefix = 'noteplan://docs/';
|
|
2223
|
+
let filePath;
|
|
2224
|
+
if (uri.startsWith(pluginPrefix)) {
|
|
2225
|
+
const filename = uri.slice(pluginPrefix.length);
|
|
2226
|
+
const entry = PLUGIN_API_RESOURCES.find((r) => r.file === filename);
|
|
2227
|
+
if (!entry) {
|
|
2228
|
+
throw new Error(`Unknown resource: ${filename}. Available: ${PLUGIN_API_RESOURCES.map((r) => r.file).join(', ')}`);
|
|
2229
|
+
}
|
|
2230
|
+
filePath = path.join(PLUGIN_API_DOCS_DIR, entry.file);
|
|
2231
|
+
}
|
|
2232
|
+
else if (uri.startsWith(docsPrefix)) {
|
|
2233
|
+
const filename = uri.slice(docsPrefix.length);
|
|
2234
|
+
const entry = GENERAL_DOC_RESOURCES.find((r) => r.file === filename);
|
|
2235
|
+
if (!entry) {
|
|
2236
|
+
throw new Error(`Unknown resource: ${filename}. Available: ${GENERAL_DOC_RESOURCES.map((r) => r.file).join(', ')}`);
|
|
2237
|
+
}
|
|
2238
|
+
filePath = path.join(DOCS_DIR, entry.file);
|
|
2048
2239
|
}
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
if (!entry) {
|
|
2052
|
-
throw new Error(`Unknown resource: ${filename}. Available: ${PLUGIN_API_RESOURCES.map((r) => r.file).join(', ')}`);
|
|
2240
|
+
else {
|
|
2241
|
+
throw new Error(`Unknown resource URI: ${uri}`);
|
|
2053
2242
|
}
|
|
2054
|
-
const filePath = path.join(PLUGIN_API_DOCS_DIR, entry.file);
|
|
2055
2243
|
if (!fs.existsSync(filePath)) {
|
|
2056
2244
|
throw new Error(`Resource file not found on disk: ${filePath}`);
|
|
2057
2245
|
}
|
|
2058
2246
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
2247
|
+
const mimeType = filePath.endsWith('.md') ? 'text/markdown' : filePath.endsWith('.json') ? 'application/json' : 'text/javascript';
|
|
2059
2248
|
return {
|
|
2060
|
-
contents: [
|
|
2061
|
-
{
|
|
2062
|
-
uri,
|
|
2063
|
-
mimeType: entry.file.endsWith('.md') ? 'text/markdown' : entry.file.endsWith('.json') ? 'application/json' : 'text/javascript',
|
|
2064
|
-
text: content,
|
|
2065
|
-
},
|
|
2066
|
-
],
|
|
2249
|
+
contents: [{ uri, mimeType, text: content }],
|
|
2067
2250
|
};
|
|
2068
2251
|
});
|
|
2252
|
+
// ── Action registry for list_actions discovery ──
|
|
2253
|
+
const TOOL_ACTIONS = {
|
|
2254
|
+
noteplan_get_notes: [
|
|
2255
|
+
{ action: 'get', description: 'Get a single note by id, filename, title, date, or query' },
|
|
2256
|
+
{ action: 'list', description: 'List notes with optional folder/type/date filtering' },
|
|
2257
|
+
{ action: 'resolve', description: 'Resolve a reference (title, filename, query) to a single note' },
|
|
2258
|
+
{ action: 'today', description: 'Get today\'s daily note' },
|
|
2259
|
+
{ action: 'calendar', description: 'Get a calendar note by date' },
|
|
2260
|
+
{ action: 'periodic', description: 'Get a periodic note (week, month, quarter, year)' },
|
|
2261
|
+
{ action: 'range', description: 'Get calendar notes in a date range' },
|
|
2262
|
+
],
|
|
2263
|
+
noteplan_search: [
|
|
2264
|
+
{ action: 'search', description: 'Full-text or metadata search across notes' },
|
|
2265
|
+
{ action: 'list_tags', description: 'List all tags/hashtags with optional filtering' },
|
|
2266
|
+
],
|
|
2267
|
+
noteplan_manage_note: [
|
|
2268
|
+
{ action: 'create', description: 'Create a project note (requires title)' },
|
|
2269
|
+
{ action: 'update', description: 'Replace note content (requires filename, content, fullReplace + confirmationToken)' },
|
|
2270
|
+
{ action: 'delete', description: 'Delete a note (requires dryRun/confirmationToken)' },
|
|
2271
|
+
{ action: 'move', description: 'Move a note to another folder (requires dryRun/confirmationToken)' },
|
|
2272
|
+
{ action: 'restore', description: 'Restore a trashed note (requires dryRun/confirmationToken)' },
|
|
2273
|
+
{ action: 'rename', description: 'Rename a note (requires newTitle)' },
|
|
2274
|
+
{ action: 'set_property', description: 'Set a frontmatter property (requires key + value)' },
|
|
2275
|
+
{ action: 'remove_property', description: 'Remove a frontmatter property (requires key)' },
|
|
2276
|
+
],
|
|
2277
|
+
noteplan_edit_content: [
|
|
2278
|
+
{ action: 'insert', description: 'Insert content at a position. Use heading param to scope to a section' },
|
|
2279
|
+
{ action: 'append', description: 'Append content at end of note or section' },
|
|
2280
|
+
{ action: 'delete_lines', description: 'Delete a line range (requires startLine + endLine, 1-indexed)' },
|
|
2281
|
+
{ action: 'edit_line', description: 'Edit a single line (requires line + content)' },
|
|
2282
|
+
{ action: 'replace_lines', description: 'Replace a line range (requires startLine + endLine + content)' },
|
|
2283
|
+
],
|
|
2284
|
+
noteplan_paragraphs: [
|
|
2285
|
+
{ action: 'get', description: 'Get note lines with metadata (requires filename)' },
|
|
2286
|
+
{ action: 'search', description: 'Search for matching lines in a note (requires query + note ref)' },
|
|
2287
|
+
{ action: 'search_global', description: 'Search tasks across all notes (requires query, supports "*" wildcard)' },
|
|
2288
|
+
{ action: 'add', description: 'Add a task (requires target + content)' },
|
|
2289
|
+
{ action: 'complete', description: 'Mark task done (requires filename + lineIndex or line)' },
|
|
2290
|
+
{ action: 'update', description: 'Update task content/status (requires filename + lineIndex or line)' },
|
|
2291
|
+
],
|
|
2292
|
+
noteplan_folders: [
|
|
2293
|
+
{ action: 'list', description: 'List folders with optional filtering' },
|
|
2294
|
+
{ action: 'find', description: 'Find folder matches for exploration' },
|
|
2295
|
+
{ action: 'resolve', description: 'Resolve to one canonical folder path' },
|
|
2296
|
+
{ action: 'create', description: 'Create a folder' },
|
|
2297
|
+
{ action: 'move', description: 'Move a folder (requires dryRun/confirmationToken)' },
|
|
2298
|
+
{ action: 'rename', description: 'Rename a folder (requires dryRun/confirmationToken)' },
|
|
2299
|
+
{ action: 'delete', description: 'Delete folder to trash (requires dryRun/confirmationToken)' },
|
|
2300
|
+
{ action: 'list_spaces', description: 'List spaces/workspaces' },
|
|
2301
|
+
],
|
|
2302
|
+
noteplan_filters: [
|
|
2303
|
+
{ action: 'list', description: 'List saved filters' },
|
|
2304
|
+
{ action: 'get', description: 'Get one filter with parsed params (requires name)' },
|
|
2305
|
+
{ action: 'get_tasks', description: 'Execute a filter against tasks (requires name)' },
|
|
2306
|
+
{ action: 'list_parameters', description: 'List supported filter parameter keys' },
|
|
2307
|
+
{ action: 'save', description: 'Create or update a filter (requires name + items)' },
|
|
2308
|
+
{ action: 'rename', description: 'Rename a filter (requires oldName + newName)' },
|
|
2309
|
+
],
|
|
2310
|
+
noteplan_eventkit: [
|
|
2311
|
+
{ action: 'get_events', description: 'Get events for a date/range (source: calendar)' },
|
|
2312
|
+
{ action: 'list_calendars', description: 'List all calendars (source: calendar)' },
|
|
2313
|
+
{ action: 'create_event', description: 'Create event (source: calendar, requires title + startDate)' },
|
|
2314
|
+
{ action: 'update_event', description: 'Update event (source: calendar, requires eventId)' },
|
|
2315
|
+
{ action: 'delete_event', description: 'Delete event (source: calendar, requires eventId + dryRun/confirmationToken)' },
|
|
2316
|
+
{ action: 'get', description: 'Get reminders (source: reminders, optional list/query filter)' },
|
|
2317
|
+
{ action: 'list_lists', description: 'List reminder lists (source: reminders)' },
|
|
2318
|
+
{ action: 'create', description: 'Create reminder (source: reminders, requires title)' },
|
|
2319
|
+
{ action: 'complete', description: 'Mark reminder done (source: reminders, requires reminderId)' },
|
|
2320
|
+
{ action: 'update', description: 'Update reminder (source: reminders, requires reminderId)' },
|
|
2321
|
+
{ action: 'delete', description: 'Delete reminder (source: reminders, requires reminderId + dryRun/confirmationToken)' },
|
|
2322
|
+
],
|
|
2323
|
+
noteplan_memory: [
|
|
2324
|
+
{ action: 'list', description: 'List/search stored memories' },
|
|
2325
|
+
{ action: 'save', description: 'Save a new memory (requires content)' },
|
|
2326
|
+
{ action: 'update', description: 'Update memory content/tags (requires id)' },
|
|
2327
|
+
{ action: 'delete', description: 'Delete a memory (requires id)' },
|
|
2328
|
+
],
|
|
2329
|
+
noteplan_ui: [
|
|
2330
|
+
{ action: 'open_note', description: 'Open a note by title or filename' },
|
|
2331
|
+
{ action: 'open_today', description: 'Open today\'s note' },
|
|
2332
|
+
{ action: 'search', description: 'Search in UI' },
|
|
2333
|
+
{ action: 'run_plugin', description: 'Run a plugin command (requires pluginId + command)' },
|
|
2334
|
+
{ action: 'open_view', description: 'Open a named view' },
|
|
2335
|
+
{ action: 'toggle_sidebar', description: 'Toggle sidebar visibility' },
|
|
2336
|
+
{ action: 'close_plugin_window', description: 'Close plugin window (by windowID/title, or omit both to close all)' },
|
|
2337
|
+
{ action: 'list_plugin_windows', description: 'List open plugin windows' },
|
|
2338
|
+
{ action: 'backup', description: 'Create a full backup of all notes, calendars, themes, filters, and plugin data' },
|
|
2339
|
+
],
|
|
2340
|
+
noteplan_plugins: [
|
|
2341
|
+
{ action: 'list', description: 'List installed plugins' },
|
|
2342
|
+
{ action: 'list_available', description: 'List plugins from online repository' },
|
|
2343
|
+
{ action: 'create', description: 'Create plugin with HTML view (requires pluginId, pluginName, commandName, html)' },
|
|
2344
|
+
{ action: 'delete', description: 'Delete plugin (requires pluginId + confirmationToken)' },
|
|
2345
|
+
{ action: 'install', description: 'Install from repository (requires pluginId)' },
|
|
2346
|
+
{ action: 'log', description: 'Read plugin console log (requires pluginId)' },
|
|
2347
|
+
{ action: 'source', description: 'Read plugin source (requires pluginId)' },
|
|
2348
|
+
{ action: 'update_html', description: 'Apply find/replace patches (requires pluginId + patches)' },
|
|
2349
|
+
{ action: 'screenshot', description: 'Capture plugin WebView screenshot (requires pluginId)' },
|
|
2350
|
+
],
|
|
2351
|
+
noteplan_themes: [
|
|
2352
|
+
{ action: 'list', description: 'List all themes and active theme names' },
|
|
2353
|
+
{ action: 'get', description: 'Read a custom theme JSON (requires filename)' },
|
|
2354
|
+
{ action: 'save', description: 'Create/update a custom theme (requires filename + theme)' },
|
|
2355
|
+
{ action: 'set_active', description: 'Activate a theme (requires name)' },
|
|
2356
|
+
],
|
|
2357
|
+
noteplan_embeddings: [
|
|
2358
|
+
{ action: 'status', description: 'Get embeddings config and index status' },
|
|
2359
|
+
{ action: 'search', description: 'Semantic search over indexed notes (requires query)' },
|
|
2360
|
+
{ action: 'sync', description: 'Build/refresh embeddings index' },
|
|
2361
|
+
{ action: 'reset', description: 'Delete index rows (requires dryRun/confirmationToken)' },
|
|
2362
|
+
],
|
|
2363
|
+
noteplan_templates: [
|
|
2364
|
+
{ action: 'list', description: 'List templates from @Templates folder with types and preview' },
|
|
2365
|
+
{ action: 'render', description: 'Render a template by title or raw content string' },
|
|
2366
|
+
{ 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' },
|
|
2367
|
+
{ action: 'get_doc', description: 'Get full text of a doc chunk by noteTitle + chunkIndex (from search_docs results)' },
|
|
2368
|
+
],
|
|
2369
|
+
noteplan_attachments: [
|
|
2370
|
+
{ action: 'add', description: 'Write a file to the note\'s _attachments folder (requires data + attachmentFilename)' },
|
|
2371
|
+
{ action: 'list', description: 'List all attachments for a note' },
|
|
2372
|
+
{ action: 'get', description: 'Get attachment metadata. Set includeData=true for base64 content' },
|
|
2373
|
+
{ action: 'move', description: 'Move an attachment between notes' },
|
|
2374
|
+
],
|
|
2375
|
+
};
|
|
2069
2376
|
// Register tool call handler
|
|
2070
2377
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
2071
2378
|
const { name, arguments: args } = request.params;
|
|
@@ -2074,6 +2381,12 @@ export function createServer() {
|
|
|
2074
2381
|
const startTime = Date.now();
|
|
2075
2382
|
try {
|
|
2076
2383
|
let result;
|
|
2384
|
+
// ── Intercept list_actions for any tool with an action registry ──
|
|
2385
|
+
if (args?.action === 'list_actions' && TOOL_ACTIONS[normalizedName]) {
|
|
2386
|
+
result = { success: true, tool: normalizedName, actions: TOOL_ACTIONS[normalizedName] };
|
|
2387
|
+
const resultWithDuration = withDuration(result, Date.now() - startTime, includeTiming);
|
|
2388
|
+
return { content: [{ type: 'text', text: JSON.stringify(resultWithDuration, null, 2) }] };
|
|
2389
|
+
}
|
|
2077
2390
|
switch (normalizedName) {
|
|
2078
2391
|
// ── Primary consolidated tools ──
|
|
2079
2392
|
case 'noteplan_get_notes':
|
|
@@ -2121,7 +2434,7 @@ export function createServer() {
|
|
|
2121
2434
|
case 'remove_property':
|
|
2122
2435
|
result = noteTools.removeProperty(args);
|
|
2123
2436
|
break;
|
|
2124
|
-
default: throw new Error(`Unknown action: ${action}`);
|
|
2437
|
+
default: throw new Error(`Unknown action: "${action}". Valid actions: create, update, delete, move, restore, rename, set_property, remove_property`);
|
|
2125
2438
|
}
|
|
2126
2439
|
break;
|
|
2127
2440
|
}
|
|
@@ -2152,7 +2465,7 @@ export function createServer() {
|
|
|
2152
2465
|
case 'replace_lines':
|
|
2153
2466
|
result = noteTools.replaceLines(a);
|
|
2154
2467
|
break;
|
|
2155
|
-
default: throw new Error(`Unknown action: ${action}`);
|
|
2468
|
+
default: throw new Error(`Unknown action: "${action}". Valid actions: insert, append, delete_lines, edit_line, replace_lines (snake_case required)`);
|
|
2156
2469
|
}
|
|
2157
2470
|
break;
|
|
2158
2471
|
}
|
|
@@ -2166,6 +2479,10 @@ export function createServer() {
|
|
|
2166
2479
|
if (a.scheduleDate && a.content) {
|
|
2167
2480
|
a.content = appendScheduleDate(a.content, a.scheduleDate);
|
|
2168
2481
|
}
|
|
2482
|
+
// Derive `target` for addTaskToNote from date/filename when not provided
|
|
2483
|
+
if (!a.target && (a.date || a.filename)) {
|
|
2484
|
+
a.target = a.date || a.filename;
|
|
2485
|
+
}
|
|
2169
2486
|
const action = a?.action;
|
|
2170
2487
|
switch (action) {
|
|
2171
2488
|
case 'get':
|
|
@@ -2175,7 +2492,7 @@ export function createServer() {
|
|
|
2175
2492
|
result = noteTools.searchParagraphs(a);
|
|
2176
2493
|
break;
|
|
2177
2494
|
case 'search_global':
|
|
2178
|
-
result =
|
|
2495
|
+
result = noteTools.searchParagraphsGlobal(a);
|
|
2179
2496
|
break;
|
|
2180
2497
|
case 'add':
|
|
2181
2498
|
result = taskTools.addTaskToNote(a);
|
|
@@ -2346,7 +2663,67 @@ export function createServer() {
|
|
|
2346
2663
|
case 'list_plugin_windows':
|
|
2347
2664
|
result = uiTools.listPluginWindows(args);
|
|
2348
2665
|
break;
|
|
2349
|
-
|
|
2666
|
+
case 'backup': {
|
|
2667
|
+
if (versionInfo.build < MIN_BUILD_CREATE_BACKUP) {
|
|
2668
|
+
result = { success: false, error: `Backup requires NotePlan build ${MIN_BUILD_CREATE_BACKUP}+. Current: ${versionInfo.build}.`, code: 'ERR_VERSION_GATE' };
|
|
2669
|
+
}
|
|
2670
|
+
else {
|
|
2671
|
+
result = uiTools.createBackup(args);
|
|
2672
|
+
}
|
|
2673
|
+
break;
|
|
2674
|
+
}
|
|
2675
|
+
default: {
|
|
2676
|
+
// Help the LLM recover from common mistakes (camelCase, missing underscore, etc.)
|
|
2677
|
+
const UI_ACTION_ALIASES = {
|
|
2678
|
+
open: 'open_note', opennote: 'open_note', open_notes: 'open_note',
|
|
2679
|
+
opentoday: 'open_today', today: 'open_today',
|
|
2680
|
+
openview: 'open_view', view: 'open_view',
|
|
2681
|
+
runplugin: 'run_plugin', plugin: 'run_plugin',
|
|
2682
|
+
togglesidebar: 'toggle_sidebar', sidebar: 'toggle_sidebar',
|
|
2683
|
+
closepluginwindow: 'close_plugin_window',
|
|
2684
|
+
listpluginwindows: 'list_plugin_windows',
|
|
2685
|
+
navigate: 'open_note', show: 'open_note', select: 'open_note',
|
|
2686
|
+
};
|
|
2687
|
+
const normalized = (action || '').toLowerCase().replace(/[\s_-]/g, '');
|
|
2688
|
+
const resolved = UI_ACTION_ALIASES[normalized];
|
|
2689
|
+
if (resolved) {
|
|
2690
|
+
args.action = resolved;
|
|
2691
|
+
// Re-dispatch with corrected action
|
|
2692
|
+
switch (resolved) {
|
|
2693
|
+
case 'open_note':
|
|
2694
|
+
result = uiTools.openNote(args);
|
|
2695
|
+
break;
|
|
2696
|
+
case 'open_today':
|
|
2697
|
+
result = uiTools.openToday(args);
|
|
2698
|
+
break;
|
|
2699
|
+
case 'search':
|
|
2700
|
+
result = uiTools.searchNotes(args);
|
|
2701
|
+
break;
|
|
2702
|
+
case 'run_plugin':
|
|
2703
|
+
result = uiTools.runPlugin(args);
|
|
2704
|
+
break;
|
|
2705
|
+
case 'open_view':
|
|
2706
|
+
result = uiTools.openView(args);
|
|
2707
|
+
break;
|
|
2708
|
+
case 'toggle_sidebar':
|
|
2709
|
+
result = uiTools.toggleSidebar(args);
|
|
2710
|
+
break;
|
|
2711
|
+
case 'close_plugin_window':
|
|
2712
|
+
result = uiTools.closePluginWindow(args);
|
|
2713
|
+
break;
|
|
2714
|
+
case 'list_plugin_windows':
|
|
2715
|
+
result = uiTools.listPluginWindows(args);
|
|
2716
|
+
break;
|
|
2717
|
+
case 'backup':
|
|
2718
|
+
result = uiTools.createBackup(args);
|
|
2719
|
+
break;
|
|
2720
|
+
default: throw new Error(`Unknown action: ${action}. Valid actions: open_note, open_today, search, run_plugin, open_view, toggle_sidebar, close_plugin_window, list_plugin_windows, backup`);
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
else {
|
|
2724
|
+
throw new Error(`Unknown action: "${action}". Valid actions: open_note, open_today, search, run_plugin, open_view, toggle_sidebar, close_plugin_window, list_plugin_windows, backup`);
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2350
2727
|
}
|
|
2351
2728
|
break;
|
|
2352
2729
|
}
|
|
@@ -2422,6 +2799,44 @@ export function createServer() {
|
|
|
2422
2799
|
}
|
|
2423
2800
|
break;
|
|
2424
2801
|
}
|
|
2802
|
+
case 'noteplan_templates': {
|
|
2803
|
+
const action = args?.action;
|
|
2804
|
+
switch (action) {
|
|
2805
|
+
case 'list':
|
|
2806
|
+
result = templateTools.listTemplates(args);
|
|
2807
|
+
break;
|
|
2808
|
+
case 'render':
|
|
2809
|
+
result = templateTools.renderTemplate(args);
|
|
2810
|
+
break;
|
|
2811
|
+
case 'search_docs':
|
|
2812
|
+
result = await templateTools.searchDocs(args);
|
|
2813
|
+
break;
|
|
2814
|
+
case 'get_doc':
|
|
2815
|
+
result = templateTools.getDoc(args);
|
|
2816
|
+
break;
|
|
2817
|
+
default: throw new Error(`Unknown action: ${action}`);
|
|
2818
|
+
}
|
|
2819
|
+
break;
|
|
2820
|
+
}
|
|
2821
|
+
case 'noteplan_attachments': {
|
|
2822
|
+
const action = args?.action;
|
|
2823
|
+
switch (action) {
|
|
2824
|
+
case 'add':
|
|
2825
|
+
result = attachmentTools.addAttachment(args);
|
|
2826
|
+
break;
|
|
2827
|
+
case 'list':
|
|
2828
|
+
result = attachmentTools.listAttachments(args);
|
|
2829
|
+
break;
|
|
2830
|
+
case 'get':
|
|
2831
|
+
result = attachmentTools.getAttachment(args);
|
|
2832
|
+
break;
|
|
2833
|
+
case 'move':
|
|
2834
|
+
result = attachmentTools.moveAttachment(args);
|
|
2835
|
+
break;
|
|
2836
|
+
default: throw new Error(`Unknown action: ${action}. Valid actions: add, list, get, move`);
|
|
2837
|
+
}
|
|
2838
|
+
break;
|
|
2839
|
+
}
|
|
2425
2840
|
default:
|
|
2426
2841
|
throw new Error(`Unknown tool: ${name} (normalized: ${normalizedName})`);
|
|
2427
2842
|
}
|
|
@@ -2462,7 +2877,12 @@ export function createServer() {
|
|
|
2462
2877
|
};
|
|
2463
2878
|
}
|
|
2464
2879
|
catch (error) {
|
|
2465
|
-
|
|
2880
|
+
let errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
2881
|
+
// Append list_actions hint for unknown action errors
|
|
2882
|
+
if (errorMessage.includes('Unknown action') && TOOL_ACTIONS[normalizedName]) {
|
|
2883
|
+
const validActions = TOOL_ACTIONS[normalizedName].map(a => a.action).join(', ');
|
|
2884
|
+
errorMessage += `. Valid actions: ${validActions}. Tip: use action "list_actions" to discover all actions with descriptions.`;
|
|
2885
|
+
}
|
|
2466
2886
|
const meta = inferToolErrorMeta(normalizedName, errorMessage, registeredToolNames);
|
|
2467
2887
|
const errorResult = {
|
|
2468
2888
|
success: false,
|