virlow-mcp 3.14.4 → 3.14.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +40 -8
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -103,8 +103,38 @@ var VirlowApi = class {
|
|
|
103
103
|
updateNote(id, body) {
|
|
104
104
|
return this.request("PUT", `/api/notes/${id}`, body);
|
|
105
105
|
}
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Every folder, not the first page of them.
|
|
108
|
+
*
|
|
109
|
+
* `GET /api/folders` is paginated and defaults to 20. This asked for it with
|
|
110
|
+
* no parameters and treated the answer as the whole set, so on an account
|
|
111
|
+
* with more folders than that the rest simply did not exist as far as this
|
|
112
|
+
* client was concerned.
|
|
113
|
+
*
|
|
114
|
+
* Nothing about that failed loudly. Folder exposure was computed from a
|
|
115
|
+
* partial list, so notes in later folders were invisible; and
|
|
116
|
+
* `resolveMemoryTree` could not find a Memories folder that was really
|
|
117
|
+
* there, tried to create one, and got a correct 409 "Memories folder already
|
|
118
|
+
* exists" — permanently, on every memory tool call, for any account past one
|
|
119
|
+
* page of folders. The recovery path re-listed and found nothing, because
|
|
120
|
+
* re-listing had the same blind spot.
|
|
121
|
+
*
|
|
122
|
+
* 50 is the API's maximum page size, so this is the fewest round trips
|
|
123
|
+
* available. `pages` comes from the response rather than being inferred from
|
|
124
|
+
* a short page: a server that clamps the limit would otherwise stop this
|
|
125
|
+
* after one request with no sign anything was missing.
|
|
126
|
+
*/
|
|
127
|
+
async listFolders() {
|
|
128
|
+
const PAGE_SIZE = 50;
|
|
129
|
+
const folders = [];
|
|
130
|
+
for (let page = 1; ; page += 1) {
|
|
131
|
+
const result = await this.request("GET", `/api/folders?page=${page}&limit=${PAGE_SIZE}`);
|
|
132
|
+
folders.push(...result.folders);
|
|
133
|
+
const pages = result.pagination?.pages ?? 1;
|
|
134
|
+
if (page >= pages || result.folders.length === 0)
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
return { folders };
|
|
108
138
|
}
|
|
109
139
|
createFolder(name, parentId, kind) {
|
|
110
140
|
const body = {
|
|
@@ -1326,6 +1356,8 @@ function mapError(err) {
|
|
|
1326
1356
|
return err.message;
|
|
1327
1357
|
return String(err);
|
|
1328
1358
|
}
|
|
1359
|
+
var CONTENT_FORMAT = 'CONTENT FORMAT: content is HTML, not Markdown. Virlow renders it in a rich-text editor, so Markdown syntax is stored and displayed literally \u2014 "# Heading" appears as those characters, not as a heading. Use <h1>-<h4>, <p>, <strong>, <em>, <u>, <s>, <mark>, <ul>/<ol>/<li>, <blockquote>, <pre><code>, <a href>, <hr>, <img src>, and <table>/<tr>/<th>/<td>. Task lists are <ul data-type="taskList"> with <li data-checked="true|false">. Wrap every paragraph in <p>; a bare newline is not a paragraph break. STYLE: never use em-dashes (\u2014). Use a comma, a colon, or two sentences.';
|
|
1360
|
+
var HTML_FIELD_HINT = "Note body as HTML (not Markdown). Paragraphs in <p>, headings in <h1>-<h4>. See the tool description for the full tag list.";
|
|
1329
1361
|
function wrap(fn) {
|
|
1330
1362
|
return async (...args) => {
|
|
1331
1363
|
try {
|
|
@@ -1535,7 +1567,7 @@ page ${pagination.page} of ${pagination.pages} (${pagination.total} total)` + fi
|
|
|
1535
1567
|
return textResult(body + notice);
|
|
1536
1568
|
}));
|
|
1537
1569
|
server.registerTool("read_note", {
|
|
1538
|
-
description: "Read the full title and content of a note by id. Requires the vault to be unlocked.",
|
|
1570
|
+
description: "Read the full title and content of a note by id. Requires the vault to be unlocked. Content comes back as the HTML the editor stores \u2014 write it back in the same form.",
|
|
1539
1571
|
inputSchema: {
|
|
1540
1572
|
id: z.string().min(1)
|
|
1541
1573
|
}
|
|
@@ -1546,10 +1578,10 @@ page ${pagination.page} of ${pagination.pages} (${pagination.total} total)` + fi
|
|
|
1546
1578
|
${note.content}`);
|
|
1547
1579
|
}));
|
|
1548
1580
|
server.registerTool("create_note", {
|
|
1549
|
-
description: "Create a new note with a title and content, optionally placed in a folder. Requires the vault to be unlocked
|
|
1581
|
+
description: "Create a new note with a title and content, optionally placed in a folder. Requires the vault to be unlocked.\n\n" + CONTENT_FORMAT,
|
|
1550
1582
|
inputSchema: {
|
|
1551
1583
|
title: z.string().min(1).max(200),
|
|
1552
|
-
content: z.string().max(5e4).optional(),
|
|
1584
|
+
content: z.string().max(5e4).optional().describe(HTML_FIELD_HINT),
|
|
1553
1585
|
folderId: z.string().optional(),
|
|
1554
1586
|
type: z.string().max(50).optional()
|
|
1555
1587
|
}
|
|
@@ -1558,11 +1590,11 @@ ${note.content}`);
|
|
|
1558
1590
|
return textResult(`created note ${note.id}`);
|
|
1559
1591
|
}));
|
|
1560
1592
|
server.registerTool("update_note", {
|
|
1561
|
-
description: "Update the title and/or content of an existing note by id. Only the provided fields are changed. Requires the vault to be unlocked
|
|
1593
|
+
description: "Update the title and/or content of an existing note by id. Only the provided fields are changed. Content replaces the note body entirely \u2014 read the note first if you mean to add to it. Requires the vault to be unlocked.\n\n" + CONTENT_FORMAT,
|
|
1562
1594
|
inputSchema: {
|
|
1563
1595
|
id: z.string().min(1),
|
|
1564
1596
|
title: z.string().min(1).max(200).optional(),
|
|
1565
|
-
content: z.string().max(5e4).optional()
|
|
1597
|
+
content: z.string().max(5e4).optional().describe(HTML_FIELD_HINT)
|
|
1566
1598
|
}
|
|
1567
1599
|
}, wrap(async (args) => {
|
|
1568
1600
|
await notesService.updateNote(args.id, { title: args.title, content: args.content });
|
|
@@ -1921,7 +1953,7 @@ function startUnlockServer(api, vault, opts = {}) {
|
|
|
1921
1953
|
}
|
|
1922
1954
|
|
|
1923
1955
|
// src/version.ts
|
|
1924
|
-
var VERSION = true ? "3.14.
|
|
1956
|
+
var VERSION = true ? "3.14.6" : "dev";
|
|
1925
1957
|
|
|
1926
1958
|
// src/server.ts
|
|
1927
1959
|
function defaultEmbeddingCacheDir() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "virlow-mcp",
|
|
3
|
-
"version": "3.14.
|
|
3
|
+
"version": "3.14.6",
|
|
4
4
|
"description": "Local MCP server for Virlow Secure Notes: end-to-end-encrypted AI memories and notes for Cursor, Claude, Codex, and any MCP client.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"esbuild": "^0.25.0",
|
|
35
35
|
"typescript": "^5.8.0",
|
|
36
36
|
"vitest": "^3.0.0",
|
|
37
|
-
"@batalabs/virlow-crypto": "3.14.
|
|
38
|
-
"@batalabs/virlow-memory": "3.14.
|
|
39
|
-
"@batalabs/virlow-mcp-core": "3.14.
|
|
37
|
+
"@batalabs/virlow-crypto": "3.14.6",
|
|
38
|
+
"@batalabs/virlow-memory": "3.14.6",
|
|
39
|
+
"@batalabs/virlow-mcp-core": "3.14.6"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "node build.mjs",
|