obsidian-mcp-server 3.5.3 → 3.5.5
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/AGENTS.md +47 -6
- package/CLAUDE.md +47 -6
- package/Dockerfile +3 -2
- package/README.md +144 -100
- package/changelog/3.5.x/3.5.3.md +4 -3
- package/changelog/3.5.x/3.5.4.md +42 -0
- package/changelog/3.5.x/3.5.5.md +20 -0
- package/changelog/template.md +7 -7
- package/dist/config/server-config.d.ts +1 -1
- package/dist/config/server-config.d.ts.map +1 -1
- package/dist/config/server-config.js +9 -2
- package/dist/config/server-config.js.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/resources/definitions/obsidian-vault-note.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/obsidian-vault-note.resource.js +19 -1
- package/dist/mcp-server/resources/definitions/obsidian-vault-note.resource.js.map +1 -1
- package/dist/mcp-server/tools/definitions/_shared/schemas.js +1 -1
- package/dist/mcp-server/tools/definitions/_shared/schemas.js.map +1 -1
- package/dist/mcp-server/tools/definitions/index.d.ts +157 -65
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts +13 -2
- package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js +14 -3
- package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts +9 -0
- package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.js +9 -0
- package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.d.ts +1 -0
- package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.js +1 -0
- package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.d.ts +9 -0
- package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.js +19 -26
- package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.d.ts +3 -0
- package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.js +3 -0
- package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts +13 -0
- package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.js +19 -1
- package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts +17 -2
- package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.js +22 -3
- package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.d.ts +4 -0
- package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.js +4 -0
- package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts +13 -2
- package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js +14 -3
- package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts +10 -2
- package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js +10 -2
- package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts +12 -5
- package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js +29 -24
- package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts +12 -2
- package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js +20 -10
- package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js.map +1 -1
- package/dist/services/obsidian/frontmatter-ops.d.ts +44 -11
- package/dist/services/obsidian/frontmatter-ops.d.ts.map +1 -1
- package/dist/services/obsidian/frontmatter-ops.js +370 -69
- package/dist/services/obsidian/frontmatter-ops.js.map +1 -1
- package/dist/services/obsidian/obsidian-service.d.ts +26 -5
- package/dist/services/obsidian/obsidian-service.d.ts.map +1 -1
- package/dist/services/obsidian/obsidian-service.js +469 -85
- package/dist/services/obsidian/obsidian-service.js.map +1 -1
- package/dist/services/obsidian/section-extractor.d.ts +33 -3
- package/dist/services/obsidian/section-extractor.d.ts.map +1 -1
- package/dist/services/obsidian/section-extractor.js +115 -75
- package/dist/services/obsidian/section-extractor.js.map +1 -1
- package/dist/services/obsidian/types.d.ts +11 -4
- package/dist/services/obsidian/types.d.ts.map +1 -1
- package/manifest.json +1 -1
- package/package.json +9 -9
- package/server.json +3 -3
|
@@ -107,36 +107,43 @@ export declare const readToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
|
|
|
107
107
|
readonly recovery: "Pass `section: { type, target }` (e.g. `{ type: \"heading\", target: \"Intro\" }`), or use `format: \"full\"` / `\"document-map\"` instead.";
|
|
108
108
|
}, {
|
|
109
109
|
readonly reason: "path_forbidden";
|
|
110
|
+
readonly thrownBy: "service";
|
|
110
111
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
111
112
|
readonly when: "The target path is outside OBSIDIAN_READ_PATHS (and OBSIDIAN_WRITE_PATHS, since write paths imply read access).";
|
|
112
113
|
readonly recovery: "Use a path inside the configured read scope. The error data echoes the active scope.";
|
|
113
114
|
}, {
|
|
114
115
|
readonly reason: "note_missing";
|
|
116
|
+
readonly thrownBy: "service";
|
|
115
117
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
116
118
|
readonly when: "The vault path does not resolve to an existing note.";
|
|
117
119
|
readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
|
|
118
120
|
}, {
|
|
119
121
|
readonly reason: "ambiguous_path";
|
|
122
|
+
readonly thrownBy: "service";
|
|
120
123
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
|
|
121
124
|
readonly when: "The parent directory contains multiple files whose names differ only in case (case-sensitive filesystems only).";
|
|
122
125
|
readonly recovery: "Retry with one of the exact paths listed in `matches` on the error data.";
|
|
123
126
|
}, {
|
|
124
127
|
readonly reason: "no_active_file";
|
|
128
|
+
readonly thrownBy: "service";
|
|
125
129
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
126
130
|
readonly when: "Target was `active` but no file is currently open in Obsidian.";
|
|
127
131
|
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
|
|
128
132
|
}, {
|
|
129
133
|
readonly reason: "periodic_unsupported";
|
|
134
|
+
readonly thrownBy: "service";
|
|
130
135
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
131
136
|
readonly when: "Target was `periodic` and this vault runs Local REST API v5.0.2 or later without the companion periodic-notes extension, so the `/periodic/` routes are not served at all.";
|
|
132
137
|
readonly recovery: "Install the periodic-notes extension from https://github.com/coddingtonbear/obsidian-local-rest-api-periodic-notes, or address the note by an explicit vault path.";
|
|
133
138
|
}, {
|
|
134
139
|
readonly reason: "periodic_not_found";
|
|
140
|
+
readonly thrownBy: "service";
|
|
135
141
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
136
142
|
readonly when: "Target was `periodic`, the `/periodic/` routes are served on this vault, and no note exists for the requested period.";
|
|
137
143
|
readonly recovery: "Create the periodic note first or pass an explicit path target.";
|
|
138
144
|
}, {
|
|
139
145
|
readonly reason: "periodic_disabled";
|
|
146
|
+
readonly thrownBy: "service";
|
|
140
147
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
141
148
|
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
|
|
142
149
|
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
|
|
@@ -147,11 +154,13 @@ export declare const readToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
|
|
|
147
154
|
readonly recovery: "Call obsidian_get_note with format \"document-map\" to list available headings, blocks, and frontmatter fields, then retry with one of those locators.";
|
|
148
155
|
}, {
|
|
149
156
|
readonly reason: "path_is_directory";
|
|
157
|
+
readonly thrownBy: "service";
|
|
150
158
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
151
159
|
readonly when: "The supplied path names a folder rather than a note file.";
|
|
152
160
|
readonly recovery: "Call obsidian_list_notes with this path to list the folder, then retry with the full path of one of the files it returns.";
|
|
153
161
|
}, {
|
|
154
162
|
readonly reason: "path_traversal";
|
|
163
|
+
readonly thrownBy: "service";
|
|
155
164
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
156
165
|
readonly when: "The path contains a `.` or `..` segment, which is rejected to prevent vault escape.";
|
|
157
166
|
readonly recovery: "Supply a vault-relative path with no `.` or `..` segments, e.g. \"Projects/Note.md\". Use obsidian_list_notes to browse the vault.";
|
|
@@ -228,16 +237,19 @@ export declare const readToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
|
|
|
228
237
|
readonly recovery: "Avoid nested quantifiers like `(a+)+` or `(.*)*`. Use a simpler pattern (e.g. `^Project.*\\.md$`), or omit nameRegex to disable filtering.";
|
|
229
238
|
}, {
|
|
230
239
|
readonly reason: "path_forbidden";
|
|
240
|
+
readonly thrownBy: "service";
|
|
231
241
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
232
242
|
readonly when: "The supplied `path` is outside OBSIDIAN_READ_PATHS (root listings always pass; specific subdirectories must be readable).";
|
|
233
243
|
readonly recovery: "List a directory inside the configured read scope, or omit `path` to list from the vault root. The error data echoes the active scope.";
|
|
234
244
|
}, {
|
|
235
245
|
readonly reason: "directory_missing";
|
|
246
|
+
readonly thrownBy: "service";
|
|
236
247
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
237
248
|
readonly when: "No listable directory at the supplied `path` — either it does not exist, or it exists and currently holds no files. Sub-directories that disappear mid-walk are silently skipped, so only the root path surfaces this error.";
|
|
238
249
|
readonly recovery: "List the parent directory to check the spelling and casing. A folder that exists but holds no files reports the same way, since the Local REST API omits empty folders from its listings — add a file to it, or confirm from the parent that the folder is there.";
|
|
239
250
|
}, {
|
|
240
251
|
readonly reason: "path_is_file";
|
|
252
|
+
readonly thrownBy: "service";
|
|
241
253
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
242
254
|
readonly when: "The supplied `path` names a file rather than a directory.";
|
|
243
255
|
readonly recovery: "Read the file with obsidian_get_note instead, or list its parent directory to browse alongside it.";
|
|
@@ -253,6 +265,7 @@ export declare const readToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
|
|
|
253
265
|
createdIfMissing: import("zod").ZodBoolean;
|
|
254
266
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
255
267
|
readonly reason: "path_forbidden";
|
|
268
|
+
readonly thrownBy: "service";
|
|
256
269
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
257
270
|
readonly when: "The path is outside OBSIDIAN_READ_PATHS, or — when the file does not exist and `failIfMissing: false` would have Obsidian create it — outside OBSIDIAN_WRITE_PATHS or blocked by OBSIDIAN_READ_ONLY=true.";
|
|
258
271
|
readonly recovery: "Open a path inside the configured scope. The error data echoes the active scope and whether read or write access was the one denied.";
|
|
@@ -263,16 +276,19 @@ export declare const readToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
|
|
|
263
276
|
readonly recovery: "Verify the path with obsidian_list_notes or obsidian_search_notes first — a typo would otherwise materialize as an empty file. If creation is intended, retry with failIfMissing: false.";
|
|
264
277
|
}, {
|
|
265
278
|
readonly reason: "ambiguous_path";
|
|
279
|
+
readonly thrownBy: "service";
|
|
266
280
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
|
|
267
281
|
readonly when: "The parent directory contains multiple files whose names differ only in case (case-sensitive filesystems only).";
|
|
268
282
|
readonly recovery: "Retry with one of the exact paths listed in `matches` on the error data.";
|
|
269
283
|
}, {
|
|
270
284
|
readonly reason: "path_is_directory";
|
|
285
|
+
readonly thrownBy: "service";
|
|
271
286
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
272
287
|
readonly when: "The supplied path names a folder rather than a file.";
|
|
273
288
|
readonly recovery: "Call obsidian_list_notes with this path to list the folder, then open one of the files it returns.";
|
|
274
289
|
}, {
|
|
275
290
|
readonly reason: "path_traversal";
|
|
291
|
+
readonly thrownBy: "service";
|
|
276
292
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
277
293
|
readonly when: "The path contains a `.` or `..` segment, which is rejected to prevent vault escape.";
|
|
278
294
|
readonly recovery: "Supply a vault-relative path with no `.` or `..` segments, e.g. \"Projects/Note.md\". Use obsidian_list_notes to browse the vault.";
|
|
@@ -295,98 +311,90 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
295
311
|
}>;
|
|
296
312
|
date: import("zod").ZodOptional<import("zod").ZodString>;
|
|
297
313
|
}, import("zod/v4/core").$strip>], "type">;
|
|
298
|
-
|
|
314
|
+
content: import("zod").ZodString;
|
|
315
|
+
section: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
299
316
|
type: import("zod").ZodEnum<{
|
|
300
317
|
block: "block";
|
|
301
318
|
frontmatter: "frontmatter";
|
|
302
319
|
heading: "heading";
|
|
303
320
|
}>;
|
|
304
321
|
target: import("zod").ZodString;
|
|
305
|
-
}, import("zod/v4/core").$strip
|
|
306
|
-
operation: import("zod").ZodEnum<{
|
|
307
|
-
append: "append";
|
|
308
|
-
prepend: "prepend";
|
|
309
|
-
replace: "replace";
|
|
310
|
-
}>;
|
|
311
|
-
content: import("zod").ZodString;
|
|
322
|
+
}, import("zod/v4/core").$strip>>;
|
|
312
323
|
contentType: import("zod").ZodDefault<import("zod").ZodEnum<{
|
|
313
324
|
json: "json";
|
|
314
325
|
markdown: "markdown";
|
|
315
326
|
}>>;
|
|
316
|
-
|
|
317
|
-
createTargetIfMissing: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
318
|
-
applyIfContentPreexists: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
319
|
-
trimTargetWhitespace: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
320
|
-
}, import("zod/v4/core").$strip>>;
|
|
327
|
+
createTargetIfMissing: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
321
328
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
322
329
|
path: import("zod").ZodString;
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
frontmatter: "frontmatter";
|
|
327
|
-
heading: "heading";
|
|
328
|
-
}>;
|
|
329
|
-
target: import("zod").ZodString;
|
|
330
|
-
}, import("zod/v4/core").$strip>;
|
|
331
|
-
operation: import("zod").ZodEnum<{
|
|
332
|
-
append: "append";
|
|
333
|
-
prepend: "prepend";
|
|
334
|
-
replace: "replace";
|
|
335
|
-
}>;
|
|
330
|
+
sectionTargeted: import("zod").ZodBoolean;
|
|
331
|
+
sectionTarget: import("zod").ZodOptional<import("zod").ZodString>;
|
|
332
|
+
created: import("zod").ZodBoolean;
|
|
336
333
|
previousSizeInBytes: import("zod").ZodNumber;
|
|
337
334
|
currentSizeInBytes: import("zod").ZodNumber;
|
|
338
335
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
339
336
|
readonly reason: "path_forbidden";
|
|
337
|
+
readonly thrownBy: "service";
|
|
340
338
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
341
339
|
readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
|
|
342
340
|
readonly recovery: "Use a path inside the configured write scope. The error data echoes the active scope.";
|
|
343
341
|
}, {
|
|
344
342
|
readonly reason: "note_missing";
|
|
343
|
+
readonly thrownBy: "service";
|
|
345
344
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
346
|
-
readonly when: "
|
|
347
|
-
readonly recovery: "Verify the path with obsidian_list_notes or
|
|
345
|
+
readonly when: "Section append targets a path that does not resolve to an existing note (PATCH requires the file to exist).";
|
|
346
|
+
readonly recovery: "Verify the path with obsidian_list_notes, or omit `section` to fall back to whole-file append (which creates the note if missing).";
|
|
348
347
|
}, {
|
|
349
348
|
readonly reason: "no_active_file";
|
|
349
|
+
readonly thrownBy: "service";
|
|
350
350
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
351
351
|
readonly when: "Target was `active` but no file is currently open in Obsidian.";
|
|
352
352
|
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
|
|
353
353
|
}, {
|
|
354
354
|
readonly reason: "periodic_unsupported";
|
|
355
|
+
readonly thrownBy: "service";
|
|
355
356
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
356
357
|
readonly when: "Target was `periodic` and this vault runs Local REST API v5.0.2 or later without the companion periodic-notes extension, so the `/periodic/` routes are not served at all.";
|
|
357
358
|
readonly recovery: "Install the periodic-notes extension from https://github.com/coddingtonbear/obsidian-local-rest-api-periodic-notes, or address the note by an explicit vault path.";
|
|
358
359
|
}, {
|
|
359
360
|
readonly reason: "periodic_not_found";
|
|
361
|
+
readonly thrownBy: "service";
|
|
360
362
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
361
363
|
readonly when: "Target was `periodic`, the `/periodic/` routes are served on this vault, and no note exists for the requested period.";
|
|
362
364
|
readonly recovery: "Create the periodic note first or pass an explicit path target.";
|
|
363
365
|
}, {
|
|
364
366
|
readonly reason: "periodic_disabled";
|
|
367
|
+
readonly thrownBy: "service";
|
|
365
368
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
366
369
|
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
|
|
367
370
|
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
|
|
368
371
|
}, {
|
|
369
372
|
readonly reason: "section_target_missing";
|
|
373
|
+
readonly thrownBy: "service";
|
|
370
374
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
371
|
-
readonly when: "
|
|
372
|
-
readonly recovery: "Call obsidian_get_note with format document-map to discover
|
|
375
|
+
readonly when: "`section` was provided but the named heading/block/frontmatter field does not exist in the note.";
|
|
376
|
+
readonly recovery: "Call obsidian_get_note with format document-map to discover available targets, or pass createTargetIfMissing: true to bring it into existence.";
|
|
373
377
|
}, {
|
|
374
378
|
readonly reason: "ambiguous_section";
|
|
379
|
+
readonly thrownBy: "service";
|
|
375
380
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
|
|
376
|
-
readonly when: "A bare heading leaf name matches more than one heading in the note, so the
|
|
377
|
-
readonly recovery: "Retry with
|
|
381
|
+
readonly when: "A bare heading leaf name matches more than one heading in the note, or the resolved full heading path occurs more than once, so the append target is undetermined.";
|
|
382
|
+
readonly recovery: "Retry with a distinct full Parent::Child heading path from `candidates` on the error data; when every candidate is the same path, rename the repeated headings first.";
|
|
378
383
|
}, {
|
|
379
384
|
readonly reason: "content_preexists";
|
|
385
|
+
readonly thrownBy: "service";
|
|
380
386
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
381
|
-
readonly when: "
|
|
382
|
-
readonly recovery: "
|
|
387
|
+
readonly when: "Section append where the supplied content already appears at the target — rejected to keep retries idempotent (the default for the section path).";
|
|
388
|
+
readonly recovery: "Change the content to something not already present at the target, or use obsidian_patch_note with `patchOptions.applyIfContentPreexists: true` if a duplicate is intended.";
|
|
383
389
|
}, {
|
|
384
390
|
readonly reason: "path_is_directory";
|
|
391
|
+
readonly thrownBy: "service";
|
|
385
392
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
386
393
|
readonly when: "The supplied path names a folder rather than a note file.";
|
|
387
394
|
readonly recovery: "Call obsidian_list_notes with this path to list the folder, then retry with the full path of one of the files it returns.";
|
|
388
395
|
}, {
|
|
389
396
|
readonly reason: "path_traversal";
|
|
397
|
+
readonly thrownBy: "service";
|
|
390
398
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
391
399
|
readonly when: "The path contains a `.` or `..` segment, which is rejected to prevent vault escape.";
|
|
392
400
|
readonly recovery: "Supply a vault-relative path with no `.` or `..` segments, e.g. \"Projects/Note.md\". Use obsidian_list_notes to browse the vault.";
|
|
@@ -407,79 +415,109 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
407
415
|
}>;
|
|
408
416
|
date: import("zod").ZodOptional<import("zod").ZodString>;
|
|
409
417
|
}, import("zod/v4/core").$strip>], "type">;
|
|
410
|
-
|
|
411
|
-
section: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
418
|
+
section: import("zod").ZodObject<{
|
|
412
419
|
type: import("zod").ZodEnum<{
|
|
413
420
|
block: "block";
|
|
414
421
|
frontmatter: "frontmatter";
|
|
415
422
|
heading: "heading";
|
|
416
423
|
}>;
|
|
417
424
|
target: import("zod").ZodString;
|
|
418
|
-
}, import("zod/v4/core").$strip
|
|
425
|
+
}, import("zod/v4/core").$strip>;
|
|
426
|
+
operation: import("zod").ZodEnum<{
|
|
427
|
+
append: "append";
|
|
428
|
+
prepend: "prepend";
|
|
429
|
+
replace: "replace";
|
|
430
|
+
}>;
|
|
431
|
+
content: import("zod").ZodString;
|
|
419
432
|
contentType: import("zod").ZodDefault<import("zod").ZodEnum<{
|
|
420
433
|
json: "json";
|
|
421
434
|
markdown: "markdown";
|
|
422
435
|
}>>;
|
|
423
|
-
|
|
436
|
+
patchOptions: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
437
|
+
createTargetIfMissing: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
438
|
+
applyIfContentPreexists: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
439
|
+
trimTargetWhitespace: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
440
|
+
}, import("zod/v4/core").$strip>>;
|
|
424
441
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
425
442
|
path: import("zod").ZodString;
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
443
|
+
section: import("zod").ZodObject<{
|
|
444
|
+
type: import("zod").ZodEnum<{
|
|
445
|
+
block: "block";
|
|
446
|
+
frontmatter: "frontmatter";
|
|
447
|
+
heading: "heading";
|
|
448
|
+
}>;
|
|
449
|
+
target: import("zod").ZodString;
|
|
450
|
+
}, import("zod/v4/core").$strip>;
|
|
451
|
+
operation: import("zod").ZodEnum<{
|
|
452
|
+
append: "append";
|
|
453
|
+
prepend: "prepend";
|
|
454
|
+
replace: "replace";
|
|
455
|
+
}>;
|
|
429
456
|
previousSizeInBytes: import("zod").ZodNumber;
|
|
430
457
|
currentSizeInBytes: import("zod").ZodNumber;
|
|
431
458
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
432
|
-
readonly reason: "file_exists";
|
|
433
|
-
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
|
|
434
|
-
readonly when: "Whole-file write was attempted against an existing note and `overwrite` was not set to `true`.";
|
|
435
|
-
readonly recovery: "Retry with overwrite true or use obsidian_patch_note for in-place edits.";
|
|
436
|
-
}, {
|
|
437
459
|
readonly reason: "path_forbidden";
|
|
460
|
+
readonly thrownBy: "service";
|
|
438
461
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
439
462
|
readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
|
|
440
463
|
readonly recovery: "Use a path inside the configured write scope. The error data echoes the active scope.";
|
|
441
464
|
}, {
|
|
442
465
|
readonly reason: "note_missing";
|
|
466
|
+
readonly thrownBy: "service";
|
|
443
467
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
444
|
-
readonly when: "
|
|
445
|
-
readonly recovery: "Verify the path with obsidian_list_notes
|
|
468
|
+
readonly when: "The vault path does not resolve to an existing note.";
|
|
469
|
+
readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
|
|
446
470
|
}, {
|
|
447
471
|
readonly reason: "no_active_file";
|
|
472
|
+
readonly thrownBy: "service";
|
|
448
473
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
449
474
|
readonly when: "Target was `active` but no file is currently open in Obsidian.";
|
|
450
475
|
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
|
|
451
476
|
}, {
|
|
452
477
|
readonly reason: "periodic_unsupported";
|
|
478
|
+
readonly thrownBy: "service";
|
|
453
479
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
454
480
|
readonly when: "Target was `periodic` and this vault runs Local REST API v5.0.2 or later without the companion periodic-notes extension, so the `/periodic/` routes are not served at all.";
|
|
455
481
|
readonly recovery: "Install the periodic-notes extension from https://github.com/coddingtonbear/obsidian-local-rest-api-periodic-notes, or address the note by an explicit vault path.";
|
|
456
482
|
}, {
|
|
457
483
|
readonly reason: "periodic_not_found";
|
|
484
|
+
readonly thrownBy: "service";
|
|
458
485
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
459
486
|
readonly when: "Target was `periodic`, the `/periodic/` routes are served on this vault, and no note exists for the requested period.";
|
|
460
487
|
readonly recovery: "Create the periodic note first or pass an explicit path target.";
|
|
461
488
|
}, {
|
|
462
489
|
readonly reason: "periodic_disabled";
|
|
490
|
+
readonly thrownBy: "service";
|
|
463
491
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
464
492
|
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
|
|
465
493
|
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
|
|
466
494
|
}, {
|
|
467
495
|
readonly reason: "section_target_missing";
|
|
496
|
+
readonly thrownBy: "service";
|
|
468
497
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
469
|
-
readonly when: "
|
|
470
|
-
readonly recovery: "Call obsidian_get_note with format document-map to discover available targets.";
|
|
498
|
+
readonly when: "The named heading/block/frontmatter field does not exist in the note. Use `obsidian_get_note` with `format: \"document-map\"` to discover available targets.";
|
|
499
|
+
readonly recovery: "Call obsidian_get_note with format document-map to discover the available targets.";
|
|
471
500
|
}, {
|
|
472
501
|
readonly reason: "ambiguous_section";
|
|
502
|
+
readonly thrownBy: "service";
|
|
473
503
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
|
|
474
|
-
readonly when: "A bare heading leaf name matches more than one heading in the note, so the
|
|
475
|
-
readonly recovery: "Retry with
|
|
504
|
+
readonly when: "A bare heading leaf name matches more than one heading in the note, or the resolved full heading path occurs more than once, so the write target is undetermined.";
|
|
505
|
+
readonly recovery: "Retry with a distinct full Parent::Child heading path from `candidates` on the error data; when every candidate is the same path, rename the repeated headings first.";
|
|
506
|
+
}, {
|
|
507
|
+
readonly reason: "content_preexists";
|
|
508
|
+
readonly thrownBy: "service";
|
|
509
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
510
|
+
readonly when: "The supplied content already appears at the target — the patch was rejected to keep retries idempotent (the default).";
|
|
511
|
+
readonly recovery: "Pass `patchOptions.applyIfContentPreexists: true` to force-apply over preexisting content, or change the content to something not already present.";
|
|
476
512
|
}, {
|
|
477
513
|
readonly reason: "path_is_directory";
|
|
514
|
+
readonly thrownBy: "service";
|
|
478
515
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
479
516
|
readonly when: "The supplied path names a folder rather than a note file.";
|
|
480
517
|
readonly recovery: "Call obsidian_list_notes with this path to list the folder, then retry with the full path of one of the files it returns.";
|
|
481
518
|
}, {
|
|
482
519
|
readonly reason: "path_traversal";
|
|
520
|
+
readonly thrownBy: "service";
|
|
483
521
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
484
522
|
readonly when: "The path contains a `.` or `..` segment, which is rejected to prevent vault escape.";
|
|
485
523
|
readonly recovery: "Supply a vault-relative path with no `.` or `..` segments, e.g. \"Projects/Note.md\". Use obsidian_list_notes to browse the vault.";
|
|
@@ -513,7 +551,7 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
513
551
|
json: "json";
|
|
514
552
|
markdown: "markdown";
|
|
515
553
|
}>>;
|
|
516
|
-
|
|
554
|
+
overwrite: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
517
555
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
518
556
|
path: import("zod").ZodString;
|
|
519
557
|
sectionTargeted: import("zod").ZodBoolean;
|
|
@@ -522,57 +560,67 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
522
560
|
previousSizeInBytes: import("zod").ZodNumber;
|
|
523
561
|
currentSizeInBytes: import("zod").ZodNumber;
|
|
524
562
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
563
|
+
readonly reason: "file_exists";
|
|
564
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
|
|
565
|
+
readonly when: "Whole-file write was attempted against an existing note and `overwrite` was not set to `true`.";
|
|
566
|
+
readonly recovery: "Retry with overwrite true or use obsidian_patch_note for in-place edits.";
|
|
567
|
+
}, {
|
|
525
568
|
readonly reason: "path_forbidden";
|
|
569
|
+
readonly thrownBy: "service";
|
|
526
570
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
527
571
|
readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
|
|
528
572
|
readonly recovery: "Use a path inside the configured write scope. The error data echoes the active scope.";
|
|
529
573
|
}, {
|
|
530
574
|
readonly reason: "note_missing";
|
|
575
|
+
readonly thrownBy: "service";
|
|
531
576
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
532
|
-
readonly when: "Section
|
|
533
|
-
readonly recovery: "Verify the path with obsidian_list_notes, or omit `section` to fall back to whole-file
|
|
577
|
+
readonly when: "Section replace targets a path that does not resolve to an existing note (PATCH requires the file to exist).";
|
|
578
|
+
readonly recovery: "Verify the path with obsidian_list_notes, or omit `section` to fall back to whole-file write (which creates the note when it is absent).";
|
|
534
579
|
}, {
|
|
535
580
|
readonly reason: "no_active_file";
|
|
581
|
+
readonly thrownBy: "service";
|
|
536
582
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
537
583
|
readonly when: "Target was `active` but no file is currently open in Obsidian.";
|
|
538
584
|
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
|
|
539
585
|
}, {
|
|
540
586
|
readonly reason: "periodic_unsupported";
|
|
587
|
+
readonly thrownBy: "service";
|
|
541
588
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
542
589
|
readonly when: "Target was `periodic` and this vault runs Local REST API v5.0.2 or later without the companion periodic-notes extension, so the `/periodic/` routes are not served at all.";
|
|
543
590
|
readonly recovery: "Install the periodic-notes extension from https://github.com/coddingtonbear/obsidian-local-rest-api-periodic-notes, or address the note by an explicit vault path.";
|
|
544
591
|
}, {
|
|
545
592
|
readonly reason: "periodic_not_found";
|
|
593
|
+
readonly thrownBy: "service";
|
|
546
594
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
547
595
|
readonly when: "Target was `periodic`, the `/periodic/` routes are served on this vault, and no note exists for the requested period.";
|
|
548
596
|
readonly recovery: "Create the periodic note first or pass an explicit path target.";
|
|
549
597
|
}, {
|
|
550
598
|
readonly reason: "periodic_disabled";
|
|
599
|
+
readonly thrownBy: "service";
|
|
551
600
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
552
601
|
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
|
|
553
602
|
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
|
|
554
603
|
}, {
|
|
555
604
|
readonly reason: "section_target_missing";
|
|
605
|
+
readonly thrownBy: "service";
|
|
556
606
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
557
607
|
readonly when: "`section` was provided but the named heading/block/frontmatter field does not exist in the note.";
|
|
558
|
-
readonly recovery: "Call obsidian_get_note with format document-map to discover available targets
|
|
608
|
+
readonly recovery: "Call obsidian_get_note with format document-map to discover available targets.";
|
|
559
609
|
}, {
|
|
560
610
|
readonly reason: "ambiguous_section";
|
|
611
|
+
readonly thrownBy: "service";
|
|
561
612
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
|
|
562
|
-
readonly when: "A bare heading leaf name matches more than one heading in the note, so the
|
|
563
|
-
readonly recovery: "Retry with
|
|
564
|
-
}, {
|
|
565
|
-
readonly reason: "content_preexists";
|
|
566
|
-
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
567
|
-
readonly when: "Section append where the supplied content already appears at the target — rejected to keep retries idempotent (the default for the section path).";
|
|
568
|
-
readonly recovery: "Change the content to something not already present at the target, or use obsidian_patch_note with `patchOptions.applyIfContentPreexists: true` if a duplicate is intended.";
|
|
613
|
+
readonly when: "A bare heading leaf name matches more than one heading in the note, or the resolved full heading path occurs more than once, so the replacement target is undetermined.";
|
|
614
|
+
readonly recovery: "Retry with a distinct full Parent::Child heading path from `candidates` on the error data; when every candidate is the same path, rename the repeated headings first.";
|
|
569
615
|
}, {
|
|
570
616
|
readonly reason: "path_is_directory";
|
|
617
|
+
readonly thrownBy: "service";
|
|
571
618
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
572
619
|
readonly when: "The supplied path names a folder rather than a note file.";
|
|
573
620
|
readonly recovery: "Call obsidian_list_notes with this path to list the folder, then retry with the full path of one of the files it returns.";
|
|
574
621
|
}, {
|
|
575
622
|
readonly reason: "path_traversal";
|
|
623
|
+
readonly thrownBy: "service";
|
|
576
624
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
577
625
|
readonly when: "The path contains a `.` or `..` segment, which is rejected to prevent vault escape.";
|
|
578
626
|
readonly recovery: "Supply a vault-relative path with no `.` or `..` segments, e.g. \"Projects/Note.md\". Use obsidian_list_notes to browse the vault.";
|
|
@@ -620,8 +668,9 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
620
668
|
currentSizeInBytes: import("zod").ZodNumber;
|
|
621
669
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
622
670
|
readonly reason: "path_forbidden";
|
|
671
|
+
readonly thrownBy: "service";
|
|
623
672
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
624
|
-
readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.
|
|
673
|
+
readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes. The pre-read also requires the path to be readable.";
|
|
625
674
|
readonly recovery: "Use a path inside the configured write scope. The error data echoes the active scope.";
|
|
626
675
|
}, {
|
|
627
676
|
readonly reason: "regex_invalid";
|
|
@@ -636,40 +685,47 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
636
685
|
}, {
|
|
637
686
|
readonly reason: "frontmatter_invalid";
|
|
638
687
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
639
|
-
readonly when: "A `scope` of \"frontmatter\" or \"both\" produced YAML that no longer parses as a mapping of properties. Nothing is written — the note keeps its original bytes. The check reads the rewritten YAML only, so a replacement that renames a key or changes a scalar's type while still parsing is not caught by it.";
|
|
688
|
+
readonly when: "A `scope` of \"frontmatter\" or \"both\" produced YAML that no longer parses as a mapping of properties, or that parses but cannot be re-emitted (an alias whose anchor the replacement removed). Nothing is written — the note keeps its original bytes. The check reads the rewritten YAML only, so a replacement that renames a key or changes a scalar's type while still parsing is not caught by it.";
|
|
640
689
|
readonly recovery: "Narrow the search so it cannot match inside the YAML, or leave scope at \"body\" and edit the property with obsidian_manage_frontmatter.";
|
|
641
690
|
}, {
|
|
642
691
|
readonly reason: "note_missing";
|
|
692
|
+
readonly thrownBy: "service";
|
|
643
693
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
644
694
|
readonly when: "The vault path does not resolve to an existing note.";
|
|
645
695
|
readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
|
|
646
696
|
}, {
|
|
647
697
|
readonly reason: "no_active_file";
|
|
698
|
+
readonly thrownBy: "service";
|
|
648
699
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
649
700
|
readonly when: "Target was `active` but no file is currently open in Obsidian.";
|
|
650
701
|
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
|
|
651
702
|
}, {
|
|
652
703
|
readonly reason: "periodic_unsupported";
|
|
704
|
+
readonly thrownBy: "service";
|
|
653
705
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
654
706
|
readonly when: "Target was `periodic` and this vault runs Local REST API v5.0.2 or later without the companion periodic-notes extension, so the `/periodic/` routes are not served at all.";
|
|
655
707
|
readonly recovery: "Install the periodic-notes extension from https://github.com/coddingtonbear/obsidian-local-rest-api-periodic-notes, or address the note by an explicit vault path.";
|
|
656
708
|
}, {
|
|
657
709
|
readonly reason: "periodic_not_found";
|
|
710
|
+
readonly thrownBy: "service";
|
|
658
711
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
659
712
|
readonly when: "Target was `periodic`, the `/periodic/` routes are served on this vault, and no note exists for the requested period.";
|
|
660
713
|
readonly recovery: "Create the periodic note first or pass an explicit path target.";
|
|
661
714
|
}, {
|
|
662
715
|
readonly reason: "periodic_disabled";
|
|
716
|
+
readonly thrownBy: "service";
|
|
663
717
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
664
718
|
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
|
|
665
719
|
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
|
|
666
720
|
}, {
|
|
667
721
|
readonly reason: "path_is_directory";
|
|
722
|
+
readonly thrownBy: "service";
|
|
668
723
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
669
724
|
readonly when: "The supplied path names a folder rather than a note file.";
|
|
670
725
|
readonly recovery: "Call obsidian_list_notes with this path to list the folder, then retry with the full path of one of the files it returns.";
|
|
671
726
|
}, {
|
|
672
727
|
readonly reason: "path_traversal";
|
|
728
|
+
readonly thrownBy: "service";
|
|
673
729
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
674
730
|
readonly when: "The path contains a `.` or `..` segment, which is rejected to prevent vault escape.";
|
|
675
731
|
readonly recovery: "Supply a vault-relative path with no `.` or `..` segments, e.g. \"Projects/Note.md\". Use obsidian_list_notes to browse the vault.";
|
|
@@ -721,6 +777,7 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
721
777
|
}, import("zod/v4/core").$strip>], "operation">;
|
|
722
778
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
723
779
|
readonly reason: "path_forbidden";
|
|
780
|
+
readonly thrownBy: "service";
|
|
724
781
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
725
782
|
readonly when: "`get` requires the path to be readable; `set`/`delete` require it to be inside OBSIDIAN_WRITE_PATHS, with OBSIDIAN_READ_ONLY=false.";
|
|
726
783
|
readonly recovery: "Use a path inside the configured scope. The error data echoes the active scope.";
|
|
@@ -729,38 +786,50 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
729
786
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
730
787
|
readonly when: "`operation` is \"set\" but no `value` was supplied.";
|
|
731
788
|
readonly recovery: "Pass `value` as any JSON-typed value: string, number, boolean, array, or object (e.g. `\"draft\"`, `42`, `true`, `[\"a\",\"b\"]`).";
|
|
789
|
+
}, {
|
|
790
|
+
readonly reason: "frontmatter_invalid";
|
|
791
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
792
|
+
readonly when: "`operation` is \"delete\" and the note's existing frontmatter does not parse as a mapping of properties, or removing the key would leave YAML that cannot be re-emitted (an alias whose anchor went with it). Nothing is written — the note keeps its original bytes.";
|
|
793
|
+
readonly recovery: "Read the block with obsidian_get_note (format \"content\"), repair the YAML between the `---` fences, then retry the delete.";
|
|
732
794
|
}, {
|
|
733
795
|
readonly reason: "note_missing";
|
|
796
|
+
readonly thrownBy: "service";
|
|
734
797
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
735
798
|
readonly when: "The vault path does not resolve to an existing note.";
|
|
736
799
|
readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
|
|
737
800
|
}, {
|
|
738
801
|
readonly reason: "no_active_file";
|
|
802
|
+
readonly thrownBy: "service";
|
|
739
803
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
740
804
|
readonly when: "Target was `active` but no file is currently open in Obsidian.";
|
|
741
805
|
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
|
|
742
806
|
}, {
|
|
743
807
|
readonly reason: "periodic_unsupported";
|
|
808
|
+
readonly thrownBy: "service";
|
|
744
809
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
745
810
|
readonly when: "Target was `periodic` and this vault runs Local REST API v5.0.2 or later without the companion periodic-notes extension, so the `/periodic/` routes are not served at all.";
|
|
746
811
|
readonly recovery: "Install the periodic-notes extension from https://github.com/coddingtonbear/obsidian-local-rest-api-periodic-notes, or address the note by an explicit vault path.";
|
|
747
812
|
}, {
|
|
748
813
|
readonly reason: "periodic_not_found";
|
|
814
|
+
readonly thrownBy: "service";
|
|
749
815
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
750
816
|
readonly when: "Target was `periodic`, the `/periodic/` routes are served on this vault, and no note exists for the requested period.";
|
|
751
817
|
readonly recovery: "Create the periodic note first or pass an explicit path target.";
|
|
752
818
|
}, {
|
|
753
819
|
readonly reason: "periodic_disabled";
|
|
820
|
+
readonly thrownBy: "service";
|
|
754
821
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
755
822
|
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
|
|
756
823
|
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
|
|
757
824
|
}, {
|
|
758
825
|
readonly reason: "path_is_directory";
|
|
826
|
+
readonly thrownBy: "service";
|
|
759
827
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
760
828
|
readonly when: "The supplied path names a folder rather than a note file.";
|
|
761
829
|
readonly recovery: "Call obsidian_list_notes with this path to list the folder, then retry with the full path of one of the files it returns.";
|
|
762
830
|
}, {
|
|
763
831
|
readonly reason: "path_traversal";
|
|
832
|
+
readonly thrownBy: "service";
|
|
764
833
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
765
834
|
readonly when: "The path contains a `.` or `..` segment, which is rejected to prevent vault escape.";
|
|
766
835
|
readonly recovery: "Supply a vault-relative path with no `.` or `..` segments, e.g. \"Projects/Note.md\". Use obsidian_list_notes to browse the vault.";
|
|
@@ -820,6 +889,7 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
820
889
|
}, import("zod/v4/core").$strip>], "operation">;
|
|
821
890
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
822
891
|
readonly reason: "path_forbidden";
|
|
892
|
+
readonly thrownBy: "service";
|
|
823
893
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
824
894
|
readonly when: "`list` requires the path to be readable; `add`/`remove` require it to be inside OBSIDIAN_WRITE_PATHS, with OBSIDIAN_READ_ONLY=false.";
|
|
825
895
|
readonly recovery: "Use a path inside the configured scope. The error data echoes the active scope.";
|
|
@@ -828,38 +898,50 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
828
898
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
829
899
|
readonly when: "`operation` is \"add\" or \"remove\" but `tags` was empty or omitted.";
|
|
830
900
|
readonly recovery: "Pass a non-empty `tags` array (without `#`), e.g. `[\"draft\", \"wip\"]`.";
|
|
901
|
+
}, {
|
|
902
|
+
readonly reason: "frontmatter_invalid";
|
|
903
|
+
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
904
|
+
readonly when: "`location` reaches the frontmatter and the note's existing block does not parse as a mapping of properties, or the tag change would leave YAML that cannot be re-emitted. Nothing is written — the note keeps its original bytes, and under `location: \"both\"` the inline half is skipped too rather than applied on its own.";
|
|
905
|
+
readonly recovery: "Use `location: \"inline\"` to tag the body without touching the block, or repair the YAML between the `---` fences and retry.";
|
|
831
906
|
}, {
|
|
832
907
|
readonly reason: "note_missing";
|
|
908
|
+
readonly thrownBy: "service";
|
|
833
909
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
834
910
|
readonly when: "The vault path does not resolve to an existing note.";
|
|
835
911
|
readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
|
|
836
912
|
}, {
|
|
837
913
|
readonly reason: "no_active_file";
|
|
914
|
+
readonly thrownBy: "service";
|
|
838
915
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
839
916
|
readonly when: "Target was `active` but no file is currently open in Obsidian.";
|
|
840
917
|
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
|
|
841
918
|
}, {
|
|
842
919
|
readonly reason: "periodic_unsupported";
|
|
920
|
+
readonly thrownBy: "service";
|
|
843
921
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
844
922
|
readonly when: "Target was `periodic` and this vault runs Local REST API v5.0.2 or later without the companion periodic-notes extension, so the `/periodic/` routes are not served at all.";
|
|
845
923
|
readonly recovery: "Install the periodic-notes extension from https://github.com/coddingtonbear/obsidian-local-rest-api-periodic-notes, or address the note by an explicit vault path.";
|
|
846
924
|
}, {
|
|
847
925
|
readonly reason: "periodic_not_found";
|
|
926
|
+
readonly thrownBy: "service";
|
|
848
927
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
849
928
|
readonly when: "Target was `periodic`, the `/periodic/` routes are served on this vault, and no note exists for the requested period.";
|
|
850
929
|
readonly recovery: "Create the periodic note first or pass an explicit path target.";
|
|
851
930
|
}, {
|
|
852
931
|
readonly reason: "periodic_disabled";
|
|
932
|
+
readonly thrownBy: "service";
|
|
853
933
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
854
934
|
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
|
|
855
935
|
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
|
|
856
936
|
}, {
|
|
857
937
|
readonly reason: "path_is_directory";
|
|
938
|
+
readonly thrownBy: "service";
|
|
858
939
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
859
940
|
readonly when: "The supplied path names a folder rather than a note file.";
|
|
860
941
|
readonly recovery: "Call obsidian_list_notes with this path to list the folder, then retry with the full path of one of the files it returns.";
|
|
861
942
|
}, {
|
|
862
943
|
readonly reason: "path_traversal";
|
|
944
|
+
readonly thrownBy: "service";
|
|
863
945
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
864
946
|
readonly when: "The path contains a `.` or `..` segment, which is rejected to prevent vault escape.";
|
|
865
947
|
readonly recovery: "Supply a vault-relative path with no `.` or `..` segments, e.g. \"Projects/Note.md\". Use obsidian_list_notes to browse the vault.";
|
|
@@ -887,6 +969,7 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
887
969
|
currentSizeInBytes: import("zod").ZodNumber;
|
|
888
970
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
889
971
|
readonly reason: "path_forbidden";
|
|
972
|
+
readonly thrownBy: "service";
|
|
890
973
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
|
|
891
974
|
readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
|
|
892
975
|
readonly recovery: "Use a path inside the configured write scope. The error data echoes the active scope.";
|
|
@@ -894,39 +977,47 @@ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").Too
|
|
|
894
977
|
readonly reason: "cancelled";
|
|
895
978
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.InvalidRequest;
|
|
896
979
|
readonly when: "User declined, cancelled, or answered false to the confirmation request.";
|
|
980
|
+
readonly severity: "notice";
|
|
897
981
|
readonly recovery: "Re-run the tool when the user is ready to confirm deletion.";
|
|
898
982
|
}, {
|
|
899
983
|
readonly reason: "note_missing";
|
|
984
|
+
readonly thrownBy: "service";
|
|
900
985
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
901
986
|
readonly when: "The vault path does not resolve to an existing note.";
|
|
902
987
|
readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
|
|
903
988
|
}, {
|
|
904
989
|
readonly reason: "no_active_file";
|
|
990
|
+
readonly thrownBy: "service";
|
|
905
991
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
906
992
|
readonly when: "Target was `active` but no file is currently open in Obsidian.";
|
|
907
993
|
readonly recovery: "Call obsidian_open_in_ui to focus a file, or pass an explicit path target instead.";
|
|
908
994
|
}, {
|
|
909
995
|
readonly reason: "periodic_unsupported";
|
|
996
|
+
readonly thrownBy: "service";
|
|
910
997
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
911
998
|
readonly when: "Target was `periodic` and this vault runs Local REST API v5.0.2 or later without the companion periodic-notes extension, so the `/periodic/` routes are not served at all.";
|
|
912
999
|
readonly recovery: "Install the periodic-notes extension from https://github.com/coddingtonbear/obsidian-local-rest-api-periodic-notes, or address the note by an explicit vault path.";
|
|
913
1000
|
}, {
|
|
914
1001
|
readonly reason: "periodic_not_found";
|
|
1002
|
+
readonly thrownBy: "service";
|
|
915
1003
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
916
1004
|
readonly when: "Target was `periodic`, the `/periodic/` routes are served on this vault, and no note exists for the requested period.";
|
|
917
1005
|
readonly recovery: "Pass an explicit path target — periodic notes must already exist.";
|
|
918
1006
|
}, {
|
|
919
1007
|
readonly reason: "periodic_disabled";
|
|
1008
|
+
readonly thrownBy: "service";
|
|
920
1009
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
921
1010
|
readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
|
|
922
1011
|
readonly recovery: "Pass an explicit path target — the requested period is disabled in the operator's Periodic Notes plugin.";
|
|
923
1012
|
}, {
|
|
924
1013
|
readonly reason: "path_is_directory";
|
|
1014
|
+
readonly thrownBy: "service";
|
|
925
1015
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
926
1016
|
readonly when: "The supplied path names a folder rather than a note file. Deleting a folder is not offered — the upstream removes it and everything inside it in one unrecoverable step.";
|
|
927
1017
|
readonly recovery: "Call obsidian_list_notes with this path to list the folder, then delete files one at a time by their full paths.";
|
|
928
1018
|
}, {
|
|
929
1019
|
readonly reason: "path_traversal";
|
|
1020
|
+
readonly thrownBy: "service";
|
|
930
1021
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
|
|
931
1022
|
readonly when: "The path contains a `.` or `..` segment, which is rejected to prevent vault escape.";
|
|
932
1023
|
readonly recovery: "Supply a vault-relative path with no `.` or `..` segments, e.g. \"Projects/Note.md\". Use obsidian_list_notes to browse the vault.";
|
|
@@ -959,6 +1050,7 @@ export declare const commandToolDefinitions: (import("@cyanheads/mcp-ts-core").T
|
|
|
959
1050
|
executed: import("zod").ZodBoolean;
|
|
960
1051
|
}, import("zod/v4/core").$strip>, readonly [{
|
|
961
1052
|
readonly reason: "command_unknown";
|
|
1053
|
+
readonly thrownBy: "service";
|
|
962
1054
|
readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
|
|
963
1055
|
readonly when: "The supplied `commandId` is not registered in Obsidian. Use `obsidian_list_commands` to discover valid IDs.";
|
|
964
1056
|
readonly recovery: "Call obsidian_list_commands to discover the registered command IDs.";
|