virlow-mcp 3.14.7 → 3.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/dist/cli.js +12 -7
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -793,9 +793,7 @@ async function createEmbedder(opts = {}) {
|
|
|
793
793
|
import { parse as parseYaml } from "yaml";
|
|
794
794
|
var KEY_ORDER = ["source", "tags", "confidence", "created"];
|
|
795
795
|
var FENCE = "---";
|
|
796
|
-
|
|
797
|
-
return JSON.stringify({ language: "markdown", code: body, lastExecution: null });
|
|
798
|
-
}
|
|
796
|
+
var MEMORY_NOTE_TYPE = "memory";
|
|
799
797
|
function unwrapEnvelope(content) {
|
|
800
798
|
try {
|
|
801
799
|
const parsed = JSON.parse(content);
|
|
@@ -1199,7 +1197,7 @@ var MemoryStore = class {
|
|
|
1199
1197
|
/** Create or update a memory note, encrypting through the note field
|
|
1200
1198
|
* helpers. `noteId === null` creates. */
|
|
1201
1199
|
async writeNote(key, noteId, label, text, meta, folderId) {
|
|
1202
|
-
const body =
|
|
1200
|
+
const body = serializeMemoryBody(text, meta);
|
|
1203
1201
|
const salt = bytesToBase64(crypto.getRandomValues(new Uint8Array(32)));
|
|
1204
1202
|
const { encryptedTitle, encryptedContent, iv } = await encryptNoteFields(key, label, body);
|
|
1205
1203
|
const write = {
|
|
@@ -1209,7 +1207,7 @@ var MemoryStore = class {
|
|
|
1209
1207
|
encryptedContent,
|
|
1210
1208
|
iv,
|
|
1211
1209
|
salt,
|
|
1212
|
-
type:
|
|
1210
|
+
type: MEMORY_NOTE_TYPE,
|
|
1213
1211
|
// Mirrored so the app can filter memories by tag. The frontmatter stays
|
|
1214
1212
|
// the source of truth; this column follows it on every write we make.
|
|
1215
1213
|
tags: meta.tags ?? []
|
|
@@ -1383,6 +1381,11 @@ function mapError(err) {
|
|
|
1383
1381
|
return String(err);
|
|
1384
1382
|
}
|
|
1385
1383
|
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.';
|
|
1384
|
+
function serverInstructions(memoriesEnabled) {
|
|
1385
|
+
const memory = "MEMORY: Virlow holds durable facts about this user, their preferences and their projects. At the start of a task, call search_memory with the topic of the task (and namespace set to the project, when there is one) before acting, so earlier decisions are honoured instead of rediscovered. When you learn something that will still be true next week and would be wasteful to work out again (a decision, a convention, a preference, a fact about the environment), call add_memory with a short label and the fact itself; do this without being asked. Do not store transient task state, secrets, or anything the user asked to keep out. Memories are ordinary encrypted notes the user can read and edit in the Virlow app. ";
|
|
1386
|
+
const notes = "NOTES: note content is HTML, never Markdown; wrap paragraphs in <p>. Never use em-dashes. If a tool reports the vault is locked, call unlock, tell the user to finish in the browser, and confirm with status before retrying.";
|
|
1387
|
+
return (memoriesEnabled ? memory : "") + notes;
|
|
1388
|
+
}
|
|
1386
1389
|
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.";
|
|
1387
1390
|
function wrap(fn) {
|
|
1388
1391
|
return async (...args) => {
|
|
@@ -1427,7 +1430,9 @@ function createServices(opts) {
|
|
|
1427
1430
|
}
|
|
1428
1431
|
function buildServer(opts) {
|
|
1429
1432
|
const { api, vault, memoryStore, notesService } = opts.services ?? createServices(opts);
|
|
1430
|
-
const server = new McpServer(opts.serverInfo
|
|
1433
|
+
const server = new McpServer(opts.serverInfo, {
|
|
1434
|
+
instructions: serverInstructions(opts.memoriesEnabled !== false)
|
|
1435
|
+
});
|
|
1431
1436
|
server.registerTool("unlock", { description: opts.unlock.description }, wrap(async () => textResult(await opts.unlock.begin({ api, vault, memoryStore, notesService }))));
|
|
1432
1437
|
server.registerTool("lock", {
|
|
1433
1438
|
description: "Immediately lock the vault, discarding the in-memory decryption key and clearing all cached memories and notes. Use this when the user is done with a session or asks to lock explicitly. Safe to call even if already locked."
|
|
@@ -1979,7 +1984,7 @@ function startUnlockServer(api, vault, opts = {}) {
|
|
|
1979
1984
|
}
|
|
1980
1985
|
|
|
1981
1986
|
// src/version.ts
|
|
1982
|
-
var VERSION = true ? "3.
|
|
1987
|
+
var VERSION = true ? "3.16.0" : "dev";
|
|
1983
1988
|
|
|
1984
1989
|
// src/server.ts
|
|
1985
1990
|
function defaultEmbeddingCacheDir() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "virlow-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.16.0",
|
|
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-
|
|
38
|
-
"@batalabs/virlow-
|
|
39
|
-
"@batalabs/virlow-
|
|
37
|
+
"@batalabs/virlow-crypto": "3.16.0",
|
|
38
|
+
"@batalabs/virlow-memory": "3.16.0",
|
|
39
|
+
"@batalabs/virlow-mcp-core": "3.16.0"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "node build.mjs",
|