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.
- package/CHANGELOG.md +78 -0
- package/README.md +74 -30
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +9 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +14 -2
- package/dist/config.js +210 -10
- package/dist/config.js.map +1 -1
- package/dist/daemon.d.ts +61 -0
- package/dist/daemon.js +735 -0
- package/dist/daemon.js.map +1 -0
- package/dist/index.js +8 -10
- package/dist/index.js.map +1 -1
- package/dist/remnote-cli/cli.js +8 -1
- 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 +14 -5
- package/dist/remnote-cli/client/mcp-server-client.js.map +1 -1
- package/dist/remnote-cli/commands/content-input.d.ts +0 -12
- package/dist/remnote-cli/commands/content-input.js +0 -20
- package/dist/remnote-cli/commands/content-input.js.map +1 -1
- package/dist/remnote-cli/commands/create.js +6 -3
- package/dist/remnote-cli/commands/create.js.map +1 -1
- package/dist/remnote-cli/commands/journal.js +3 -0
- package/dist/remnote-cli/commands/journal.js.map +1 -1
- package/dist/remnote-cli/commands/read.js +37 -5
- 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 +111 -11
- package/dist/remnote-cli/commands/search.js.map +1 -1
- package/dist/remnote-cli/commands/update.js +5 -24
- package/dist/remnote-cli/commands/update.js.map +1 -1
- package/dist/remnote-cli/commands/write-actions.d.ts +6 -0
- package/dist/remnote-cli/commands/write-actions.js +229 -0
- package/dist/remnote-cli/commands/write-actions.js.map +1 -0
- package/dist/schemas/remnote-schemas.d.ts +105 -18
- package/dist/schemas/remnote-schemas.js +179 -60
- 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 +3722 -173
- package/dist/tools/index.js +595 -66
- 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 +40 -26
- 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 +477 -0
- package/mcpb/remnote-local/server/index.js +11 -124
- package/package.json +5 -3
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
// Generated by scripts/generate-mcpb-tools.mjs; do not edit by hand.
|
|
2
|
+
export const FALLBACK_TOOLS = [
|
|
3
|
+
{
|
|
4
|
+
name: 'remnote_create_note',
|
|
5
|
+
description:
|
|
6
|
+
'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.',
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: 'object',
|
|
9
|
+
properties: {
|
|
10
|
+
title: {
|
|
11
|
+
type: 'string',
|
|
12
|
+
description: 'The title of the note (optional if content is provided)',
|
|
13
|
+
},
|
|
14
|
+
content: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'Content as plain text, child bullets or hierarchical markdown',
|
|
17
|
+
},
|
|
18
|
+
parentId: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
description: 'Parent Rem ID',
|
|
21
|
+
},
|
|
22
|
+
tagRemIds: {
|
|
23
|
+
type: 'array',
|
|
24
|
+
items: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
},
|
|
27
|
+
description: 'Exact tag Rem IDs to apply',
|
|
28
|
+
},
|
|
29
|
+
asDocument: {
|
|
30
|
+
type: 'boolean',
|
|
31
|
+
description:
|
|
32
|
+
'Mark the created title/root Rem as a document while preserving any concept/card status',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
required: [],
|
|
36
|
+
additionalProperties: false,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'remnote_search',
|
|
41
|
+
description:
|
|
42
|
+
'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.',
|
|
43
|
+
inputSchema: {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: {
|
|
46
|
+
query: {
|
|
47
|
+
type: 'string',
|
|
48
|
+
description: 'Search query text',
|
|
49
|
+
},
|
|
50
|
+
limit: {
|
|
51
|
+
type: 'number',
|
|
52
|
+
description: 'Maximum results (1-150, default: 50)',
|
|
53
|
+
},
|
|
54
|
+
cursor: {
|
|
55
|
+
type: 'string',
|
|
56
|
+
description: 'Opaque cursor returned by a previous remnote_search response',
|
|
57
|
+
},
|
|
58
|
+
contentMode: {
|
|
59
|
+
type: 'string',
|
|
60
|
+
enum: ['none', 'markdown', 'structured'],
|
|
61
|
+
description:
|
|
62
|
+
'Content rendering mode: "none" omits content (default), "markdown" renders child subtree as indented markdown, "structured" returns nested child objects with remIds',
|
|
63
|
+
},
|
|
64
|
+
view: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
enum: ['compact', 'standard', 'full'],
|
|
67
|
+
description: 'Output detail level: compact, standard, or full',
|
|
68
|
+
},
|
|
69
|
+
ancestorDepth: {
|
|
70
|
+
type: 'number',
|
|
71
|
+
description: 'Number of parent Rems to include, direct parent first (0-20, default: 0)',
|
|
72
|
+
},
|
|
73
|
+
depth: {
|
|
74
|
+
type: 'number',
|
|
75
|
+
description:
|
|
76
|
+
'Depth of child hierarchy to render for markdown/structured content (0-10, default: 1)',
|
|
77
|
+
},
|
|
78
|
+
childLimit: {
|
|
79
|
+
type: 'number',
|
|
80
|
+
description: 'Maximum children per level (1-500, default: 20)',
|
|
81
|
+
},
|
|
82
|
+
maxContentLength: {
|
|
83
|
+
type: 'number',
|
|
84
|
+
description: 'Maximum character length for rendered content (default: 3000)',
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
required: ['query'],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'remnote_search_by_tag',
|
|
92
|
+
description:
|
|
93
|
+
'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.',
|
|
94
|
+
inputSchema: {
|
|
95
|
+
type: 'object',
|
|
96
|
+
properties: {
|
|
97
|
+
tagRemId: {
|
|
98
|
+
type: 'string',
|
|
99
|
+
description: 'Exact tag Rem ID to search',
|
|
100
|
+
},
|
|
101
|
+
resultMode: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
enum: ['context', 'tagged'],
|
|
104
|
+
description:
|
|
105
|
+
'"context" returns resolved ancestor context targets with matchedRems (default); "tagged" returns directly tagged Rems with context metadata',
|
|
106
|
+
},
|
|
107
|
+
limit: {
|
|
108
|
+
type: 'number',
|
|
109
|
+
description: 'Maximum results (1-150, default: 50)',
|
|
110
|
+
},
|
|
111
|
+
contentMode: {
|
|
112
|
+
type: 'string',
|
|
113
|
+
enum: ['none', 'markdown', 'structured'],
|
|
114
|
+
description:
|
|
115
|
+
'Content rendering mode: "none" omits content (default), "markdown" renders child subtree as indented markdown, "structured" returns nested child objects with remIds',
|
|
116
|
+
},
|
|
117
|
+
view: {
|
|
118
|
+
type: 'string',
|
|
119
|
+
enum: ['compact', 'standard', 'full'],
|
|
120
|
+
description: 'Output detail level: compact, standard, or full',
|
|
121
|
+
},
|
|
122
|
+
ancestorDepth: {
|
|
123
|
+
type: 'number',
|
|
124
|
+
description: 'Number of parent Rems to include, direct parent first (0-20, default: 0)',
|
|
125
|
+
},
|
|
126
|
+
depth: {
|
|
127
|
+
type: 'number',
|
|
128
|
+
description:
|
|
129
|
+
'Depth of child hierarchy to render for markdown/structured content (0-10, default: 1)',
|
|
130
|
+
},
|
|
131
|
+
childLimit: {
|
|
132
|
+
type: 'number',
|
|
133
|
+
description: 'Maximum children per level (1-500, default: 20)',
|
|
134
|
+
},
|
|
135
|
+
maxContentLength: {
|
|
136
|
+
type: 'number',
|
|
137
|
+
description: 'Maximum character length for rendered content (default: 3000)',
|
|
138
|
+
},
|
|
139
|
+
cursor: {
|
|
140
|
+
type: 'string',
|
|
141
|
+
description: 'Opaque cursor returned by a previous remnote_search_by_tag response',
|
|
142
|
+
},
|
|
143
|
+
timeoutMs: {
|
|
144
|
+
type: 'number',
|
|
145
|
+
description:
|
|
146
|
+
'Per-call bridge wait timeout in milliseconds (1-60000, default: 15000). Does not cancel plugin-side work.',
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
required: ['tagRemId'],
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: 'remnote_read_note',
|
|
154
|
+
description:
|
|
155
|
+
'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.',
|
|
156
|
+
inputSchema: {
|
|
157
|
+
type: 'object',
|
|
158
|
+
properties: {
|
|
159
|
+
remId: {
|
|
160
|
+
type: 'string',
|
|
161
|
+
description: 'The Rem ID to read',
|
|
162
|
+
},
|
|
163
|
+
depth: {
|
|
164
|
+
type: 'number',
|
|
165
|
+
description: 'Depth of child hierarchy to render (0-10, default: 5)',
|
|
166
|
+
},
|
|
167
|
+
contentMode: {
|
|
168
|
+
type: 'string',
|
|
169
|
+
enum: ['none', 'markdown', 'structured'],
|
|
170
|
+
description:
|
|
171
|
+
'Content rendering mode: "markdown" renders child subtree (default), "structured" returns nested child objects with remIds, "none" omits content',
|
|
172
|
+
},
|
|
173
|
+
view: {
|
|
174
|
+
type: 'string',
|
|
175
|
+
enum: ['compact', 'standard', 'full'],
|
|
176
|
+
description: 'Output detail level: compact, standard, or full',
|
|
177
|
+
},
|
|
178
|
+
ancestorDepth: {
|
|
179
|
+
type: 'number',
|
|
180
|
+
description: 'Number of parent Rems to include, direct parent first (0-20, default: 0)',
|
|
181
|
+
},
|
|
182
|
+
childLimit: {
|
|
183
|
+
type: 'number',
|
|
184
|
+
description: 'Maximum children per level (1-500, default: 100)',
|
|
185
|
+
},
|
|
186
|
+
maxContentLength: {
|
|
187
|
+
type: 'number',
|
|
188
|
+
description: 'Maximum character length for rendered content (default: 100000)',
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
required: ['remId'],
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: 'remnote_list_children',
|
|
196
|
+
description:
|
|
197
|
+
'List direct child Rems under a parent without rendering a subtree. Use for cheap hierarchy traversal; page with nextCursor when hasMore is true.',
|
|
198
|
+
inputSchema: {
|
|
199
|
+
type: 'object',
|
|
200
|
+
properties: {
|
|
201
|
+
parentRemId: {
|
|
202
|
+
type: 'string',
|
|
203
|
+
description: 'Parent Rem ID whose direct children to list',
|
|
204
|
+
},
|
|
205
|
+
limit: {
|
|
206
|
+
type: 'number',
|
|
207
|
+
description: 'Maximum direct children (1-150, default: 50)',
|
|
208
|
+
},
|
|
209
|
+
cursor: {
|
|
210
|
+
type: 'string',
|
|
211
|
+
description: 'Opaque cursor returned by a previous remnote_list_children response',
|
|
212
|
+
},
|
|
213
|
+
view: {
|
|
214
|
+
type: 'string',
|
|
215
|
+
enum: ['compact', 'standard', 'full'],
|
|
216
|
+
description: 'Output detail level for child metadata: compact, standard, or full',
|
|
217
|
+
},
|
|
218
|
+
ancestorDepth: {
|
|
219
|
+
type: 'number',
|
|
220
|
+
description: 'Number of parent Rems to include for each child, direct parent first',
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
required: ['parentRemId'],
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: 'remnote_update_note',
|
|
228
|
+
description: 'Update note metadata in RemNote. Use this tool for title changes only.',
|
|
229
|
+
inputSchema: {
|
|
230
|
+
type: 'object',
|
|
231
|
+
properties: {
|
|
232
|
+
remId: {
|
|
233
|
+
type: 'string',
|
|
234
|
+
description: 'The Rem ID to update',
|
|
235
|
+
},
|
|
236
|
+
title: {
|
|
237
|
+
type: 'string',
|
|
238
|
+
description: 'New title',
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
required: ['remId', 'title'],
|
|
242
|
+
additionalProperties: false,
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: 'remnote_set_document_status',
|
|
247
|
+
description:
|
|
248
|
+
'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.',
|
|
249
|
+
inputSchema: {
|
|
250
|
+
type: 'object',
|
|
251
|
+
properties: {
|
|
252
|
+
remId: {
|
|
253
|
+
type: 'string',
|
|
254
|
+
description: 'The Rem ID whose document status should change',
|
|
255
|
+
},
|
|
256
|
+
isDocument: {
|
|
257
|
+
type: 'boolean',
|
|
258
|
+
description: 'Whether the Rem should be marked as a document',
|
|
259
|
+
},
|
|
260
|
+
dryRun: {
|
|
261
|
+
type: 'boolean',
|
|
262
|
+
description:
|
|
263
|
+
'Preview the document-status change without mutating RemNote (default: true)',
|
|
264
|
+
},
|
|
265
|
+
expectedOldRemType: {
|
|
266
|
+
type: 'string',
|
|
267
|
+
enum: ['document', 'dailyDocument', 'concept', 'descriptor', 'portal', 'text'],
|
|
268
|
+
description:
|
|
269
|
+
'Optional stale-context guard; reject if current remType differs from this value',
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
required: ['remId', 'isDocument'],
|
|
273
|
+
additionalProperties: false,
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
name: 'remnote_move_note',
|
|
278
|
+
description:
|
|
279
|
+
'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.',
|
|
280
|
+
inputSchema: {
|
|
281
|
+
type: 'object',
|
|
282
|
+
properties: {
|
|
283
|
+
remId: {
|
|
284
|
+
type: 'string',
|
|
285
|
+
description: 'Rem ID to move',
|
|
286
|
+
},
|
|
287
|
+
newParentRemId: {
|
|
288
|
+
type: 'string',
|
|
289
|
+
description: 'New parent Rem ID',
|
|
290
|
+
},
|
|
291
|
+
position: {
|
|
292
|
+
type: 'string',
|
|
293
|
+
enum: ['first', 'last', 'before', 'after'],
|
|
294
|
+
description: 'Where to place the moved Rem under the new parent (default: last)',
|
|
295
|
+
},
|
|
296
|
+
siblingRemId: {
|
|
297
|
+
type: 'string',
|
|
298
|
+
description: 'Sibling Rem ID required for before/after positioning',
|
|
299
|
+
},
|
|
300
|
+
dryRun: {
|
|
301
|
+
type: 'boolean',
|
|
302
|
+
description: 'Preview without mutating RemNote (default: true)',
|
|
303
|
+
},
|
|
304
|
+
expectedOldParentRemId: {
|
|
305
|
+
type: 'string',
|
|
306
|
+
description: 'Reject if the current direct parent differs from this Rem ID',
|
|
307
|
+
},
|
|
308
|
+
ancestorDepth: {
|
|
309
|
+
type: 'number',
|
|
310
|
+
description: 'Number of parent Rems to include before/after the move',
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
required: ['remId', 'newParentRemId'],
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
name: 'remnote_insert_children',
|
|
318
|
+
description:
|
|
319
|
+
'Insert new child Rems under a parent at a deterministic position without replacing existing children. Use this for tag description nodes and hierarchy maintenance.',
|
|
320
|
+
inputSchema: {
|
|
321
|
+
type: 'object',
|
|
322
|
+
properties: {
|
|
323
|
+
parentRemId: {
|
|
324
|
+
type: 'string',
|
|
325
|
+
description: 'Parent Rem ID that will receive the new children',
|
|
326
|
+
},
|
|
327
|
+
content: {
|
|
328
|
+
type: 'string',
|
|
329
|
+
description: 'Markdown content to insert as child Rems',
|
|
330
|
+
},
|
|
331
|
+
position: {
|
|
332
|
+
type: 'string',
|
|
333
|
+
enum: ['first', 'last', 'before', 'after'],
|
|
334
|
+
description: 'Where to insert the new child Rems',
|
|
335
|
+
},
|
|
336
|
+
siblingRemId: {
|
|
337
|
+
type: 'string',
|
|
338
|
+
description: 'Sibling Rem ID required when position is before or after',
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
required: ['parentRemId', 'content', 'position'],
|
|
342
|
+
additionalProperties: false,
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
name: 'remnote_replace_children',
|
|
347
|
+
description:
|
|
348
|
+
'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.',
|
|
349
|
+
inputSchema: {
|
|
350
|
+
type: 'object',
|
|
351
|
+
properties: {
|
|
352
|
+
parentRemId: {
|
|
353
|
+
type: 'string',
|
|
354
|
+
description: 'Parent Rem ID whose direct children will be replaced',
|
|
355
|
+
},
|
|
356
|
+
content: {
|
|
357
|
+
type: 'string',
|
|
358
|
+
description:
|
|
359
|
+
'Markdown content to use as replacement children; empty string clears all direct children',
|
|
360
|
+
},
|
|
361
|
+
},
|
|
362
|
+
required: ['parentRemId', 'content'],
|
|
363
|
+
additionalProperties: false,
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
name: 'remnote_update_tags',
|
|
368
|
+
description:
|
|
369
|
+
'Add or remove tags from a note by exact tag Rem IDs. Use this for production tagging workflows to avoid ambiguous name lookup.',
|
|
370
|
+
inputSchema: {
|
|
371
|
+
type: 'object',
|
|
372
|
+
properties: {
|
|
373
|
+
remId: {
|
|
374
|
+
type: 'string',
|
|
375
|
+
description: 'The Rem ID whose tags should change',
|
|
376
|
+
},
|
|
377
|
+
addTagRemIds: {
|
|
378
|
+
type: 'array',
|
|
379
|
+
items: {
|
|
380
|
+
type: 'string',
|
|
381
|
+
},
|
|
382
|
+
minItems: 1,
|
|
383
|
+
description: 'Exact tag Rem IDs to add',
|
|
384
|
+
},
|
|
385
|
+
removeTagRemIds: {
|
|
386
|
+
type: 'array',
|
|
387
|
+
items: {
|
|
388
|
+
type: 'string',
|
|
389
|
+
},
|
|
390
|
+
minItems: 1,
|
|
391
|
+
description: 'Exact tag Rem IDs to remove',
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
required: ['remId'],
|
|
395
|
+
additionalProperties: false,
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
name: 'remnote_append_journal',
|
|
400
|
+
description:
|
|
401
|
+
"Append content to today's daily document in RemNote with optional exact tag Rem IDs. Recommended preflight once per session: remnote_status.",
|
|
402
|
+
inputSchema: {
|
|
403
|
+
type: 'object',
|
|
404
|
+
properties: {
|
|
405
|
+
content: {
|
|
406
|
+
type: 'string',
|
|
407
|
+
description: "Content to append to today's daily document (markdown supported)",
|
|
408
|
+
},
|
|
409
|
+
timestamp: {
|
|
410
|
+
type: 'boolean',
|
|
411
|
+
description: 'Include timestamp (default: true)',
|
|
412
|
+
},
|
|
413
|
+
tagRemIds: {
|
|
414
|
+
type: 'array',
|
|
415
|
+
items: {
|
|
416
|
+
type: 'string',
|
|
417
|
+
},
|
|
418
|
+
description: 'Exact tag Rem IDs to apply',
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
required: ['content'],
|
|
422
|
+
additionalProperties: false,
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
name: 'remnote_get_playbook',
|
|
427
|
+
description:
|
|
428
|
+
'Get an operations playbook for MCP agents: status-first recommendation, navigation presets, content-mode guidance, and write-safety decision tree.',
|
|
429
|
+
inputSchema: {
|
|
430
|
+
type: 'object',
|
|
431
|
+
properties: {},
|
|
432
|
+
},
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
name: 'remnote_status',
|
|
436
|
+
description:
|
|
437
|
+
'Check bridge connection health, compatibility warnings, and write-policy capabilities. Recommended once per session before write operations.',
|
|
438
|
+
inputSchema: {
|
|
439
|
+
type: 'object',
|
|
440
|
+
properties: {},
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
name: 'remnote_read_table',
|
|
445
|
+
description:
|
|
446
|
+
'Read an Advanced Table from RemNote by exact title or Rem ID. Returns the table schema (columns with property types) and row data (cell values). Use this when you need structured tabular data. For simple tag-based queries without table structure, prefer remnote_search_by_tag.',
|
|
447
|
+
inputSchema: {
|
|
448
|
+
type: 'object',
|
|
449
|
+
properties: {
|
|
450
|
+
tableRemId: {
|
|
451
|
+
type: 'string',
|
|
452
|
+
description: 'Table Rem ID',
|
|
453
|
+
},
|
|
454
|
+
tableTitle: {
|
|
455
|
+
type: 'string',
|
|
456
|
+
description: 'Exact Advanced Table title',
|
|
457
|
+
},
|
|
458
|
+
limit: {
|
|
459
|
+
type: 'number',
|
|
460
|
+
description: 'Maximum rows to return (1-150, default: 50)',
|
|
461
|
+
},
|
|
462
|
+
offset: {
|
|
463
|
+
type: 'number',
|
|
464
|
+
description: '0-based row offset for pagination (default: 0)',
|
|
465
|
+
},
|
|
466
|
+
propertyFilter: {
|
|
467
|
+
type: 'array',
|
|
468
|
+
items: {
|
|
469
|
+
type: 'string',
|
|
470
|
+
},
|
|
471
|
+
description: 'Only return these property/column names (all if omitted)',
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
description: 'Provide exactly one of tableRemId or tableTitle.',
|
|
475
|
+
},
|
|
476
|
+
},
|
|
477
|
+
];
|
|
@@ -2,143 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
import process from 'node:process';
|
|
4
4
|
import { realpathSync } from 'node:fs';
|
|
5
|
+
import { createRequire } from 'node:module';
|
|
5
6
|
import { fileURLToPath, URL, pathToFileURL } from 'node:url';
|
|
6
7
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
7
8
|
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
8
9
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
9
10
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
10
11
|
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
12
|
+
import { FALLBACK_TOOLS } from './fallback-tools.generated.js';
|
|
11
13
|
|
|
12
|
-
export
|
|
13
|
-
export const SERVER_INFO = { name: 'remnote-mcp-stdio', version: '0.14.1' };
|
|
14
|
+
export { FALLBACK_TOOLS } from './fallback-tools.generated.js';
|
|
14
15
|
|
|
15
|
-
export const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
'Create a new note in RemNote with optional content, parent, and tags. Supports hierarchical markdown in content and flashcard syntax.',
|
|
20
|
-
inputSchema: {
|
|
21
|
-
type: 'object',
|
|
22
|
-
properties: {
|
|
23
|
-
title: { type: 'string', description: 'The title of the note' },
|
|
24
|
-
content: { type: 'string', description: 'Content as plain text or hierarchical markdown' },
|
|
25
|
-
parentId: { type: 'string', description: 'Parent Rem ID' },
|
|
26
|
-
tags: { type: 'array', items: { type: 'string' }, description: 'Tags to apply' },
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
name: 'remnote_search',
|
|
32
|
-
description: 'Search the RemNote knowledge base.',
|
|
33
|
-
inputSchema: {
|
|
34
|
-
type: 'object',
|
|
35
|
-
properties: {
|
|
36
|
-
query: { type: 'string', description: 'Search query text' },
|
|
37
|
-
limit: { type: 'number', description: 'Maximum results' },
|
|
38
|
-
includeContent: { type: 'string', enum: ['none', 'markdown', 'structured'] },
|
|
39
|
-
depth: { type: 'number', description: 'Depth of child hierarchy to render' },
|
|
40
|
-
childLimit: { type: 'number', description: 'Maximum children per level' },
|
|
41
|
-
maxContentLength: { type: 'number', description: 'Maximum rendered content length' },
|
|
42
|
-
},
|
|
43
|
-
required: ['query'],
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
name: 'remnote_search_by_tag',
|
|
48
|
-
description: 'Find notes by tag.',
|
|
49
|
-
inputSchema: {
|
|
50
|
-
type: 'object',
|
|
51
|
-
properties: {
|
|
52
|
-
tag: { type: 'string', description: 'Tag name to search' },
|
|
53
|
-
limit: { type: 'number', description: 'Maximum results' },
|
|
54
|
-
includeContent: { type: 'string', enum: ['none', 'markdown', 'structured'] },
|
|
55
|
-
depth: { type: 'number', description: 'Depth of child hierarchy to render' },
|
|
56
|
-
childLimit: { type: 'number', description: 'Maximum children per level' },
|
|
57
|
-
maxContentLength: { type: 'number', description: 'Maximum rendered content length' },
|
|
58
|
-
},
|
|
59
|
-
required: ['tag'],
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
name: 'remnote_read_note',
|
|
64
|
-
description: 'Read a specific note from RemNote by its Rem ID.',
|
|
65
|
-
inputSchema: {
|
|
66
|
-
type: 'object',
|
|
67
|
-
properties: {
|
|
68
|
-
remId: { type: 'string', description: 'The Rem ID to read' },
|
|
69
|
-
depth: { type: 'number', description: 'Depth of child hierarchy to render' },
|
|
70
|
-
includeContent: { type: 'string', enum: ['none', 'markdown', 'structured'] },
|
|
71
|
-
childLimit: { type: 'number', description: 'Maximum children per level' },
|
|
72
|
-
maxContentLength: { type: 'number', description: 'Maximum rendered content length' },
|
|
73
|
-
},
|
|
74
|
-
required: ['remId'],
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
name: 'remnote_update_note',
|
|
79
|
-
description: 'Update an existing note in RemNote.',
|
|
80
|
-
inputSchema: {
|
|
81
|
-
type: 'object',
|
|
82
|
-
properties: {
|
|
83
|
-
remId: { type: 'string', description: 'The Rem ID to update' },
|
|
84
|
-
title: { type: 'string', description: 'New title' },
|
|
85
|
-
appendContent: { type: 'string', description: 'Content to append as children' },
|
|
86
|
-
replaceContent: { type: 'string', description: 'Content to replace direct children' },
|
|
87
|
-
addTags: { type: 'array', items: { type: 'string' }, description: 'Tags to add' },
|
|
88
|
-
removeTags: { type: 'array', items: { type: 'string' }, description: 'Tags to remove' },
|
|
89
|
-
},
|
|
90
|
-
required: ['remId'],
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
name: 'remnote_append_journal',
|
|
95
|
-
description: "Append content to today's daily document in RemNote.",
|
|
96
|
-
inputSchema: {
|
|
97
|
-
type: 'object',
|
|
98
|
-
properties: {
|
|
99
|
-
content: { type: 'string', description: "Content to append to today's daily document" },
|
|
100
|
-
timestamp: { type: 'boolean', description: 'Include timestamp' },
|
|
101
|
-
},
|
|
102
|
-
required: ['content'],
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
name: 'remnote_read_table',
|
|
107
|
-
description: 'Read an Advanced Table from RemNote by exact title or Rem ID.',
|
|
108
|
-
inputSchema: {
|
|
109
|
-
type: 'object',
|
|
110
|
-
properties: {
|
|
111
|
-
tableRemId: { type: 'string', description: 'Table Rem ID' },
|
|
112
|
-
tableTitle: { type: 'string', description: 'Exact Advanced Table title' },
|
|
113
|
-
limit: { type: 'number', description: 'Maximum rows to return' },
|
|
114
|
-
offset: { type: 'number', description: '0-based row offset for pagination' },
|
|
115
|
-
propertyFilter: {
|
|
116
|
-
type: 'array',
|
|
117
|
-
items: { type: 'string' },
|
|
118
|
-
description: 'Only return these property/column names',
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
name: 'remnote_get_playbook',
|
|
125
|
-
description: 'Get an operations playbook for MCP agents.',
|
|
126
|
-
inputSchema: { type: 'object', properties: {} },
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
name: 'remnote_status',
|
|
130
|
-
description:
|
|
131
|
-
'Check bridge connection health, compatibility warnings, and write-policy capabilities.',
|
|
132
|
-
inputSchema: { type: 'object', properties: {} },
|
|
133
|
-
},
|
|
134
|
-
];
|
|
16
|
+
export const DEFAULT_MCP_URL = 'http://127.0.0.1:3001/mcp';
|
|
17
|
+
const require = createRequire(import.meta.url);
|
|
18
|
+
const packageJson = require('../package.json');
|
|
19
|
+
export const SERVER_INFO = { name: 'remnote-mcp-stdio', version: packageJson.version };
|
|
135
20
|
|
|
136
21
|
export function normalizeMcpUrl(value) {
|
|
137
|
-
const trimmed = String(value || DEFAULT_MCP_URL)
|
|
22
|
+
const trimmed = String(value || DEFAULT_MCP_URL)
|
|
23
|
+
.trim()
|
|
24
|
+
.replace(/\/+$/, '');
|
|
138
25
|
if (trimmed.endsWith('/mcp')) {
|
|
139
26
|
return trimmed;
|
|
140
27
|
}
|
|
141
|
-
return `${trimmed
|
|
28
|
+
return `${trimmed}/mcp`;
|
|
142
29
|
}
|
|
143
30
|
|
|
144
31
|
export function createSdkHttpClient(mcpUrl, clientInfo = SERVER_INFO) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remnote-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "MCP server bridge for RemNote knowledge base",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
"remnote-mcp-stdio": "mcpb/remnote-local/server/index.js"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build": "tsc && node scripts/chmod-bins.mjs && node scripts/build-mcpb.mjs",
|
|
14
|
-
"build:mcpb": "node scripts/build-mcpb.mjs",
|
|
13
|
+
"build": "tsc && node scripts/chmod-bins.mjs && node scripts/generate-mcpb-tools.mjs && node scripts/build-mcpb.mjs",
|
|
14
|
+
"build:mcpb": "npm run generate:mcpb-tools && node scripts/build-mcpb.mjs",
|
|
15
|
+
"generate:mcpb-tools": "tsc && node scripts/generate-mcpb-tools.mjs",
|
|
16
|
+
"check:mcpb-tools": "tsc && node scripts/generate-mcpb-tools.mjs --check",
|
|
15
17
|
"dev": "tsx watch src/index.ts",
|
|
16
18
|
"start": "node dist/index.js",
|
|
17
19
|
"typecheck": "tsc --noEmit",
|