remnote-mcp-server 0.14.2 → 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.
Files changed (53) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/README.md +74 -30
  3. package/dist/cli.d.ts +2 -1
  4. package/dist/cli.js +9 -2
  5. package/dist/cli.js.map +1 -1
  6. package/dist/config.d.ts +14 -2
  7. package/dist/config.js +210 -10
  8. package/dist/config.js.map +1 -1
  9. package/dist/daemon.d.ts +61 -0
  10. package/dist/daemon.js +735 -0
  11. package/dist/daemon.js.map +1 -0
  12. package/dist/index.js +8 -10
  13. package/dist/index.js.map +1 -1
  14. package/dist/remnote-cli/cli.js +8 -1
  15. package/dist/remnote-cli/cli.js.map +1 -1
  16. package/dist/remnote-cli/client/mcp-server-client.d.ts +1 -0
  17. package/dist/remnote-cli/client/mcp-server-client.js +14 -5
  18. package/dist/remnote-cli/client/mcp-server-client.js.map +1 -1
  19. package/dist/remnote-cli/commands/content-input.d.ts +0 -12
  20. package/dist/remnote-cli/commands/content-input.js +0 -20
  21. package/dist/remnote-cli/commands/content-input.js.map +1 -1
  22. package/dist/remnote-cli/commands/create.js +6 -3
  23. package/dist/remnote-cli/commands/create.js.map +1 -1
  24. package/dist/remnote-cli/commands/journal.js +3 -0
  25. package/dist/remnote-cli/commands/journal.js.map +1 -1
  26. package/dist/remnote-cli/commands/read.js +37 -5
  27. package/dist/remnote-cli/commands/read.js.map +1 -1
  28. package/dist/remnote-cli/commands/search.d.ts +1 -0
  29. package/dist/remnote-cli/commands/search.js +111 -11
  30. package/dist/remnote-cli/commands/search.js.map +1 -1
  31. package/dist/remnote-cli/commands/update.js +5 -24
  32. package/dist/remnote-cli/commands/update.js.map +1 -1
  33. package/dist/remnote-cli/commands/write-actions.d.ts +6 -0
  34. package/dist/remnote-cli/commands/write-actions.js +229 -0
  35. package/dist/remnote-cli/commands/write-actions.js.map +1 -0
  36. package/dist/schemas/remnote-schemas.d.ts +105 -18
  37. package/dist/schemas/remnote-schemas.js +179 -60
  38. package/dist/schemas/remnote-schemas.js.map +1 -1
  39. package/dist/shutdown.d.ts +15 -0
  40. package/dist/shutdown.js +59 -0
  41. package/dist/shutdown.js.map +1 -0
  42. package/dist/tools/index.d.ts +3722 -173
  43. package/dist/tools/index.js +595 -66
  44. package/dist/tools/index.js.map +1 -1
  45. package/dist/websocket-server.d.ts +2 -1
  46. package/dist/websocket-server.js +6 -2
  47. package/dist/websocket-server.js.map +1 -1
  48. package/mcpb/remnote-local/manifest.json +40 -26
  49. package/mcpb/remnote-local/package.json +1 -1
  50. package/mcpb/remnote-local/remnote-local.mcpb +0 -0
  51. package/mcpb/remnote-local/server/fallback-tools.generated.js +477 -0
  52. package/mcpb/remnote-local/server/index.js +11 -124
  53. package/package.json +5 -3
@@ -4,17 +4,97 @@ 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';
10
+ import { InsertChildrenSchema } from '../schemas/remnote-schemas.js';
11
+ import { ReplaceChildrenSchema } from '../schemas/remnote-schemas.js';
12
+ import { UpdateTagsSchema } from '../schemas/remnote-schemas.js';
7
13
  import { AppendJournalSchema } from '../schemas/remnote-schemas.js';
8
14
  import { ReadTableSchema } from '../schemas/remnote-schemas.js';
9
15
  import { checkVersionCompatibility } from '../version-compat.js';
