remnote-mcp-server 0.15.0 → 0.16.0
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/CHANGELOG.md +34 -0
- package/README.md +11 -9
- package/dist/index.js +2 -7
- package/dist/index.js.map +1 -1
- package/dist/remnote-cli/cli.js +5 -2
- package/dist/remnote-cli/cli.js.map +1 -1
- package/dist/remnote-cli/client/mcp-server-client.d.ts +1 -0
- package/dist/remnote-cli/client/mcp-server-client.js +7 -4
- package/dist/remnote-cli/client/mcp-server-client.js.map +1 -1
- package/dist/remnote-cli/commands/create.js +3 -0
- package/dist/remnote-cli/commands/create.js.map +1 -1
- package/dist/remnote-cli/commands/read.js +17 -3
- package/dist/remnote-cli/commands/read.js.map +1 -1
- package/dist/remnote-cli/commands/search.d.ts +1 -0
- package/dist/remnote-cli/commands/search.js +88 -7
- package/dist/remnote-cli/commands/search.js.map +1 -1
- package/dist/remnote-cli/commands/write-actions.d.ts +2 -0
- package/dist/remnote-cli/commands/write-actions.js +106 -0
- package/dist/remnote-cli/commands/write-actions.js.map +1 -1
- package/dist/schemas/remnote-schemas.d.ts +73 -9
- package/dist/schemas/remnote-schemas.js +125 -48
- package/dist/schemas/remnote-schemas.js.map +1 -1
- package/dist/shutdown.d.ts +15 -0
- package/dist/shutdown.js +59 -0
- package/dist/shutdown.js.map +1 -0
- package/dist/tools/index.d.ts +2915 -618
- package/dist/tools/index.js +442 -23
- package/dist/tools/index.js.map +1 -1
- package/dist/websocket-server.d.ts +2 -1
- package/dist/websocket-server.js +6 -2
- package/dist/websocket-server.js.map +1 -1
- package/mcpb/remnote-local/manifest.json +16 -4
- package/mcpb/remnote-local/package.json +1 -1
- package/mcpb/remnote-local/remnote-local.mcpb +0 -0
- package/mcpb/remnote-local/server/fallback-tools.generated.js +160 -6
- package/mcpb/remnote-local/server/index.js +4 -2
- package/package.json +1 -1
package/dist/tools/index.js
CHANGED
|
@@ -4,6 +4,9 @@ import { SearchSchema } from '../schemas/remnote-schemas.js';
|
|
|
4
4
|
import { SearchByTagSchema } from '../schemas/remnote-schemas.js';
|
|
5
5
|
import { ReadNoteSchema } from '../schemas/remnote-schemas.js';
|
|
6
6
|
import { UpdateNoteSchema } from '../schemas/remnote-schemas.js';
|
|
7
|
+
import { SetDocumentStatusSchema } from '../schemas/remnote-schemas.js';
|
|
8
|
+
import { ListChildrenSchema } from '../schemas/remnote-schemas.js';
|
|
9
|
+
import { MoveNoteSchema } from '../schemas/remnote-schemas.js';
|
|
7
10
|
import { InsertChildrenSchema } from '../schemas/remnote-schemas.js';
|
|
8
11
|
import { ReplaceChildrenSchema } from '../schemas/remnote-schemas.js';
|
|
9
12
|
import { UpdateTagsSchema } from '../schemas/remnote-schemas.js';
|
|
@@ -11,10 +14,24 @@ import { AppendJournalSchema } from '../schemas/remnote-schemas.js';
|
|
|
11
14
|
import { ReadTableSchema } from '../schemas/remnote-schemas.js';
|
|
12
15
|
import { checkVersionCompatibility } from '../version-compat.js';
|
|
13
16
|
const NAVIGATION_PRESET = {
|
|
14
|
-
|
|
17
|
+
contentMode: 'structured',
|
|
18
|
+
view: 'compact',
|
|
15
19
|
depth: 1,
|
|
16
20
|
childLimit: 500,
|
|
17
21
|
};
|
|
22
|
+
const ANCESTOR_SCHEMA = {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
remId: { type: 'string', description: 'Ancestor Rem ID' },
|
|
26
|
+
title: { type: 'string', description: 'Rendered ancestor title' },
|
|
27
|
+
remType: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
description: 'Ancestor Rem classification when available',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
required: ['remId', 'title'],
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
};
|
|
18
35
|
const TAG_INFO_SCHEMA = {
|
|
19
36
|
type: 'object',
|
|
20
37
|
properties: {
|
|
@@ -24,6 +41,57 @@ const TAG_INFO_SCHEMA = {
|
|
|
24
41
|
required: ['tagRemId', 'name'],
|
|
25
42
|
additionalProperties: false,
|
|
26
43
|
};
|
|
44
|
+
const INLINE_REF_SCHEMA = {
|
|
45
|
+
type: 'object',
|
|
46
|
+
properties: {
|
|
47
|
+
text: { type: 'string', description: 'Rendered target text used in output' },
|
|
48
|
+
targetRemId: { type: 'string', description: 'Exact target Rem ID' },
|
|
49
|
+
kind: { type: 'string', enum: ['rem'], description: 'Inline reference kind' },
|
|
50
|
+
},
|
|
51
|
+
required: ['text', 'targetRemId', 'kind'],
|
|
52
|
+
additionalProperties: false,
|
|
53
|
+
};
|
|
54
|
+
const MATCHED_REM_SCHEMA = {
|
|
55
|
+
type: 'object',
|
|
56
|
+
properties: {
|
|
57
|
+
remId: { type: 'string', description: 'Directly tagged Rem ID' },
|
|
58
|
+
title: { type: 'string', description: 'Rendered title with markdown formatting' },
|
|
59
|
+
headline: { type: 'string', description: 'Display-oriented full line' },
|
|
60
|
+
inlineRefs: {
|
|
61
|
+
type: 'array',
|
|
62
|
+
items: INLINE_REF_SCHEMA,
|
|
63
|
+
description: 'Resolvable inline Rem references from the matched Rem title/headline',
|
|
64
|
+
},
|
|
65
|
+
remType: {
|
|
66
|
+
type: 'string',
|
|
67
|
+
description: 'Rem classification: document, dailyDocument, concept, descriptor, portal, or text',
|
|
68
|
+
},
|
|
69
|
+
parentRemId: {
|
|
70
|
+
type: 'string',
|
|
71
|
+
description: 'Direct parent Rem ID (omitted for top-level Rems)',
|
|
72
|
+
},
|
|
73
|
+
parentTitle: {
|
|
74
|
+
type: 'string',
|
|
75
|
+
description: 'Direct parent title/front text (omitted for top-level Rems)',
|
|
76
|
+
},
|
|
77
|
+
ancestors: {
|
|
78
|
+
type: 'array',
|
|
79
|
+
items: ANCESTOR_SCHEMA,
|
|
80
|
+
description: 'Parent-first ancestor chain when ancestorDepth is greater than zero',
|
|
81
|
+
},
|
|
82
|
+
ancestorsTruncated: {
|
|
83
|
+
type: 'boolean',
|
|
84
|
+
description: 'Whether the ancestor chain was capped by ancestorDepth',
|
|
85
|
+
},
|
|
86
|
+
tags: {
|
|
87
|
+
type: 'array',
|
|
88
|
+
items: TAG_INFO_SCHEMA,
|
|
89
|
+
description: 'Direct tags applied to the matched Rem as exact tag Rem IDs plus names',
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
required: ['remId', 'title', 'headline', 'remType'],
|
|
93
|
+
additionalProperties: false,
|
|
94
|
+
};
|
|
27
95
|
export const CREATE_NOTE_TOOL = {
|
|
28
96
|
name: 'remnote_create_note',
|
|
29
97
|
description: 'Create a new note in RemNote with optional content, parent, and exact tag Rem IDs. Supports hierarchical markdown in content and flashcard syntax (e.g. "- Term :: Definition"). At least one of title or content must be provided. Recommended preflight once per session: remnote_status.',
|
|
@@ -44,6 +112,10 @@ export const CREATE_NOTE_TOOL = {
|
|
|
44
112
|
items: { type: 'string' },
|
|
45
113
|
description: 'Exact tag Rem IDs to apply',
|
|
46
114
|
},
|
|
115
|
+
asDocument: {
|
|
116
|
+
type: 'boolean',
|
|
117
|
+
description: 'Mark the created title/root Rem as a document while preserving any concept/card status',
|
|
118
|
+
},
|
|
47
119
|
},
|
|
48
120
|
required: [],
|
|
49
121
|
additionalProperties: false,
|
|
@@ -67,17 +139,30 @@ export const CREATE_NOTE_TOOL = {
|
|
|
67
139
|
};
|
|
68
140
|
export const SEARCH_TOOL = {
|
|
69
141
|
name: 'remnote_search',
|
|
70
|
-
description: 'Search the RemNote knowledge base. For whole-KB orientation, prefer
|
|
142
|
+
description: 'Search the RemNote knowledge base. Supports cursor paging through hasMore/nextCursor. For whole-KB orientation, prefer contentMode="structured" with view="compact", depth=1, and childLimit=500. Request ancestorDepth when hierarchy context matters.',
|
|
71
143
|
inputSchema: {
|
|
72
144
|
type: 'object',
|
|
73
145
|
properties: {
|
|
74
146
|
query: { type: 'string', description: 'Search query text' },
|
|
75
147
|
limit: { type: 'number', description: 'Maximum results (1-150, default: 50)' },
|
|
76
|
-
|
|
148
|
+
cursor: {
|
|
149
|
+
type: 'string',
|
|
150
|
+
description: 'Opaque cursor returned by a previous remnote_search response',
|
|
151
|
+
},
|
|
152
|
+
contentMode: {
|
|
77
153
|
type: 'string',
|
|
78
154
|
enum: ['none', 'markdown', 'structured'],
|
|
79
155
|
description: 'Content rendering mode: "none" omits content (default), "markdown" renders child subtree as indented markdown, "structured" returns nested child objects with remIds',
|
|
80
156
|
},
|
|
157
|
+
view: {
|
|
158
|
+
type: 'string',
|
|
159
|
+
enum: ['compact', 'standard', 'full'],
|
|
160
|
+
description: 'Output detail level: compact, standard, or full',
|
|
161
|
+
},
|
|
162
|
+
ancestorDepth: {
|
|
163
|
+
type: 'number',
|
|
164
|
+
description: 'Number of parent Rems to include, direct parent first (0-20, default: 0)',
|
|
165
|
+
},
|
|
81
166
|
depth: {
|
|
82
167
|
type: 'number',
|
|
83
168
|
description: 'Depth of child hierarchy to render for markdown/structured content (0-10, default: 1)',
|
|
@@ -108,6 +193,11 @@ export const SEARCH_TOOL = {
|
|
|
108
193
|
type: 'string',
|
|
109
194
|
description: 'Display-oriented full line: title + type-aware delimiter + detail (e.g. "Term :: Definition")',
|
|
110
195
|
},
|
|
196
|
+
inlineRefs: {
|
|
197
|
+
type: 'array',
|
|
198
|
+
items: INLINE_REF_SCHEMA,
|
|
199
|
+
description: 'Resolvable inline Rem references from the rendered title/headline. Markdown text preserves these as [[Target Title]].',
|
|
200
|
+
},
|
|
111
201
|
parentRemId: {
|
|
112
202
|
type: 'string',
|
|
113
203
|
description: 'Direct parent Rem ID (omitted for top-level Rems)',
|
|
@@ -116,6 +206,15 @@ export const SEARCH_TOOL = {
|
|
|
116
206
|
type: 'string',
|
|
117
207
|
description: 'Direct parent title/front text (omitted for top-level Rems)',
|
|
118
208
|
},
|
|
209
|
+
ancestors: {
|
|
210
|
+
type: 'array',
|
|
211
|
+
items: ANCESTOR_SCHEMA,
|
|
212
|
+
description: 'Parent-first ancestor chain when ancestorDepth is greater than zero',
|
|
213
|
+
},
|
|
214
|
+
ancestorsTruncated: {
|
|
215
|
+
type: 'boolean',
|
|
216
|
+
description: 'Whether the ancestor chain was capped by ancestorDepth',
|
|
217
|
+
},
|
|
119
218
|
aliases: {
|
|
120
219
|
type: 'array',
|
|
121
220
|
items: { type: 'string' },
|
|
@@ -130,17 +229,35 @@ export const SEARCH_TOOL = {
|
|
|
130
229
|
type: 'string',
|
|
131
230
|
description: 'Rem classification: document, dailyDocument, concept, descriptor, portal, or text',
|
|
132
231
|
},
|
|
232
|
+
matchedRems: {
|
|
233
|
+
type: 'array',
|
|
234
|
+
items: MATCHED_REM_SCHEMA,
|
|
235
|
+
description: 'For remnote_search_by_tag context mode, direct Rems carrying the requested tag that produced this context result',
|
|
236
|
+
},
|
|
237
|
+
contextRemId: {
|
|
238
|
+
type: 'string',
|
|
239
|
+
description: 'For remnote_search_by_tag tagged mode, resolved ancestor/context Rem ID for this direct match',
|
|
240
|
+
},
|
|
241
|
+
contextTitle: {
|
|
242
|
+
type: 'string',
|
|
243
|
+
description: 'For remnote_search_by_tag tagged mode, resolved ancestor/context title for this direct match',
|
|
244
|
+
},
|
|
245
|
+
contextReason: {
|
|
246
|
+
type: 'string',
|
|
247
|
+
enum: ['ancestor-document', 'ancestor-concept', 'ancestor-context', 'self'],
|
|
248
|
+
description: 'For remnote_search_by_tag tagged mode, why the context Rem was selected',
|
|
249
|
+
},
|
|
133
250
|
cardDirection: {
|
|
134
251
|
type: 'string',
|
|
135
252
|
description: 'Flashcard direction: forward, reverse, or bidirectional (omitted if not a flashcard)',
|
|
136
253
|
},
|
|
137
254
|
content: {
|
|
138
255
|
type: 'string',
|
|
139
|
-
description: 'Rendered markdown content of child subtree (only when
|
|
256
|
+
description: 'Rendered markdown content of child subtree (only when contentMode="markdown")',
|
|
140
257
|
},
|
|
141
258
|
contentStructured: {
|
|
142
259
|
type: 'array',
|
|
143
|
-
description: 'Structured child subtree with nested remIds and metadata (only when
|
|
260
|
+
description: 'Structured child subtree with nested remIds and metadata (only when contentMode="structured")',
|
|
144
261
|
items: {
|
|
145
262
|
type: 'object',
|
|
146
263
|
properties: {
|
|
@@ -150,6 +267,11 @@ export const SEARCH_TOOL = {
|
|
|
150
267
|
type: 'string',
|
|
151
268
|
description: 'Display-oriented child line with type-aware delimiter',
|
|
152
269
|
},
|
|
270
|
+
inlineRefs: {
|
|
271
|
+
type: 'array',
|
|
272
|
+
items: INLINE_REF_SCHEMA,
|
|
273
|
+
description: 'Resolvable inline Rem references from the child title/headline',
|
|
274
|
+
},
|
|
153
275
|
aliases: {
|
|
154
276
|
type: 'array',
|
|
155
277
|
items: { type: 'string' },
|
|
@@ -198,12 +320,29 @@ export const SEARCH_TOOL = {
|
|
|
198
320
|
},
|
|
199
321
|
},
|
|
200
322
|
},
|
|
323
|
+
hasMore: {
|
|
324
|
+
type: 'boolean',
|
|
325
|
+
description: 'Whether more results are available through nextCursor',
|
|
326
|
+
},
|
|
327
|
+
nextCursor: {
|
|
328
|
+
type: 'string',
|
|
329
|
+
description: 'Opaque cursor for the next page when hasMore is true',
|
|
330
|
+
},
|
|
331
|
+
truncated: {
|
|
332
|
+
type: 'boolean',
|
|
333
|
+
description: 'Whether search results may be incomplete because the bridge hit its snapshot cap',
|
|
334
|
+
},
|
|
335
|
+
truncationReason: {
|
|
336
|
+
type: 'string',
|
|
337
|
+
enum: ['cursor_snapshot_limit'],
|
|
338
|
+
description: 'Reason search results may be incomplete when truncated is true',
|
|
339
|
+
},
|
|
201
340
|
},
|
|
202
341
|
},
|
|
203
342
|
};
|
|
204
343
|
export const SEARCH_BY_TAG_TOOL = {
|
|
205
344
|
name: 'remnote_search_by_tag',
|
|
206
|
-
description: 'Find notes by exact tag Rem ID
|
|
345
|
+
description: 'Find notes by exact tag Rem ID. Supports cursor paging through hasMore/nextCursor. Default resultMode="context" returns resolved ancestor context targets with matchedRems; resultMode="tagged" returns directly tagged Rems with context metadata. Request ancestorDepth to include parent-first ancestors on both context results and matchedRems.',
|
|
207
346
|
inputSchema: {
|
|
208
347
|
type: 'object',
|
|
209
348
|
properties: {
|
|
@@ -211,12 +350,26 @@ export const SEARCH_BY_TAG_TOOL = {
|
|
|
211
350
|
type: 'string',
|
|
212
351
|
description: 'Exact tag Rem ID to search',
|
|
213
352
|
},
|
|
353
|
+
resultMode: {
|
|
354
|
+
type: 'string',
|
|
355
|
+
enum: ['context', 'tagged'],
|
|
356
|
+
description: '"context" returns resolved ancestor context targets with matchedRems (default); "tagged" returns directly tagged Rems with context metadata',
|
|
357
|
+
},
|
|
214
358
|
limit: { type: 'number', description: 'Maximum results (1-150, default: 50)' },
|
|
215
|
-
|
|
359
|
+
contentMode: {
|
|
216
360
|
type: 'string',
|
|
217
361
|
enum: ['none', 'markdown', 'structured'],
|
|
218
362
|
description: 'Content rendering mode: "none" omits content (default), "markdown" renders child subtree as indented markdown, "structured" returns nested child objects with remIds',
|
|
219
363
|
},
|
|
364
|
+
view: {
|
|
365
|
+
type: 'string',
|
|
366
|
+
enum: ['compact', 'standard', 'full'],
|
|
367
|
+
description: 'Output detail level: compact, standard, or full',
|
|
368
|
+
},
|
|
369
|
+
ancestorDepth: {
|
|
370
|
+
type: 'number',
|
|
371
|
+
description: 'Number of parent Rems to include, direct parent first (0-20, default: 0)',
|
|
372
|
+
},
|
|
220
373
|
depth: {
|
|
221
374
|
type: 'number',
|
|
222
375
|
description: 'Depth of child hierarchy to render for markdown/structured content (0-10, default: 1)',
|
|
@@ -229,14 +382,31 @@ export const SEARCH_BY_TAG_TOOL = {
|
|
|
229
382
|
type: 'number',
|
|
230
383
|
description: 'Maximum character length for rendered content (default: 3000)',
|
|
231
384
|
},
|
|
385
|
+
cursor: {
|
|
386
|
+
type: 'string',
|
|
387
|
+
description: 'Opaque cursor returned by a previous remnote_search_by_tag response',
|
|
388
|
+
},
|
|
389
|
+
timeoutMs: {
|
|
390
|
+
type: 'number',
|
|
391
|
+
description: 'Per-call bridge wait timeout in milliseconds (1-60000, default: 15000). Does not cancel plugin-side work.',
|
|
392
|
+
},
|
|
232
393
|
},
|
|
233
394
|
required: ['tagRemId'],
|
|
234
395
|
},
|
|
235
|
-
outputSchema:
|
|
396
|
+
outputSchema: {
|
|
397
|
+
type: 'object',
|
|
398
|
+
properties: {
|
|
399
|
+
results: SEARCH_TOOL.outputSchema.properties.results,
|
|
400
|
+
hasMore: SEARCH_TOOL.outputSchema.properties.hasMore,
|
|
401
|
+
nextCursor: SEARCH_TOOL.outputSchema.properties.nextCursor,
|
|
402
|
+
truncated: SEARCH_TOOL.outputSchema.properties.truncated,
|
|
403
|
+
truncationReason: SEARCH_TOOL.outputSchema.properties.truncationReason,
|
|
404
|
+
},
|
|
405
|
+
},
|
|
236
406
|
};
|
|
237
407
|
export const READ_NOTE_TOOL = {
|
|
238
408
|
name: 'remnote_read_note',
|
|
239
|
-
description: 'Read a specific note from RemNote by its Rem ID. For hierarchy traversal, prefer
|
|
409
|
+
description: 'Read a specific note from RemNote by its Rem ID. For hierarchy traversal, prefer contentMode="structured" and start shallow (depth=1, childLimit=500), then deepen only selected branches. Request ancestorDepth when placement context matters.',
|
|
240
410
|
inputSchema: {
|
|
241
411
|
type: 'object',
|
|
242
412
|
properties: {
|
|
@@ -245,11 +415,20 @@ export const READ_NOTE_TOOL = {
|
|
|
245
415
|
type: 'number',
|
|
246
416
|
description: 'Depth of child hierarchy to render (0-10, default: 5)',
|
|
247
417
|
},
|
|
248
|
-
|
|
418
|
+
contentMode: {
|
|
249
419
|
type: 'string',
|
|
250
420
|
enum: ['none', 'markdown', 'structured'],
|
|
251
421
|
description: 'Content rendering mode: "markdown" renders child subtree (default), "structured" returns nested child objects with remIds, "none" omits content',
|
|
252
422
|
},
|
|
423
|
+
view: {
|
|
424
|
+
type: 'string',
|
|
425
|
+
enum: ['compact', 'standard', 'full'],
|
|
426
|
+
description: 'Output detail level: compact, standard, or full',
|
|
427
|
+
},
|
|
428
|
+
ancestorDepth: {
|
|
429
|
+
type: 'number',
|
|
430
|
+
description: 'Number of parent Rems to include, direct parent first (0-20, default: 0)',
|
|
431
|
+
},
|
|
253
432
|
childLimit: {
|
|
254
433
|
type: 'number',
|
|
255
434
|
description: 'Maximum children per level (1-500, default: 100)',
|
|
@@ -270,6 +449,11 @@ export const READ_NOTE_TOOL = {
|
|
|
270
449
|
type: 'string',
|
|
271
450
|
description: 'Display-oriented full line: title + type-aware delimiter + detail (e.g. "Term :: Definition")',
|
|
272
451
|
},
|
|
452
|
+
inlineRefs: {
|
|
453
|
+
type: 'array',
|
|
454
|
+
items: INLINE_REF_SCHEMA,
|
|
455
|
+
description: 'Resolvable inline Rem references from the rendered title/headline. Markdown text preserves these as [[Target Title]].',
|
|
456
|
+
},
|
|
273
457
|
parentRemId: {
|
|
274
458
|
type: 'string',
|
|
275
459
|
description: 'Direct parent Rem ID (omitted for top-level Rems)',
|
|
@@ -278,6 +462,15 @@ export const READ_NOTE_TOOL = {
|
|
|
278
462
|
type: 'string',
|
|
279
463
|
description: 'Direct parent title/front text (omitted for top-level Rems)',
|
|
280
464
|
},
|
|
465
|
+
ancestors: {
|
|
466
|
+
type: 'array',
|
|
467
|
+
items: ANCESTOR_SCHEMA,
|
|
468
|
+
description: 'Parent-first ancestor chain when ancestorDepth is greater than zero',
|
|
469
|
+
},
|
|
470
|
+
ancestorsTruncated: {
|
|
471
|
+
type: 'boolean',
|
|
472
|
+
description: 'Whether the ancestor chain was capped by ancestorDepth',
|
|
473
|
+
},
|
|
281
474
|
aliases: {
|
|
282
475
|
type: 'array',
|
|
283
476
|
items: { type: 'string' },
|
|
@@ -298,11 +491,11 @@ export const READ_NOTE_TOOL = {
|
|
|
298
491
|
},
|
|
299
492
|
content: {
|
|
300
493
|
type: 'string',
|
|
301
|
-
description: 'Rendered markdown content of child subtree (when
|
|
494
|
+
description: 'Rendered markdown content of child subtree (when contentMode="markdown", which is the default)',
|
|
302
495
|
},
|
|
303
496
|
contentStructured: {
|
|
304
497
|
type: 'array',
|
|
305
|
-
description: 'Structured child subtree with nested remIds and metadata (only when
|
|
498
|
+
description: 'Structured child subtree with nested remIds and metadata (only when contentMode="structured")',
|
|
306
499
|
items: {
|
|
307
500
|
type: 'object',
|
|
308
501
|
properties: {
|
|
@@ -312,6 +505,11 @@ export const READ_NOTE_TOOL = {
|
|
|
312
505
|
type: 'string',
|
|
313
506
|
description: 'Display-oriented child line with type-aware delimiter',
|
|
314
507
|
},
|
|
508
|
+
inlineRefs: {
|
|
509
|
+
type: 'array',
|
|
510
|
+
items: INLINE_REF_SCHEMA,
|
|
511
|
+
description: 'Resolvable inline Rem references from the child title/headline',
|
|
512
|
+
},
|
|
315
513
|
aliases: {
|
|
316
514
|
type: 'array',
|
|
317
515
|
items: { type: 'string' },
|
|
@@ -360,6 +558,98 @@ export const READ_NOTE_TOOL = {
|
|
|
360
558
|
},
|
|
361
559
|
},
|
|
362
560
|
};
|
|
561
|
+
export const LIST_CHILDREN_TOOL = {
|
|
562
|
+
name: 'remnote_list_children',
|
|
563
|
+
description: 'List direct child Rems under a parent without rendering a subtree. Use for cheap hierarchy traversal; page with nextCursor when hasMore is true.',
|
|
564
|
+
inputSchema: {
|
|
565
|
+
type: 'object',
|
|
566
|
+
properties: {
|
|
567
|
+
parentRemId: { type: 'string', description: 'Parent Rem ID whose direct children to list' },
|
|
568
|
+
limit: { type: 'number', description: 'Maximum direct children (1-150, default: 50)' },
|
|
569
|
+
cursor: {
|
|
570
|
+
type: 'string',
|
|
571
|
+
description: 'Opaque cursor returned by a previous remnote_list_children response',
|
|
572
|
+
},
|
|
573
|
+
view: {
|
|
574
|
+
type: 'string',
|
|
575
|
+
enum: ['compact', 'standard', 'full'],
|
|
576
|
+
description: 'Output detail level for child metadata: compact, standard, or full',
|
|
577
|
+
},
|
|
578
|
+
ancestorDepth: {
|
|
579
|
+
type: 'number',
|
|
580
|
+
description: 'Number of parent Rems to include for each child, direct parent first',
|
|
581
|
+
},
|
|
582
|
+
},
|
|
583
|
+
required: ['parentRemId'],
|
|
584
|
+
},
|
|
585
|
+
outputSchema: {
|
|
586
|
+
type: 'object',
|
|
587
|
+
properties: {
|
|
588
|
+
children: {
|
|
589
|
+
type: 'array',
|
|
590
|
+
items: SEARCH_TOOL.outputSchema.properties.results.items,
|
|
591
|
+
},
|
|
592
|
+
hasMore: SEARCH_TOOL.outputSchema.properties.hasMore,
|
|
593
|
+
nextCursor: SEARCH_TOOL.outputSchema.properties.nextCursor,
|
|
594
|
+
totalChildren: {
|
|
595
|
+
type: 'number',
|
|
596
|
+
description: 'Total direct children observed when listing this parent',
|
|
597
|
+
},
|
|
598
|
+
},
|
|
599
|
+
},
|
|
600
|
+
};
|
|
601
|
+
export const MOVE_NOTE_TOOL = {
|
|
602
|
+
name: 'remnote_move_note',
|
|
603
|
+
description: 'Safely move an existing Rem and its subtree under a new parent. Defaults to dryRun=true; pass dryRun=false only after user approval. expectedOldParentRemId rejects stale move proposals.',
|
|
604
|
+
inputSchema: {
|
|
605
|
+
type: 'object',
|
|
606
|
+
properties: {
|
|
607
|
+
remId: { type: 'string', description: 'Rem ID to move' },
|
|
608
|
+
newParentRemId: { type: 'string', description: 'New parent Rem ID' },
|
|
609
|
+
position: {
|
|
610
|
+
type: 'string',
|
|
611
|
+
enum: ['first', 'last', 'before', 'after'],
|
|
612
|
+
description: 'Where to place the moved Rem under the new parent (default: last)',
|
|
613
|
+
},
|
|
614
|
+
siblingRemId: {
|
|
615
|
+
type: 'string',
|
|
616
|
+
description: 'Sibling Rem ID required for before/after positioning',
|
|
617
|
+
},
|
|
618
|
+
dryRun: {
|
|
619
|
+
type: 'boolean',
|
|
620
|
+
description: 'Preview without mutating RemNote (default: true)',
|
|
621
|
+
},
|
|
622
|
+
expectedOldParentRemId: {
|
|
623
|
+
type: 'string',
|
|
624
|
+
description: 'Reject if the current direct parent differs from this Rem ID',
|
|
625
|
+
},
|
|
626
|
+
ancestorDepth: {
|
|
627
|
+
type: 'number',
|
|
628
|
+
description: 'Number of parent Rems to include before/after the move',
|
|
629
|
+
},
|
|
630
|
+
},
|
|
631
|
+
required: ['remId', 'newParentRemId'],
|
|
632
|
+
},
|
|
633
|
+
outputSchema: {
|
|
634
|
+
type: 'object',
|
|
635
|
+
properties: {
|
|
636
|
+
remId: { type: 'string' },
|
|
637
|
+
title: { type: 'string' },
|
|
638
|
+
dryRun: { type: 'boolean' },
|
|
639
|
+
oldParentRemId: { type: 'string' },
|
|
640
|
+
oldParentTitle: { type: 'string' },
|
|
641
|
+
newParentRemId: { type: 'string' },
|
|
642
|
+
newParentTitle: { type: 'string' },
|
|
643
|
+
position: { type: 'string', enum: ['first', 'last', 'before', 'after'] },
|
|
644
|
+
siblingRemId: { type: 'string' },
|
|
645
|
+
ancestorsBefore: { type: 'array', items: ANCESTOR_SCHEMA },
|
|
646
|
+
ancestorsBeforeTruncated: { type: 'boolean' },
|
|
647
|
+
ancestorsAfter: { type: 'array', items: ANCESTOR_SCHEMA },
|
|
648
|
+
ancestorsAfterTruncated: { type: 'boolean' },
|
|
649
|
+
},
|
|
650
|
+
required: ['remId', 'title', 'dryRun', 'newParentRemId', 'newParentTitle', 'position'],
|
|
651
|
+
},
|
|
652
|
+
};
|
|
363
653
|
export const UPDATE_NOTE_TOOL = {
|
|
364
654
|
name: 'remnote_update_note',
|
|
365
655
|
description: 'Update note metadata in RemNote. Use this tool for title changes only.',
|
|
@@ -389,6 +679,100 @@ export const UPDATE_NOTE_TOOL = {
|
|
|
389
679
|
required: ['remIds', 'titles'],
|
|
390
680
|
},
|
|
391
681
|
};
|
|
682
|
+
export const SET_DOCUMENT_STATUS_TOOL = {
|
|
683
|
+
name: 'remnote_set_document_status',
|
|
684
|
+
description: 'Preview or set whether an existing Rem is marked as a document. Uses dryRun=true by default, preserves Rem ID, children, parent, tags, and concept/card status, and requires write operations to be enabled.',
|
|
685
|
+
inputSchema: {
|
|
686
|
+
type: 'object',
|
|
687
|
+
properties: {
|
|
688
|
+
remId: { type: 'string', description: 'The Rem ID whose document status should change' },
|
|
689
|
+
isDocument: {
|
|
690
|
+
type: 'boolean',
|
|
691
|
+
description: 'Whether the Rem should be marked as a document',
|
|
692
|
+
},
|
|
693
|
+
dryRun: {
|
|
694
|
+
type: 'boolean',
|
|
695
|
+
description: 'Preview the document-status change without mutating RemNote (default: true)',
|
|
696
|
+
},
|
|
697
|
+
expectedOldRemType: {
|
|
698
|
+
type: 'string',
|
|
699
|
+
enum: ['document', 'dailyDocument', 'concept', 'descriptor', 'portal', 'text'],
|
|
700
|
+
description: 'Optional stale-context guard; reject if current remType differs from this value',
|
|
701
|
+
},
|
|
702
|
+
},
|
|
703
|
+
required: ['remId', 'isDocument'],
|
|
704
|
+
additionalProperties: false,
|
|
705
|
+
},
|
|
706
|
+
outputSchema: {
|
|
707
|
+
type: 'object',
|
|
708
|
+
properties: {
|
|
709
|
+
remId: { type: 'string', description: 'The Rem ID that was checked or changed' },
|
|
710
|
+
title: { type: 'string', description: 'Rendered title/front text' },
|
|
711
|
+
oldRemType: {
|
|
712
|
+
type: 'string',
|
|
713
|
+
description: 'Bridge remType before the requested document-status change',
|
|
714
|
+
},
|
|
715
|
+
newRemType: {
|
|
716
|
+
type: 'string',
|
|
717
|
+
description: 'Bridge remType after the change, or previewed remType for dry runs',
|
|
718
|
+
},
|
|
719
|
+
oldIsDocument: {
|
|
720
|
+
type: 'boolean',
|
|
721
|
+
description: 'Document status before the requested change',
|
|
722
|
+
},
|
|
723
|
+
newIsDocument: {
|
|
724
|
+
type: 'boolean',
|
|
725
|
+
description: 'Document status after the change, or previewed status for dry runs',
|
|
726
|
+
},
|
|
727
|
+
requestedIsDocument: {
|
|
728
|
+
type: 'boolean',
|
|
729
|
+
description: 'Requested document status',
|
|
730
|
+
},
|
|
731
|
+
dryRun: {
|
|
732
|
+
type: 'boolean',
|
|
733
|
+
description: 'Whether the request was only a preview',
|
|
734
|
+
},
|
|
735
|
+
changed: {
|
|
736
|
+
type: 'boolean',
|
|
737
|
+
description: 'Whether RemNote was actually mutated by this call',
|
|
738
|
+
},
|
|
739
|
+
wouldChange: {
|
|
740
|
+
type: 'boolean',
|
|
741
|
+
description: 'Whether the requested status differs from the current status',
|
|
742
|
+
},
|
|
743
|
+
sdkSupportsDocumentStatus: {
|
|
744
|
+
type: 'boolean',
|
|
745
|
+
description: 'Whether the bridge runtime exposes a safe SDK document-status setter',
|
|
746
|
+
},
|
|
747
|
+
warnings: {
|
|
748
|
+
type: 'array',
|
|
749
|
+
items: { type: 'string' },
|
|
750
|
+
description: 'Important side-effect notes, especially around preserved card status',
|
|
751
|
+
},
|
|
752
|
+
cardDirectionBefore: {
|
|
753
|
+
type: 'string',
|
|
754
|
+
description: 'Card direction before the change when available',
|
|
755
|
+
},
|
|
756
|
+
cardDirectionAfter: {
|
|
757
|
+
type: 'string',
|
|
758
|
+
description: 'Card direction after the change when available',
|
|
759
|
+
},
|
|
760
|
+
},
|
|
761
|
+
required: [
|
|
762
|
+
'remId',
|
|
763
|
+
'title',
|
|
764
|
+
'oldRemType',
|
|
765
|
+
'newRemType',
|
|
766
|
+
'oldIsDocument',
|
|
767
|
+
'newIsDocument',
|
|
768
|
+
'requestedIsDocument',
|
|
769
|
+
'dryRun',
|
|
770
|
+
'changed',
|
|
771
|
+
'wouldChange',
|
|
772
|
+
'sdkSupportsDocumentStatus',
|
|
773
|
+
],
|
|
774
|
+
},
|
|
775
|
+
};
|
|
392
776
|
export const INSERT_CHILDREN_TOOL = {
|
|
393
777
|
name: 'remnote_insert_children',
|
|
394
778
|
description: 'Insert new child Rems under a parent at a deterministic position without replacing existing children. Use this for tag description nodes and hierarchy maintenance.',
|
|
@@ -634,7 +1018,8 @@ export const PLAYBOOK_TOOL = {
|
|
|
634
1018
|
orientation: {
|
|
635
1019
|
type: 'object',
|
|
636
1020
|
properties: {
|
|
637
|
-
|
|
1021
|
+
contentMode: { type: 'string' },
|
|
1022
|
+
view: { type: 'string' },
|
|
638
1023
|
depth: { type: 'number' },
|
|
639
1024
|
childLimit: { type: 'number' },
|
|
640
1025
|
},
|
|
@@ -670,7 +1055,10 @@ export const ALL_TOOLS = [
|
|
|
670
1055
|
SEARCH_TOOL,
|
|
671
1056
|
SEARCH_BY_TAG_TOOL,
|
|
672
1057
|
READ_NOTE_TOOL,
|
|
1058
|
+
LIST_CHILDREN_TOOL,
|
|
673
1059
|
UPDATE_NOTE_TOOL,
|
|
1060
|
+
SET_DOCUMENT_STATUS_TOOL,
|
|
1061
|
+
MOVE_NOTE_TOOL,
|
|
674
1062
|
INSERT_CHILDREN_TOOL,
|
|
675
1063
|
REPLACE_CHILDREN_TOOL,
|
|
676
1064
|
UPDATE_TAGS_TOOL,
|
|
@@ -724,7 +1112,8 @@ export function registerAllTools(server, wsServer, logger) {
|
|
|
724
1112
|
}
|
|
725
1113
|
case 'remnote_search_by_tag': {
|
|
726
1114
|
const args = SearchByTagSchema.parse(request.params.arguments);
|
|
727
|
-
|
|
1115
|
+
const { timeoutMs, ...payload } = args;
|
|
1116
|
+
result = await wsServer.sendRequest('search_by_tag', payload, timeoutMs);
|
|
728
1117
|
break;
|
|
729
1118
|
}
|
|
730
1119
|
case 'remnote_read_note': {
|
|
@@ -732,16 +1121,31 @@ export function registerAllTools(server, wsServer, logger) {
|
|
|
732
1121
|
result = await wsServer.sendRequest('read_note', args);
|
|
733
1122
|
break;
|
|
734
1123
|
}
|
|
1124
|
+
case 'remnote_list_children': {
|
|
1125
|
+
const args = ListChildrenSchema.parse(request.params.arguments);
|
|
1126
|
+
result = await wsServer.sendRequest('list_children', args);
|
|
1127
|
+
break;
|
|
1128
|
+
}
|
|
735
1129
|
case 'remnote_update_note': {
|
|
736
1130
|
const args = UpdateNoteSchema.parse(request.params.arguments);
|
|
737
1131
|
result = await wsServer.sendRequest('update_note', args);
|
|
738
1132
|
break;
|
|
739
1133
|
}
|
|
1134
|
+
case 'remnote_set_document_status': {
|
|
1135
|
+
const args = SetDocumentStatusSchema.parse(request.params.arguments);
|
|
1136
|
+
result = await wsServer.sendRequest('set_document_status', args);
|
|
1137
|
+
break;
|
|
1138
|
+
}
|
|
740
1139
|
case 'remnote_insert_children': {
|
|
741
1140
|
const args = InsertChildrenSchema.parse(request.params.arguments);
|
|
742
1141
|
result = await wsServer.sendRequest('insert_children', args);
|
|
743
1142
|
break;
|
|
744
1143
|
}
|
|
1144
|
+
case 'remnote_move_note': {
|
|
1145
|
+
const args = MoveNoteSchema.parse(request.params.arguments);
|
|
1146
|
+
result = await wsServer.sendRequest('move_note', args);
|
|
1147
|
+
break;
|
|
1148
|
+
}
|
|
745
1149
|
case 'remnote_replace_children': {
|
|
746
1150
|
const args = ReplaceChildrenSchema.parse(request.params.arguments);
|
|
747
1151
|
result = await wsServer.sendRequest('replace_children', args);
|
|
@@ -769,8 +1173,8 @@ export function registerAllTools(server, wsServer, logger) {
|
|
|
769
1173
|
};
|
|
770
1174
|
}
|
|
771
1175
|
result = {
|
|
772
|
-
playbookVersion: '1.
|
|
773
|
-
summary: 'Use this playbook to
|
|
1176
|
+
playbookVersion: '1.5.0',
|
|
1177
|
+
summary: 'Use this playbook to check RemNote connection and write gates, navigate by remId with paged search/read/list workflows, request nearby ancestors when hierarchy context matters, choose compact/full output views, and apply safe exact-ID writes including dry-run-first document status changes.',
|
|
774
1178
|
recommendedStatusCheck: {
|
|
775
1179
|
tool: 'remnote_status',
|
|
776
1180
|
cadence: 'recommended once per session and before risky writes',
|
|
@@ -778,15 +1182,23 @@ export function registerAllTools(server, wsServer, logger) {
|
|
|
778
1182
|
},
|
|
779
1183
|
decisionTree: [
|
|
780
1184
|
'Need connection/capability context? Call remnote_status first.',
|
|
781
|
-
'Need to orient across the KB? Use remnote_search with
|
|
782
|
-
'Need
|
|
783
|
-
'Need
|
|
1185
|
+
'Need to orient across the KB? Use remnote_search with contentMode="structured", view="compact", depth=1, childLimit=500.',
|
|
1186
|
+
'Need broad search enumeration? Continue remnote_search or remnote_search_by_tag with nextCursor while hasMore is true.',
|
|
1187
|
+
'Need tagged-note context/navigation? Use remnote_search_by_tag with tagRemId and default resultMode="context"; inspect matchedRems to see the direct tagged Rems behind each context result.',
|
|
1188
|
+
'Need hierarchy placement context? Add ancestorDepth, typically 5, to search/read/search_by_tag/list_children; ancestors are direct-parent first.',
|
|
1189
|
+
'Need strict tag verification? Use remnote_search_by_tag with resultMode="tagged", or verify the exact Rem in matchedRems from context mode.',
|
|
1190
|
+
'Need a large tag search to finish? Prefer cursor paging first; use remnote_search_by_tag.timeoutMs only as a bounded wait-time escape hatch.',
|
|
1191
|
+
'Need to traverse a specific branch cheaply? Use remnote_list_children on the parentRemId and page through direct children.',
|
|
1192
|
+
'Need to read a selected subtree? Use remnote_read_note on a chosen remId with contentMode="structured", depth=1, childLimit=500, then deepen selected branches.',
|
|
1193
|
+
'Need to follow inline graph references? Inspect inlineRefs on search/read results and structured child nodes for exact target Rem IDs.',
|
|
784
1194
|
'Need tabular/structured data from an Advanced Table? Use remnote_read_table with either tableTitle or tableRemId. Use propertyFilter to limit columns for large tables.',
|
|
785
|
-
'Need a human-readable summary? Switch to
|
|
1195
|
+
'Need a human-readable summary? Switch to contentMode="markdown" on search/read results.',
|
|
786
1196
|
'Need to rename a note? Use remnote_update_note with remId and title only.',
|
|
787
|
-
'Need to create a note? Use remnote_create_note; pass tagRemIds for exact-ID tag assignment.',
|
|
1197
|
+
'Need to create a note? Use remnote_create_note; pass tagRemIds for exact-ID tag assignment and asDocument=true when the title/root Rem should be a document.',
|
|
1198
|
+
'Need to mark an existing Rem as a document? Use remnote_set_document_status dryRun first, include expectedOldRemType for stale-context protection, then rerun with dryRun=false after approval.',
|
|
788
1199
|
'Need to append to today journal? Use remnote_append_journal; pass tagRemIds when the journal entry should be tagged.',
|
|
789
1200
|
'Need to insert children? Use remnote_insert_children with an explicit position.',
|
|
1201
|
+
'Need to move a note? Use remnote_move_note dryRun first, include expectedOldParentRemId for stale-context protection, then rerun with dryRun=false after approval.',
|
|
790
1202
|
'Need to replace children? Check remnote_status first; remnote_replace_children requires acceptReplaceOperation=true.',
|
|
791
1203
|
'Need to update tags on an existing note? Use remnote_update_tags with exact tag Rem IDs.',
|
|
792
1204
|
],
|
|
@@ -795,18 +1207,25 @@ export function registerAllTools(server, wsServer, logger) {
|
|
|
795
1207
|
branchTraversal: NAVIGATION_PRESET,
|
|
796
1208
|
},
|
|
797
1209
|
contentModes: {
|
|
798
|
-
structured: 'ID-first traversal mode. Returns contentStructured with child remIds for deterministic follow-up reads.',
|
|
799
|
-
markdown: 'Summary mode. Returns rendered markdown content for human-facing synthesis
|
|
1210
|
+
structured: 'ID-first traversal mode. Returns contentStructured with child remIds and inlineRefs for deterministic follow-up reads.',
|
|
1211
|
+
markdown: 'Summary mode. Returns rendered markdown content for human-facing synthesis; inline Rem references render as [[Target Title]].',
|
|
800
1212
|
none: 'Metadata-only mode when content is not needed.',
|
|
801
1213
|
},
|
|
1214
|
+
outputViews: {
|
|
1215
|
+
compact: 'Small metadata surface for broad discovery. Omits tags, aliases, inlineRefs, and diagnostic fields unless another option requires them.',
|
|
1216
|
+
standard: 'Normal discovery metadata for most agent workflows.',
|
|
1217
|
+
full: 'Verbose metadata for diagnostics or detailed audits.',
|
|
1218
|
+
},
|
|
802
1219
|
writePolicy: {
|
|
803
1220
|
statusTool: 'remnote_status',
|
|
804
1221
|
requiredFields: ['acceptWriteOperations', 'acceptReplaceOperation'],
|
|
805
1222
|
guidance: [
|
|
806
1223
|
'Create/update/insert/replace/tag/journal writes require acceptWriteOperations=true.',
|
|
807
1224
|
'remnote_update_note is metadata-only; use insert_children, replace_children, and update_tags for structural or tag writes.',
|
|
1225
|
+
'remnote_set_document_status changes only document status; it preserves concept/card status and defaults to dryRun=true.',
|
|
808
1226
|
'remnote_replace_children requires acceptReplaceOperation=true.',
|
|
809
1227
|
'remnote_insert_children preserves existing child Rem IDs; remnote_replace_children removes them.',
|
|
1228
|
+
'remnote_move_note preserves the moved Rem ID and subtree; dryRun defaults to true.',
|
|
810
1229
|
'All production tag writes use exact tag Rem IDs: create_note.tagRemIds, append_journal.tagRemIds, and update_tags add/remove arrays.',
|
|
811
1230
|
],
|
|
812
1231
|
},
|