neuro-vault-mcp 3.2.1 → 3.3.1
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 +39 -23
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -14275,7 +14275,7 @@ function unwrap(schema) {
|
|
|
14275
14275
|
function isPlainObject2(value) {
|
|
14276
14276
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14277
14277
|
}
|
|
14278
|
-
function
|
|
14278
|
+
function coerceFieldValue(schema, value) {
|
|
14279
14279
|
if (value === null || value === void 0) return value;
|
|
14280
14280
|
const inner = unwrap(schema);
|
|
14281
14281
|
if (inner instanceof external_exports.ZodNumber) {
|
|
@@ -14303,18 +14303,26 @@ function coerceField(schema, value) {
|
|
|
14303
14303
|
}
|
|
14304
14304
|
return value;
|
|
14305
14305
|
}
|
|
14306
|
-
function
|
|
14307
|
-
|
|
14308
|
-
|
|
14309
|
-
|
|
14310
|
-
|
|
14311
|
-
|
|
14312
|
-
|
|
14313
|
-
|
|
14314
|
-
out[key] = coerceField(shape[key], out[key]);
|
|
14315
|
-
}
|
|
14306
|
+
function wrapField(field) {
|
|
14307
|
+
let inner = field;
|
|
14308
|
+
let isOptional = false;
|
|
14309
|
+
while (inner instanceof external_exports.ZodOptional || inner instanceof external_exports.ZodNullable || inner instanceof external_exports.ZodDefault) {
|
|
14310
|
+
if (inner instanceof external_exports.ZodOptional) isOptional = true;
|
|
14311
|
+
const next = inner.unwrap();
|
|
14312
|
+
if (!next) break;
|
|
14313
|
+
inner = next;
|
|
14316
14314
|
}
|
|
14317
|
-
|
|
14315
|
+
const wrapped = external_exports.preprocess((v) => coerceFieldValue(inner, v), inner);
|
|
14316
|
+
return isOptional ? wrapped.optional() : wrapped;
|
|
14317
|
+
}
|
|
14318
|
+
function wrapSchemaWithCoercion(schema) {
|
|
14319
|
+
if (!(schema instanceof external_exports.ZodObject)) return schema;
|
|
14320
|
+
const shape = schema.shape;
|
|
14321
|
+
const newShape = {};
|
|
14322
|
+
for (const [key, field] of Object.entries(shape)) {
|
|
14323
|
+
newShape[key] = wrapField(field);
|
|
14324
|
+
}
|
|
14325
|
+
return external_exports.object(newShape);
|
|
14318
14326
|
}
|
|
14319
14327
|
|
|
14320
14328
|
// src/lib/tool-response.ts
|
|
@@ -14385,18 +14393,18 @@ function formatZodError(error48) {
|
|
|
14385
14393
|
return { message, issues };
|
|
14386
14394
|
}
|
|
14387
14395
|
function registerTool(tool) {
|
|
14396
|
+
const coercingSchema = wrapSchemaWithCoercion(tool.inputSchema);
|
|
14388
14397
|
return {
|
|
14389
14398
|
name: tool.name,
|
|
14390
14399
|
spec: {
|
|
14391
14400
|
...tool.title !== void 0 ? { title: tool.title } : {},
|
|
14392
14401
|
description: tool.description,
|
|
14393
|
-
inputSchema:
|
|
14402
|
+
inputSchema: coercingSchema,
|
|
14394
14403
|
...tool.outputSchema !== void 0 ? { outputSchema: tool.outputSchema } : {},
|
|
14395
14404
|
...tool.annotations !== void 0 ? { annotations: tool.annotations } : {}
|
|
14396
14405
|
},
|
|
14397
14406
|
handler: async (args) => invokeTool(async () => {
|
|
14398
|
-
const
|
|
14399
|
-
const result = tool.inputSchema.safeParse(coerced);
|
|
14407
|
+
const result = coercingSchema.safeParse(args);
|
|
14400
14408
|
if (!result.success) {
|
|
14401
14409
|
const { message, issues } = formatZodError(result.error);
|
|
14402
14410
|
throw new ToolHandlerError("INVALID_PARAMS", message, { details: { issues } });
|
|
@@ -15368,10 +15376,18 @@ function normalizePath(raw) {
|
|
|
15368
15376
|
var VALID_FIELDS = ["frontmatter", "content"];
|
|
15369
15377
|
var DEFAULT_FIELDS = ["frontmatter", "content"];
|
|
15370
15378
|
function validateReadNotesInput(input) {
|
|
15371
|
-
|
|
15372
|
-
|
|
15379
|
+
let paths;
|
|
15380
|
+
if (typeof input.paths === "string") {
|
|
15381
|
+
if (input.paths === "") {
|
|
15382
|
+
throw invalidArgument("paths must not be empty", "paths");
|
|
15383
|
+
}
|
|
15384
|
+
paths = [input.paths];
|
|
15385
|
+
} else if (Array.isArray(input.paths)) {
|
|
15386
|
+
paths = input.paths;
|
|
15387
|
+
} else {
|
|
15388
|
+
throw invalidArgument("paths must be a string or an array of strings", "paths");
|
|
15373
15389
|
}
|
|
15374
|
-
if (
|
|
15390
|
+
if (paths.length < 1 || paths.length > 50) {
|
|
15375
15391
|
throw invalidArgument("paths must contain between 1 and 50 entries", "paths");
|
|
15376
15392
|
}
|
|
15377
15393
|
let fields;
|
|
@@ -15391,7 +15407,7 @@ function validateReadNotesInput(input) {
|
|
|
15391
15407
|
}
|
|
15392
15408
|
fields = input.fields;
|
|
15393
15409
|
}
|
|
15394
|
-
return { paths
|
|
15410
|
+
return { paths, fields };
|
|
15395
15411
|
}
|
|
15396
15412
|
|
|
15397
15413
|
// src/modules/operations/tools/append-daily.ts
|
|
@@ -15901,7 +15917,7 @@ function buildReadDailyTool(deps) {
|
|
|
15901
15917
|
// src/modules/operations/tools/read-notes.ts
|
|
15902
15918
|
var readNotesFieldSchema = external_exports.enum(["frontmatter", "content"]);
|
|
15903
15919
|
var inputSchema12 = external_exports.object({
|
|
15904
|
-
paths: external_exports.array(external_exports.string()).min(1).max(50),
|
|
15920
|
+
paths: external_exports.union([external_exports.string().min(1), external_exports.array(external_exports.string()).min(1).max(50)]),
|
|
15905
15921
|
fields: external_exports.array(readNotesFieldSchema).min(1).optional()
|
|
15906
15922
|
});
|
|
15907
15923
|
function buildReadNotesTool(deps) {
|
|
@@ -15909,7 +15925,7 @@ function buildReadNotesTool(deps) {
|
|
|
15909
15925
|
return {
|
|
15910
15926
|
name: "read_notes",
|
|
15911
15927
|
title: "Read Notes",
|
|
15912
|
-
description: "Read
|
|
15928
|
+
description: "Read one or more notes in one call. `paths` is a vault-relative POSIX path string or an array of 1\u201350 such paths; duplicates are de-duplicated and results returned in input order. `fields` projects which parts of each note to return \u2014 choose from `frontmatter` and `content`; default `['frontmatter','content']`. One missing or unreadable path does not fail the others \u2014 per-item errors come back inline. A single MCP roundtrip with parallel disk reads. Reads are direct from disk and do not require Obsidian to be running.",
|
|
15913
15929
|
inputSchema: inputSchema12,
|
|
15914
15930
|
handler: async (input) => {
|
|
15915
15931
|
const { paths, fields } = validateReadNotesInput(input);
|
|
@@ -16084,7 +16100,7 @@ When operating directly inside the vault itself (not from an external project th
|
|
|
16084
16100
|
### Notes (body)
|
|
16085
16101
|
|
|
16086
16102
|
Use \`read_notes\`, \`create_note\`, \`edit_note\`, \`read_daily\`, \`append_daily\` when the user asks to:
|
|
16087
|
-
- Read one or more notes by path (\`read_notes\` \u2014 accepts an array of 1\u201350
|
|
16103
|
+
- Read one or more notes by path (\`read_notes\` \u2014 accepts a single vault-relative POSIX path string or an array of 1\u201350 such paths; prefer this over multiple sequential reads)
|
|
16088
16104
|
- Create a new note, task, or idea (\`create_note\`)
|
|
16089
16105
|
- Add content to an existing note (\`edit_note\`)
|
|
16090
16106
|
- Read or update today's daily note (\`read_daily\` / \`append_daily\`)
|
|
@@ -16136,7 +16152,7 @@ Use \`search_notes\` when the user is recalling a topic fuzzily, asking a concep
|
|
|
16136
16152
|
|
|
16137
16153
|
## Routing between operations and semantic
|
|
16138
16154
|
|
|
16139
|
-
If the user gives an exact anchor (note path, daily note, tag, frontmatter field), prefer operations tools. If the user is recalling fuzzily or asking a conceptual question, prefer \`search_notes\`. After semantic search finds a relevant note, you can read it with \`read_notes\` (passing the path
|
|
16155
|
+
If the user gives an exact anchor (note path, daily note, tag, frontmatter field), prefer operations tools. If the user is recalling fuzzily or asking a conceptual question, prefer \`search_notes\`. After semantic search finds a relevant note, you can read it with \`read_notes\` (passing the path as a single string, or batching with sibling paths in an array) to see the details.
|
|
16140
16156
|
|
|
16141
16157
|
For tag-driven questions ("which notes are tagged X?", "show me everything in #ai") use \`query_notes\` with \`{ filter: { tags: '<name>' } }\`, not \`search_notes\` \u2014 the answer is exact, not fuzzy.
|
|
16142
16158
|
`;
|