10
16
  const NAVIGATION_PRESET = {
11
- includeContent: 'structured',
17
+ contentMode: 'structured',
18
+ view: 'compact',
12
19
  depth: 1,
13
20
  childLimit: 500,
14
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
+ };
35
+ const TAG_INFO_SCHEMA = {
36
+ type: 'object',
37
+ properties: {
38
+ tagRemId: { type: 'string', description: 'Exact tag Rem ID' },
39
+ name: { type: 'string', description: 'Human-readable tag name' },
40
+ },
41
+ required: ['tagRemId', 'name'],
42
+ additionalProperties: false,
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
+ };
15
95
  export const CREATE_NOTE_TOOL = {
16
96
  name: 'remnote_create_note',
17
- description: 'Create a new note in RemNote with optional content, parent, and tags. 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.',
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.',
18
98
  inputSchema: {
19
99
  type: 'object',
20
100
  properties: {
@@ -27,9 +107,18 @@ export const CREATE_NOTE_TOOL = {
27
107
  description: 'Content as plain text, child bullets or hierarchical markdown',
28
108
  },
29
109
  parentId: { type: 'string', description: 'Parent Rem ID' },
30
- tags: { type: 'array', items: { type: 'string' }, description: 'Tags to apply' },
110
+ tagRemIds: {
111
+ type: 'array',
112
+ items: { type: 'string' },
113
+ description: 'Exact tag Rem IDs to apply',
114
+ },
115
+ asDocument: {
116
+ type: 'boolean',
117
+ description: 'Mark the created title/root Rem as a document while preserving any concept/card status',
118
+ },
31
119
  },
32
120
  required: [],
121
+ additionalProperties: false,
33
122
  },
34
123
  outputSchema: {
35
124
  type: 'object',
@@ -50,17 +139,30 @@ export const CREATE_NOTE_TOOL = {
50
139
  };
51
140
  export const SEARCH_TOOL = {
52
141
  name: 'remnote_search',
53
- description: 'Search the RemNote knowledge base. For whole-KB orientation, prefer includeContent="structured" with depth=1 and childLimit=500, then follow remIds with remnote_read_note. Use includeContent="markdown" for human-readable summaries.',
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.',
54
143
  inputSchema: {
55
144
  type: 'object',
56
145
  properties: {
57
146
  query: { type: 'string', description: 'Search query text' },
58
147
  limit: { type: 'number', description: 'Maximum results (1-150, default: 50)' },
59
- includeContent: {
148
+ cursor: {
149
+ type: 'string',
150
+ description: 'Opaque cursor returned by a previous remnote_search response',
151
+ },
152
+ contentMode: {
60
153
  type: 'string',
61
154
  enum: ['none', 'markdown', 'structured'],
62
155
  description: 'Content rendering mode: "none" omits content (default), "markdown" renders child subtree as indented markdown, "structured" returns nested child objects with remIds',
63
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
+ },
64
166
  depth: {
65
167
  type: 'number',
66
168
  description: 'Depth of child hierarchy to render for markdown/structured content (0-10, default: 1)',
@@ -91,6 +193,11 @@ export const SEARCH_TOOL = {
91
193
  type: 'string',
92
194
  description: 'Display-oriented full line: title + type-aware delimiter + detail (e.g. "Term :: Definition")',
93
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
+ },
94
201
  parentRemId: {
95
202
  type: 'string',
96
203
  description: 'Direct parent Rem ID (omitted for top-level Rems)',
@@ -99,6 +206,15 @@ export const SEARCH_TOOL = {
99
206
  type: 'string',
100
207
  description: 'Direct parent title/front text (omitted for top-level Rems)',
101
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
+ },
102
218
  aliases: {
103
219
  type: 'array',
104
220
  items: { type: 'string' },
@@ -106,24 +222,42 @@ export const SEARCH_TOOL = {
106
222
  },
107
223
  tags: {
108
224
  type: 'array',
109
- items: { type: 'string' },
110
- description: 'Direct tag names applied to the returned Rem (omitted if none or unavailable from the bridge runtime)',
225
+ items: TAG_INFO_SCHEMA,
226
+ description: 'Direct tags applied to the returned Rem as exact tag Rem IDs plus names (omitted if none or unavailable from the bridge runtime)',
111
227
  },
112
228
  remType: {
113
229
  type: 'string',
114
230
  description: 'Rem classification: document, dailyDocument, concept, descriptor, portal, or text',
115
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
+ },
116
250
  cardDirection: {
117
251
  type: 'string',
118
252
  description: 'Flashcard direction: forward, reverse, or bidirectional (omitted if not a flashcard)',
119
253
  },
120
254
  content: {
121
255
  type: 'string',
122
- description: 'Rendered markdown content of child subtree (only when includeContent="markdown")',
256
+ description: 'Rendered markdown content of child subtree (only when contentMode="markdown")',
123
257
  },
124
258
  contentStructured: {
125
259
  type: 'array',
126
- description: 'Structured child subtree with nested remIds and metadata (only when includeContent="structured")',
260
+ description: 'Structured child subtree with nested remIds and metadata (only when contentMode="structured")',
127
261
  items: {
128
262
  type: 'object',
129
263
  properties: {
@@ -133,6 +267,11 @@ export const SEARCH_TOOL = {
133
267
  type: 'string',
134
268
  description: 'Display-oriented child line with type-aware delimiter',
135
269
  },
270
+ inlineRefs: {
271
+ type: 'array',
272
+ items: INLINE_REF_SCHEMA,
273
+ description: 'Resolvable inline Rem references from the child title/headline',
274
+ },
136
275
  aliases: {
137
276
  type: 'array',
138
277
  items: { type: 'string' },
@@ -140,8 +279,8 @@ export const SEARCH_TOOL = {
140
279
  },
141
280
  tags: {
142
281
  type: 'array',
143
- items: { type: 'string' },
144
- description: 'Direct tag names applied to the child Rem (omitted if none or unavailable from the bridge runtime)',
282
+ items: TAG_INFO_SCHEMA,
283
+ description: 'Direct tags applied to the child Rem as exact tag Rem IDs plus names (omitted if none or unavailable from the bridge runtime)',
145
284
  },
146
285
  remType: {
147
286
  type: 'string',
@@ -181,25 +320,56 @@ export const SEARCH_TOOL = {
181
320
  },
182
321
  },
183
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
+ },
184
340
  },
185
341
  },
186
342
  };
187
343
  export const SEARCH_BY_TAG_TOOL = {
188
344
  name: 'remnote_search_by_tag',
189
- description: 'Find notes by tag and return resolved ancestor context targets (nearest document/daily document when available, otherwise nearest non-document ancestor). Supports the same includeContent modes as remnote_search.',
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.',
190
346
  inputSchema: {
191
347
  type: 'object',
192
348
  properties: {
193
- tag: {
349
+ tagRemId: {
350
+ type: 'string',
351
+ description: 'Exact tag Rem ID to search',
352
+ },
353
+ resultMode: {
194
354
  type: 'string',
195
- description: 'Tag name to search (with or without # prefix)',
355
+ enum: ['context', 'tagged'],
356
+ description: '"context" returns resolved ancestor context targets with matchedRems (default); "tagged" returns directly tagged Rems with context metadata',
196
357
  },
197
358
  limit: { type: 'number', description: 'Maximum results (1-150, default: 50)' },
198
- includeContent: {
359
+ contentMode: {
199
360
  type: 'string',
200
361
  enum: ['none', 'markdown', 'structured'],
201
362
  description: 'Content rendering mode: "none" omits content (default), "markdown" renders child subtree as indented markdown, "structured" returns nested child objects with remIds',
202
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
+ },
203
373
  depth: {
204
374
  type: 'number',
205
375
  description: 'Depth of child hierarchy to render for markdown/structured content (0-10, default: 1)',
@@ -212,14 +382,31 @@ export const SEARCH_BY_TAG_TOOL = {
212
382
  type: 'number',
213
383
  description: 'Maximum character length for rendered content (default: 3000)',
214
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
+ },
393
+ },
394
+ required: ['tagRemId'],
395
+ },
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,
215
404
  },
216
- required: ['tag'],
217
405
  },
218
- outputSchema: SEARCH_TOOL.outputSchema,
219
406
  };
220
407
  export const READ_NOTE_TOOL = {
221
408
  name: 'remnote_read_note',
222
- description: 'Read a specific note from RemNote by its Rem ID. For hierarchy traversal, prefer includeContent="structured" and start shallow (depth=1, childLimit=500), then deepen only selected branches. Use includeContent="markdown" for summarization.',
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.',
223
410
  inputSchema: {
224
411
  type: 'object',
225
412
  properties: {
@@ -228,11 +415,20 @@ export const READ_NOTE_TOOL = {
228
415
  type: 'number',
229
416
  description: 'Depth of child hierarchy to render (0-10, default: 5)',
230
417
  },
231
- includeContent: {
418
+ contentMode: {
232
419
  type: 'string',
233
420
  enum: ['none', 'markdown', 'structured'],
234
421
  description: 'Content rendering mode: "markdown" renders child subtree (default), "structured" returns nested child objects with remIds, "none" omits content',
235
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
+ },
236
432
  childLimit: {
237
433
  type: 'number',
238
434
  description: 'Maximum children per level (1-500, default: 100)',
@@ -253,6 +449,11 @@ export const READ_NOTE_TOOL = {
253
449
  type: 'string',
254
450
  description: 'Display-oriented full line: title + type-aware delimiter + detail (e.g. "Term :: Definition")',
255
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
+ },
256
457
  parentRemId: {
257
458
  type: 'string',
258
459
  description: 'Direct parent Rem ID (omitted for top-level Rems)',
@@ -261,6 +462,15 @@ export const READ_NOTE_TOOL = {
261
462
  type: 'string',
262
463
  description: 'Direct parent title/front text (omitted for top-level Rems)',
263
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
+ },
264
474
  aliases: {
265
475
  type: 'array',
266
476
  items: { type: 'string' },
@@ -268,8 +478,8 @@ export const READ_NOTE_TOOL = {
268
478
  },
269
479
  tags: {
270
480
  type: 'array',
271
- items: { type: 'string' },
272
- description: 'Direct tag names applied to the returned Rem (omitted if none or unavailable from the bridge runtime)',
481
+ items: TAG_INFO_SCHEMA,
482
+ description: 'Direct tags applied to the returned Rem as exact tag Rem IDs plus names (omitted if none or unavailable from the bridge runtime)',
273
483
  },
274
484
  remType: {
275
485
  type: 'string',
@@ -281,11 +491,11 @@ export const READ_NOTE_TOOL = {
281
491
  },
282
492
  content: {
283
493
  type: 'string',
284
- description: 'Rendered markdown content of child subtree (when includeContent="markdown", which is the default)',
494
+ description: 'Rendered markdown content of child subtree (when contentMode="markdown", which is the default)',
285
495
  },
286
496
  contentStructured: {
287
497
  type: 'array',
288
- description: 'Structured child subtree with nested remIds and metadata (only when includeContent="structured")',
498
+ description: 'Structured child subtree with nested remIds and metadata (only when contentMode="structured")',
289
499
  items: {
290
500
  type: 'object',
291
501
  properties: {
@@ -295,6 +505,11 @@ export const READ_NOTE_TOOL = {
295
505
  type: 'string',
296
506
  description: 'Display-oriented child line with type-aware delimiter',
297
507
  },
508
+ inlineRefs: {
509
+ type: 'array',
510
+ items: INLINE_REF_SCHEMA,
511
+ description: 'Resolvable inline Rem references from the child title/headline',
512
+ },
298
513
  aliases: {
299
514
  type: 'array',
300
515
  items: { type: 'string' },
@@ -302,8 +517,8 @@ export const READ_NOTE_TOOL = {
302
517
  },
303
518
  tags: {
304
519
  type: 'array',
305
- items: { type: 'string' },
306
- description: 'Direct tag names applied to the child Rem (omitted if none or unavailable from the bridge runtime)',
520
+ items: TAG_INFO_SCHEMA,
521
+ description: 'Direct tags applied to the child Rem as exact tag Rem IDs plus names (omitted if none or unavailable from the bridge runtime)',
307
522
  },
308
523
  remType: {
309
524
  type: 'string',
@@ -343,26 +558,109 @@ export const READ_NOTE_TOOL = {
343
558
  },
344
559
  },
345
560
  };
346
- export const UPDATE_NOTE_TOOL = {
347
- name: 'remnote_update_note',
348
- description: 'Update an existing note in RemNote (change title, append content, replace content, or modify tags). Recommended preflight once per session: remnote_status. appendContent and replaceContent are mutually exclusive. replaceContent may be blocked by bridge policy.',
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.',
349
564
  inputSchema: {
350
565
  type: 'object',
351
566
  properties: {
352
- remId: { type: 'string', description: 'The Rem ID to update' },
353
- title: { type: 'string', description: 'New title' },
354
- appendContent: {
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: {
355
570
  type: 'string',
356
- description: 'Content to append as children (markdown supported)',
571
+ description: 'Opaque cursor returned by a previous remnote_list_children response',
357
572
  },
358
- replaceContent: {
573
+ view: {
359
574
  type: 'string',
360
- description: 'Content to replace direct children (markdown supported, empty string clears children)',
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',
361
581
  },
362
- addTags: { type: 'array', items: { type: 'string' }, description: 'Tags to add' },
363
- removeTags: { type: 'array', items: { type: 'string' }, description: 'Tags to remove' },
364
582
  },
365
- required: ['remId'],
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
+ };
653
+ export const UPDATE_NOTE_TOOL = {
654
+ name: 'remnote_update_note',
655
+ description: 'Update note metadata in RemNote. Use this tool for title changes only.',
656
+ inputSchema: {
657
+ type: 'object',
658
+ properties: {
659
+ remId: { type: 'string', description: 'The Rem ID to update' },
660
+ title: { type: 'string', description: 'New title' },
661
+ },
662
+ required: ['remId', 'title'],
663
+ additionalProperties: false,
366
664
  },
367
665
  outputSchema: {
368
666
  type: 'object',
@@ -381,9 +679,174 @@ export const UPDATE_NOTE_TOOL = {
381
679
  required: ['remIds', 'titles'],
382
680
  },
383
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
+ };
776
+ export const INSERT_CHILDREN_TOOL = {
777
+ name: 'remnote_insert_children',
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.',
779
+ inputSchema: {
780
+ type: 'object',
781
+ properties: {
782
+ parentRemId: {
783
+ type: 'string',
784
+ description: 'Parent Rem ID that will receive the new children',
785
+ },
786
+ content: { type: 'string', description: 'Markdown content to insert as child Rems' },
787
+ position: {
788
+ type: 'string',
789
+ enum: ['first', 'last', 'before', 'after'],
790
+ description: 'Where to insert the new child Rems',
791
+ },
792
+ siblingRemId: {
793
+ type: 'string',
794
+ description: 'Sibling Rem ID required when position is before or after',
795
+ },
796
+ },
797
+ required: ['parentRemId', 'content', 'position'],
798
+ additionalProperties: false,
799
+ },
800
+ outputSchema: UPDATE_NOTE_TOOL.outputSchema,
801
+ };
802
+ export const REPLACE_CHILDREN_TOOL = {
803
+ name: 'remnote_replace_children',
804
+ description: 'Replace all direct children under a parent Rem. This is destructive because existing child Rem IDs are removed and may be blocked by bridge policy.',
805
+ inputSchema: {
806
+ type: 'object',
807
+ properties: {
808
+ parentRemId: {
809
+ type: 'string',
810
+ description: 'Parent Rem ID whose direct children will be replaced',
811
+ },
812
+ content: {
813
+ type: 'string',
814
+ description: 'Markdown content to use as replacement children; empty string clears all direct children',
815
+ },
816
+ },
817
+ required: ['parentRemId', 'content'],
818
+ additionalProperties: false,
819
+ },
820
+ outputSchema: UPDATE_NOTE_TOOL.outputSchema,
821
+ };
822
+ export const UPDATE_TAGS_TOOL = {
823
+ name: 'remnote_update_tags',
824
+ description: 'Add or remove tags from a note by exact tag Rem IDs. Use this for production tagging workflows to avoid ambiguous name lookup.',
825
+ inputSchema: {
826
+ type: 'object',
827
+ properties: {
828
+ remId: { type: 'string', description: 'The Rem ID whose tags should change' },
829
+ addTagRemIds: {
830
+ type: 'array',
831
+ items: { type: 'string' },
832
+ minItems: 1,
833
+ description: 'Exact tag Rem IDs to add',
834
+ },
835
+ removeTagRemIds: {
836
+ type: 'array',
837
+ items: { type: 'string' },
838
+ minItems: 1,
839
+ description: 'Exact tag Rem IDs to remove',
840
+ },
841
+ },
842
+ required: ['remId'],
843
+ additionalProperties: false,
844
+ },
845
+ outputSchema: UPDATE_NOTE_TOOL.outputSchema,
846
+ };
384
847
  export const APPEND_JOURNAL_TOOL = {
385
848
  name: 'remnote_append_journal',
386
- description: "Append content to today's daily document in RemNote. Recommended preflight once per session: remnote_status.",
849
+ description: "Append content to today's daily document in RemNote with optional exact tag Rem IDs. Recommended preflight once per session: remnote_status.",
387
850
  inputSchema: {
388
851
  type: 'object',
389
852
  properties: {
@@ -392,8 +855,14 @@ export const APPEND_JOURNAL_TOOL = {
392
855
  description: "Content to append to today's daily document (markdown supported)",
393
856
  },
394
857
  timestamp: { type: 'boolean', description: 'Include timestamp (default: true)' },
858
+ tagRemIds: {
859
+ type: 'array',
860
+ items: { type: 'string' },
861
+ description: 'Exact tag Rem IDs to apply',
862
+ },
395
863
  },
396
864
  required: ['content'],
865
+ additionalProperties: false,
397
866
  },
398
867
  outputSchema: {
399
868
  type: 'object',
@@ -431,11 +900,11 @@ export const STATUS_TOOL = {
431
900
  },
432
901
  acceptWriteOperations: {
433
902
  type: 'boolean',
434
- description: 'Whether bridge allows write actions (create/update/journal)',
903
+ description: 'Whether bridge allows write actions',
435
904
  },
436
905
  acceptReplaceOperation: {
437
906
  type: 'boolean',
438
- description: 'Whether bridge allows update replaceContent operations',
907
+ description: 'Whether bridge allows remnote_replace_children operations',
439
908
  },
440
909
  message: {
441
910
  type: 'string',
@@ -549,7 +1018,8 @@ export const PLAYBOOK_TOOL = {
549
1018
  orientation: {
550
1019
  type: 'object',
551
1020
  properties: {
552
- includeContent: { type: 'string' },
1021
+ contentMode: { type: 'string' },
1022
+ view: { type: 'string' },
553
1023
  depth: { type: 'number' },
554
1024
  childLimit: { type: 'number' },
555
1025
  },
@@ -580,6 +1050,23 @@ export const PLAYBOOK_TOOL = {
580
1050
  required: ['playbookVersion', 'summary', 'decisionTree', 'navigationPresets', 'contentModes'],
581
1051
  },
582
1052
  };
1053
+ export const ALL_TOOLS = [
1054
+ CREATE_NOTE_TOOL,
1055
+ SEARCH_TOOL,
1056
+ SEARCH_BY_TAG_TOOL,
1057
+ READ_NOTE_TOOL,
1058
+ LIST_CHILDREN_TOOL,
1059
+ UPDATE_NOTE_TOOL,
1060
+ SET_DOCUMENT_STATUS_TOOL,
1061
+ MOVE_NOTE_TOOL,
1062
+ INSERT_CHILDREN_TOOL,
1063
+ REPLACE_CHILDREN_TOOL,
1064
+ UPDATE_TAGS_TOOL,
1065
+ APPEND_JOURNAL_TOOL,
1066
+ PLAYBOOK_TOOL,
1067
+ STATUS_TOOL,
1068
+ READ_TABLE_TOOL,
1069
+ ];
583
1070
  export function registerAllTools(server, wsServer, logger) {
584
1071
  const toolLogger = logger.child({ context: 'tools' });
585
1072
  async function buildStatusResult() {
@@ -625,7 +1112,8 @@ export function registerAllTools(server, wsServer, logger) {
625
1112
  }
626
1113
  case 'remnote_search_by_tag': {
627
1114
  const args = SearchByTagSchema.parse(request.params.arguments);
628
- result = await wsServer.sendRequest('search_by_tag', args);
1115
+ const { timeoutMs, ...payload } = args;
1116
+ result = await wsServer.sendRequest('search_by_tag', payload, timeoutMs);
629
1117
  break;
630
1118
  }
631
1119
  case 'remnote_read_note': {
@@ -633,11 +1121,41 @@ export function registerAllTools(server, wsServer, logger) {
633
1121
  result = await wsServer.sendRequest('read_note', args);
634
1122
  break;
635
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
+ }
636
1129
  case 'remnote_update_note': {
637
1130
  const args = UpdateNoteSchema.parse(request.params.arguments);
638
1131
  result = await wsServer.sendRequest('update_note', args);
639
1132
  break;
640
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
+ }
1139
+ case 'remnote_insert_children': {
1140
+ const args = InsertChildrenSchema.parse(request.params.arguments);
1141
+ result = await wsServer.sendRequest('insert_children', args);
1142
+ break;
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
+ }
1149
+ case 'remnote_replace_children': {
1150
+ const args = ReplaceChildrenSchema.parse(request.params.arguments);
1151
+ result = await wsServer.sendRequest('replace_children', args);
1152
+ break;
1153
+ }
1154
+ case 'remnote_update_tags': {
1155
+ const args = UpdateTagsSchema.parse(request.params.arguments);
1156
+ result = await wsServer.sendRequest('update_tags', args);
1157
+ break;
1158
+ }
641
1159
  case 'remnote_append_journal': {
642
1160
  const args = AppendJournalSchema.parse(request.params.arguments);
643
1161
  result = await wsServer.sendRequest('append_journal', args);
@@ -655,8 +1173,8 @@ export function registerAllTools(server, wsServer, logger) {
655
1173
  };
656
1174
  }
657
1175
  result = {
658
- playbookVersion: '1.0.0',
659
- summary: 'Use this playbook to navigate RemNote efficiently via remIds, and to apply write-safety checks before mutations.',
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.',
660
1178
  recommendedStatusCheck: {
661
1179
  tool: 'remnote_status',
662
1180
  cadence: 'recommended once per session and before risky writes',
@@ -664,28 +1182,51 @@ export function registerAllTools(server, wsServer, logger) {
664
1182
  },
665
1183
  decisionTree: [
666
1184
  'Need connection/capability context? Call remnote_status first.',
667
- 'Need to orient across the KB? Use remnote_search with includeContent="structured", depth=1, childLimit=500.',
668
- 'Need to traverse a specific branch? Use remnote_read_note on a chosen remId with includeContent="structured", depth=1, childLimit=500, then recurse by child remIds.',
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.',
669
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.',
670
- 'Need a human-readable summary? Switch to includeContent="markdown" on search/read results.',
671
- 'Need to modify content? Check remnote_status: if acceptWriteOperations is false, stop; if using replaceContent, ensure acceptReplaceOperation is true.',
1195
+ 'Need a human-readable summary? Switch to contentMode="markdown" on search/read results.',
1196
+ 'Need to rename a note? Use remnote_update_note with remId and title only.',
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.',
1199
+ 'Need to append to today journal? Use remnote_append_journal; pass tagRemIds when the journal entry should be tagged.',
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.',
1202
+ 'Need to replace children? Check remnote_status first; remnote_replace_children requires acceptReplaceOperation=true.',
1203
+ 'Need to update tags on an existing note? Use remnote_update_tags with exact tag Rem IDs.',
672
1204
  ],
673
1205
  navigationPresets: {
674
1206
  orientation: NAVIGATION_PRESET,
675
1207
  branchTraversal: NAVIGATION_PRESET,
676
1208
  },
677
1209
  contentModes: {
678
- structured: 'ID-first traversal mode. Returns contentStructured with child remIds for deterministic follow-up reads.',
679
- markdown: 'Summary mode. Returns rendered markdown content for human-facing synthesis, not deterministic child ID traversal.',
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]].',
680
1212
  none: 'Metadata-only mode when content is not needed.',
681
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
+ },
682
1219
  writePolicy: {
683
1220
  statusTool: 'remnote_status',
684
1221
  requiredFields: ['acceptWriteOperations', 'acceptReplaceOperation'],
685
1222
  guidance: [
686
- 'Create/update/journal require acceptWriteOperations=true.',
687
- 'replaceContent updates require acceptReplaceOperation=true.',
688
- 'appendContent and replaceContent cannot be used in the same remnote_update_note call.',
1223
+ 'Create/update/insert/replace/tag/journal writes require acceptWriteOperations=true.',
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.',
1226
+ 'remnote_replace_children requires acceptReplaceOperation=true.',
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.',
1229
+ 'All production tag writes use exact tag Rem IDs: create_note.tagRemIds, append_journal.tagRemIds, and update_tags add/remove arrays.',
689
1230
  ],
690
1231
  },
691
1232
  currentStatus,
@@ -732,19 +1273,7 @@ export function registerAllTools(server, wsServer, logger) {
732
1273
  // Register list_tools handler
733
1274
  server.setRequestHandler(ListToolsRequestSchema, async () => {
734
1275
  toolLogger.debug('Listing available tools');
735
- return {
736
- tools: [
737
- CREATE_NOTE_TOOL,
738
- SEARCH_TOOL,
739
- SEARCH_BY_TAG_TOOL,
740
- READ_NOTE_TOOL,
741
- UPDATE_NOTE_TOOL,
742
- APPEND_JOURNAL_TOOL,
743
- PLAYBOOK_TOOL,
744
- STATUS_TOOL,
745
- READ_TABLE_TOOL,
746
- ],
747
- };
1276
+ return { tools: [...ALL_TOOLS] };
748
1277
  });
749
1278
  }
750
1279
  //# sourceMappingURL=index.js.map