obsidian-mcp-server 3.1.0 → 3.1.2

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.
Files changed (72) hide show
  1. package/CLAUDE.md +24 -9
  2. package/README.md +28 -1
  3. package/changelog/3.1.x/3.1.1.md +21 -0
  4. package/changelog/3.1.x/3.1.2.md +23 -0
  5. package/dist/config/server-config.d.ts +5 -2
  6. package/dist/config/server-config.d.ts.map +1 -1
  7. package/dist/config/server-config.js +73 -0
  8. package/dist/config/server-config.js.map +1 -1
  9. package/dist/index.js +39 -5
  10. package/dist/index.js.map +1 -1
  11. package/dist/mcp-server/tools/definitions/index.d.ts +793 -10
  12. package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
  13. package/dist/mcp-server/tools/definitions/index.js +15 -9
  14. package/dist/mcp-server/tools/definitions/index.js.map +1 -1
  15. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts +7 -1
  16. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts.map +1 -1
  17. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js +9 -0
  18. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js.map +1 -1
  19. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts +14 -0
  20. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts.map +1 -1
  21. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.js +20 -1
  22. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.js.map +1 -1
  23. package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.d.ts +1 -0
  24. package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.d.ts.map +1 -1
  25. package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.js +1 -0
  26. package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.js.map +1 -1
  27. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.d.ts +14 -0
  28. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.d.ts.map +1 -1
  29. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.js +17 -0
  30. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.js.map +1 -1
  31. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.d.ts +7 -0
  32. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.d.ts.map +1 -1
  33. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.js +18 -3
  34. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.js.map +1 -1
  35. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts +14 -0
  36. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts.map +1 -1
  37. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.js +17 -0
  38. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.js.map +1 -1
  39. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts +14 -0
  40. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts.map +1 -1
  41. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.js +17 -1
  42. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.js.map +1 -1
  43. package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.d.ts +6 -0
  44. package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.d.ts.map +1 -1
  45. package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.js +14 -4
  46. package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.js.map +1 -1
  47. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts +16 -2
  48. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts.map +1 -1
  49. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js +16 -0
  50. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js.map +1 -1
  51. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts +14 -0
  52. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts.map +1 -1
  53. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js +17 -1
  54. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js.map +1 -1
  55. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts +3 -0
  56. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts.map +1 -1
  57. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js +21 -4
  58. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js.map +1 -1
  59. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts +6 -0
  60. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts.map +1 -1
  61. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js +13 -1
  62. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js.map +1 -1
  63. package/dist/services/obsidian/obsidian-service.d.ts +7 -0
  64. package/dist/services/obsidian/obsidian-service.d.ts.map +1 -1
  65. package/dist/services/obsidian/obsidian-service.js +132 -28
  66. package/dist/services/obsidian/obsidian-service.js.map +1 -1
  67. package/dist/services/obsidian/path-policy.d.ts +56 -0
  68. package/dist/services/obsidian/path-policy.d.ts.map +1 -0
  69. package/dist/services/obsidian/path-policy.js +154 -0
  70. package/dist/services/obsidian/path-policy.js.map +1 -0
  71. package/package.json +7 -8
  72. package/server.json +41 -3
@@ -1,12 +1,683 @@
1
1
  /**
2
- * @fileoverview Tool registration barrel. The command-palette pair
3
- * (`obsidian_list_commands` + `obsidian_execute_command`) is exported
4
- * separately so callers can decide whether to register them based on the
5
- * `OBSIDIAN_ENABLE_COMMANDS` flag keeping this module free of eager
6
- * config reads.
2
+ * @fileoverview Tool registration barrel. Tools are split into read-only and
3
+ * write groups so the entry point can wrap the write set with `disabledTool()`
4
+ * when `OBSIDIAN_READ_ONLY=true`. The command-palette pair is exported
5
+ * separately so the entry point wraps it with `disabledTool()` when either
6
+ * `OBSIDIAN_ENABLE_COMMANDS=false` or `OBSIDIAN_READ_ONLY=true` — keeping this
7
+ * module free of eager config reads.
7
8
  * @module mcp-server/tools/definitions/index
8
9
  */
9
- /** Tools registered unconditionally on every server. */
10
+ /** Read-only tools — always registered, even with `OBSIDIAN_READ_ONLY=true`. */
11
+ export declare const readToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
12
+ format: import("zod").ZodEnum<{
13
+ content: "content";
14
+ section: "section";
15
+ full: "full";
16
+ "document-map": "document-map";
17
+ }>;
18
+ target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
19
+ type: import("zod").ZodLiteral<"path">;
20
+ path: import("zod").ZodString;
21
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
22
+ type: import("zod").ZodLiteral<"active">;
23
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
24
+ type: import("zod").ZodLiteral<"periodic">;
25
+ period: import("zod").ZodEnum<{
26
+ daily: "daily";
27
+ weekly: "weekly";
28
+ monthly: "monthly";
29
+ quarterly: "quarterly";
30
+ yearly: "yearly";
31
+ }>;
32
+ date: import("zod").ZodOptional<import("zod").ZodString>;
33
+ }, import("zod/v4/core").$strip>], "type">;
34
+ section: import("zod").ZodOptional<import("zod").ZodObject<{
35
+ type: import("zod").ZodEnum<{
36
+ heading: "heading";
37
+ block: "block";
38
+ frontmatter: "frontmatter";
39
+ }>;
40
+ target: import("zod").ZodString;
41
+ }, import("zod/v4/core").$strip>>;
42
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
43
+ result: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
44
+ format: import("zod").ZodLiteral<"content">;
45
+ path: import("zod").ZodString;
46
+ content: import("zod").ZodString;
47
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
48
+ format: import("zod").ZodLiteral<"full">;
49
+ path: import("zod").ZodString;
50
+ content: import("zod").ZodString;
51
+ frontmatter: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
52
+ tags: import("zod").ZodArray<import("zod").ZodString>;
53
+ stat: import("zod").ZodObject<{
54
+ ctime: import("zod").ZodNumber;
55
+ mtime: import("zod").ZodNumber;
56
+ size: import("zod").ZodNumber;
57
+ }, import("zod/v4/core").$strip>;
58
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
59
+ format: import("zod").ZodLiteral<"document-map">;
60
+ path: import("zod").ZodString;
61
+ headings: import("zod").ZodArray<import("zod").ZodString>;
62
+ blocks: import("zod").ZodArray<import("zod").ZodString>;
63
+ frontmatterFields: import("zod").ZodArray<import("zod").ZodString>;
64
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
65
+ format: import("zod").ZodLiteral<"section">;
66
+ path: import("zod").ZodString;
67
+ section: import("zod").ZodObject<{
68
+ type: import("zod").ZodEnum<{
69
+ heading: "heading";
70
+ block: "block";
71
+ frontmatter: "frontmatter";
72
+ }>;
73
+ target: import("zod").ZodString;
74
+ }, import("zod/v4/core").$strip>;
75
+ valueText: import("zod").ZodOptional<import("zod").ZodString>;
76
+ valueJson: import("zod").ZodOptional<import("zod").ZodUnknown>;
77
+ }, import("zod/v4/core").$strip>], "format">;
78
+ }, import("zod/v4/core").$strip>, readonly [{
79
+ readonly reason: "section_required";
80
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
81
+ readonly when: "`format` is \"section\" but no `section` locator was provided.";
82
+ readonly recovery: "Pass `section: { type, target }` (e.g. `{ type: \"heading\", target: \"Intro\" }`), or use `format: \"full\"` / `\"document-map\"` instead.";
83
+ }, {
84
+ readonly reason: "path_forbidden";
85
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
86
+ readonly when: "The target path is outside OBSIDIAN_READ_PATHS (and OBSIDIAN_WRITE_PATHS, since write paths imply read access).";
87
+ readonly recovery: "Use a path inside the configured read scope. The error data echoes the active scope; check the server startup banner for the active configuration.";
88
+ }, {
89
+ readonly reason: "note_missing";
90
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
91
+ readonly when: "The vault path does not resolve to an existing note.";
92
+ readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
93
+ }, {
94
+ readonly reason: "no_active_file";
95
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
96
+ readonly when: "Target was `active` but no file is currently open in Obsidian.";
97
+ readonly recovery: "Open a note in Obsidian or pass an explicit path target instead.";
98
+ }, {
99
+ readonly reason: "periodic_not_found";
100
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
101
+ readonly when: "Target was `periodic` but no matching periodic note exists.";
102
+ readonly recovery: "Create the periodic note first or pass an explicit path target.";
103
+ }, {
104
+ readonly reason: "periodic_disabled";
105
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
106
+ readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
107
+ readonly recovery: "Enable the period in Obsidian's Periodic Notes plugin settings, or pass an explicit path target instead.";
108
+ }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
109
+ path: import("zod").ZodOptional<import("zod").ZodString>;
110
+ extension: import("zod").ZodOptional<import("zod").ZodString>;
111
+ nameRegex: import("zod").ZodOptional<import("zod").ZodString>;
112
+ depth: import("zod").ZodOptional<import("zod").ZodNumber>;
113
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
114
+ path: import("zod").ZodString;
115
+ entries: import("zod").ZodArray<import("zod").ZodObject<{
116
+ path: import("zod").ZodString;
117
+ type: import("zod").ZodEnum<{
118
+ file: "file";
119
+ directory: "directory";
120
+ }>;
121
+ truncated: import("zod").ZodOptional<import("zod").ZodBoolean>;
122
+ }, import("zod/v4/core").$strip>>;
123
+ totals: import("zod").ZodObject<{
124
+ entries: import("zod").ZodNumber;
125
+ files: import("zod").ZodNumber;
126
+ directories: import("zod").ZodNumber;
127
+ }, import("zod/v4/core").$strip>;
128
+ appliedFilters: import("zod").ZodObject<{
129
+ extension: import("zod").ZodOptional<import("zod").ZodString>;
130
+ nameRegex: import("zod").ZodOptional<import("zod").ZodString>;
131
+ depth: import("zod").ZodNumber;
132
+ }, import("zod/v4/core").$strip>;
133
+ excluded: import("zod").ZodOptional<import("zod").ZodObject<{
134
+ reason: import("zod").ZodLiteral<"entry_cap">;
135
+ cap: import("zod").ZodNumber;
136
+ hint: import("zod").ZodString;
137
+ }, import("zod/v4/core").$strip>>;
138
+ }, import("zod/v4/core").$strip>, readonly [{
139
+ readonly reason: "regex_invalid";
140
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
141
+ readonly when: "The supplied `nameRegex` is not a valid ECMAScript regex.";
142
+ readonly recovery: "Test the pattern (e.g. `^Project.*\\.md$`) in a JS regex tester, or omit nameRegex to disable filtering.";
143
+ }, {
144
+ readonly reason: "path_forbidden";
145
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
146
+ readonly when: "The supplied `path` is outside OBSIDIAN_READ_PATHS (root listings always pass; specific subdirectories must be readable).";
147
+ 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.";
148
+ }, {
149
+ readonly reason: "note_missing";
150
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
151
+ readonly when: "The supplied `path` does not exist in the vault. Sub-directories that disappear mid-walk are silently skipped — only the root path surfaces this error.";
152
+ readonly recovery: "List a parent directory to find the correct casing or check the spelling.";
153
+ }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
154
+ tags: import("zod").ZodArray<import("zod").ZodObject<{
155
+ name: import("zod").ZodString;
156
+ count: import("zod").ZodNumber;
157
+ }, import("zod/v4/core").$strip>>;
158
+ }, import("zod/v4/core").$strip>, undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
159
+ path: import("zod").ZodString;
160
+ failIfMissing: import("zod").ZodDefault<import("zod").ZodBoolean>;
161
+ newLeaf: import("zod").ZodDefault<import("zod").ZodBoolean>;
162
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
163
+ path: import("zod").ZodString;
164
+ opened: import("zod").ZodBoolean;
165
+ createdIfMissing: import("zod").ZodBoolean;
166
+ }, import("zod/v4/core").$strip>, readonly [{
167
+ readonly reason: "path_forbidden";
168
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
169
+ readonly when: "The target path is outside OBSIDIAN_READ_PATHS (and OBSIDIAN_WRITE_PATHS, since write paths imply read access).";
170
+ readonly recovery: "Use a path inside the configured read scope. The error data echoes the active scope; check the server startup banner for the active configuration.";
171
+ }, {
172
+ readonly reason: "note_missing";
173
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
174
+ readonly when: "`failIfMissing: true` (default) and the path does not exist in the vault. Pass `failIfMissing: false` to allow Obsidian to create the file on open.";
175
+ readonly recovery: "Verify the path with obsidian_list_notes or pass failIfMissing false to create on open.";
176
+ }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
177
+ mode: import("zod").ZodEnum<{
178
+ text: "text";
179
+ dataview: "dataview";
180
+ jsonlogic: "jsonlogic";
181
+ }>;
182
+ query: import("zod").ZodOptional<import("zod").ZodString>;
183
+ logic: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>>;
184
+ contextLength: import("zod").ZodOptional<import("zod").ZodNumber>;
185
+ pathPrefix: import("zod").ZodOptional<import("zod").ZodString>;
186
+ maxMatchesPerHit: import("zod").ZodOptional<import("zod").ZodNumber>;
187
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
188
+ result: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
189
+ mode: import("zod").ZodLiteral<"text">;
190
+ hits: import("zod").ZodArray<import("zod").ZodObject<{
191
+ filename: import("zod").ZodString;
192
+ score: import("zod").ZodOptional<import("zod").ZodNumber>;
193
+ matches: import("zod").ZodArray<import("zod").ZodObject<{
194
+ context: import("zod").ZodString;
195
+ match: import("zod").ZodObject<{
196
+ start: import("zod").ZodNumber;
197
+ end: import("zod").ZodNumber;
198
+ }, import("zod/v4/core").$strip>;
199
+ }, import("zod/v4/core").$strip>>;
200
+ totalMatches: import("zod").ZodOptional<import("zod").ZodNumber>;
201
+ truncated: import("zod").ZodOptional<import("zod").ZodBoolean>;
202
+ }, import("zod/v4/core").$strip>>;
203
+ excluded: import("zod").ZodOptional<import("zod").ZodObject<{
204
+ count: import("zod").ZodNumber;
205
+ hint: import("zod").ZodString;
206
+ }, import("zod/v4/core").$strip>>;
207
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
208
+ mode: import("zod").ZodLiteral<"dataview">;
209
+ hits: import("zod").ZodArray<import("zod").ZodObject<{
210
+ filename: import("zod").ZodString;
211
+ result: import("zod").ZodUnknown;
212
+ }, import("zod/v4/core").$strip>>;
213
+ excluded: import("zod").ZodOptional<import("zod").ZodObject<{
214
+ count: import("zod").ZodNumber;
215
+ hint: import("zod").ZodString;
216
+ }, import("zod/v4/core").$strip>>;
217
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
218
+ mode: import("zod").ZodLiteral<"jsonlogic">;
219
+ hits: import("zod").ZodArray<import("zod").ZodObject<{
220
+ filename: import("zod").ZodString;
221
+ result: import("zod").ZodUnknown;
222
+ }, import("zod/v4/core").$strip>>;
223
+ excluded: import("zod").ZodOptional<import("zod").ZodObject<{
224
+ count: import("zod").ZodNumber;
225
+ hint: import("zod").ZodString;
226
+ }, import("zod/v4/core").$strip>>;
227
+ }, import("zod/v4/core").$strip>], "mode">;
228
+ }, import("zod/v4/core").$strip>, readonly [{
229
+ readonly reason: "path_prefix_invalid_mode";
230
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
231
+ readonly when: "`pathPrefix` was provided in a non-text mode (only `text` supports prefix filtering).";
232
+ readonly recovery: "Drop pathPrefix or switch mode to text for prefix filtering.";
233
+ }, {
234
+ readonly reason: "query_required";
235
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
236
+ readonly when: "`query` is missing for `text` or `dataview` mode (required for both).";
237
+ readonly recovery: "Pass `query` — search terms for text mode (e.g. \"TODO\"), or DQL like \"TABLE WHERE file.mtime > date(today)\" for dataview mode.";
238
+ }, {
239
+ readonly reason: "logic_required";
240
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
241
+ readonly when: "`logic` is missing for `jsonlogic` mode.";
242
+ readonly recovery: "Pass a JSONLogic tree as `logic`, e.g. `{\"glob\": [{\"var\": \"path\"}, \"Projects/*.md\"]}`.";
243
+ }]>)[];
244
+ /** Write tools — wrapped with `disabledTool()` when `OBSIDIAN_READ_ONLY=true`. */
245
+ export declare const writeToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
246
+ target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
247
+ type: import("zod").ZodLiteral<"path">;
248
+ path: import("zod").ZodString;
249
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
250
+ type: import("zod").ZodLiteral<"active">;
251
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
252
+ type: import("zod").ZodLiteral<"periodic">;
253
+ period: import("zod").ZodEnum<{
254
+ daily: "daily";
255
+ weekly: "weekly";
256
+ monthly: "monthly";
257
+ quarterly: "quarterly";
258
+ yearly: "yearly";
259
+ }>;
260
+ date: import("zod").ZodOptional<import("zod").ZodString>;
261
+ }, import("zod/v4/core").$strip>], "type">;
262
+ content: import("zod").ZodString;
263
+ section: import("zod").ZodOptional<import("zod").ZodObject<{
264
+ type: import("zod").ZodEnum<{
265
+ heading: "heading";
266
+ block: "block";
267
+ frontmatter: "frontmatter";
268
+ }>;
269
+ target: import("zod").ZodString;
270
+ }, import("zod/v4/core").$strip>>;
271
+ contentType: import("zod").ZodDefault<import("zod").ZodEnum<{
272
+ markdown: "markdown";
273
+ json: "json";
274
+ }>>;
275
+ createTargetIfMissing: import("zod").ZodDefault<import("zod").ZodBoolean>;
276
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
277
+ path: import("zod").ZodString;
278
+ sectionTargeted: import("zod").ZodBoolean;
279
+ }, import("zod/v4/core").$strip>, readonly [{
280
+ readonly reason: "path_forbidden";
281
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
282
+ readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
283
+ readonly recovery: "Use a path inside the configured write scope, or unset OBSIDIAN_READ_ONLY. The error data echoes the active scope; check the server startup banner for the active configuration.";
284
+ }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
285
+ target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
286
+ type: import("zod").ZodLiteral<"path">;
287
+ path: import("zod").ZodString;
288
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
289
+ type: import("zod").ZodLiteral<"active">;
290
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
291
+ type: import("zod").ZodLiteral<"periodic">;
292
+ period: import("zod").ZodEnum<{
293
+ daily: "daily";
294
+ weekly: "weekly";
295
+ monthly: "monthly";
296
+ quarterly: "quarterly";
297
+ yearly: "yearly";
298
+ }>;
299
+ date: import("zod").ZodOptional<import("zod").ZodString>;
300
+ }, import("zod/v4/core").$strip>], "type">;
301
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
302
+ path: import("zod").ZodString;
303
+ deleted: import("zod").ZodBoolean;
304
+ }, import("zod/v4/core").$strip>, readonly [{
305
+ readonly reason: "path_forbidden";
306
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
307
+ readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
308
+ readonly recovery: "Use a path inside the configured write scope, or unset OBSIDIAN_READ_ONLY. The error data echoes the active scope; check the server startup banner for the active configuration.";
309
+ }, {
310
+ readonly reason: "cancelled";
311
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.InvalidRequest;
312
+ readonly when: "User declined the deletion via interactive elicitation.";
313
+ readonly recovery: "Re-run the tool when the user is ready to confirm deletion.";
314
+ }, {
315
+ readonly reason: "note_missing";
316
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
317
+ readonly when: "The vault path does not resolve to an existing note.";
318
+ readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
319
+ }, {
320
+ readonly reason: "no_active_file";
321
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
322
+ readonly when: "Target was `active` but no file is currently open in Obsidian.";
323
+ readonly recovery: "Open a note in Obsidian or pass an explicit path target instead.";
324
+ }, {
325
+ readonly reason: "periodic_not_found";
326
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
327
+ readonly when: "Target was `periodic` but no matching periodic note exists.";
328
+ readonly recovery: "Pass an explicit path target — periodic notes must already exist.";
329
+ }, {
330
+ readonly reason: "periodic_disabled";
331
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
332
+ readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
333
+ readonly recovery: "Enable the period in Obsidian's Periodic Notes plugin settings, or pass an explicit path target instead.";
334
+ }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
335
+ operation: import("zod").ZodEnum<{
336
+ set: "set";
337
+ delete: "delete";
338
+ get: "get";
339
+ }>;
340
+ target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
341
+ type: import("zod").ZodLiteral<"path">;
342
+ path: import("zod").ZodString;
343
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
344
+ type: import("zod").ZodLiteral<"active">;
345
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
346
+ type: import("zod").ZodLiteral<"periodic">;
347
+ period: import("zod").ZodEnum<{
348
+ daily: "daily";
349
+ weekly: "weekly";
350
+ monthly: "monthly";
351
+ quarterly: "quarterly";
352
+ yearly: "yearly";
353
+ }>;
354
+ date: import("zod").ZodOptional<import("zod").ZodString>;
355
+ }, import("zod/v4/core").$strip>], "type">;
356
+ key: import("zod").ZodString;
357
+ value: import("zod").ZodOptional<import("zod").ZodUnknown>;
358
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
359
+ result: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
360
+ operation: import("zod").ZodLiteral<"get">;
361
+ path: import("zod").ZodString;
362
+ key: import("zod").ZodString;
363
+ exists: import("zod").ZodBoolean;
364
+ value: import("zod").ZodUnknown;
365
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
366
+ operation: import("zod").ZodLiteral<"set">;
367
+ path: import("zod").ZodString;
368
+ key: import("zod").ZodString;
369
+ frontmatter: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
370
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
371
+ operation: import("zod").ZodLiteral<"delete">;
372
+ path: import("zod").ZodString;
373
+ key: import("zod").ZodString;
374
+ frontmatter: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
375
+ }, import("zod/v4/core").$strip>], "operation">;
376
+ }, import("zod/v4/core").$strip>, readonly [{
377
+ readonly reason: "path_forbidden";
378
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
379
+ readonly when: "`get` requires the path to be readable; `set`/`delete` require it to be inside OBSIDIAN_WRITE_PATHS, with OBSIDIAN_READ_ONLY=false.";
380
+ readonly recovery: "Use a path inside the configured scope, or unset OBSIDIAN_READ_ONLY for writes. The error data echoes the active scope; check the server startup banner for the active configuration.";
381
+ }, {
382
+ readonly reason: "value_required";
383
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
384
+ readonly when: "`operation` is \"set\" but no `value` was supplied.";
385
+ readonly recovery: "Pass `value` as any JSON-typed value: string, number, boolean, array, or object (e.g. `\"draft\"`, `42`, `true`, `[\"a\",\"b\"]`).";
386
+ }, {
387
+ readonly reason: "note_missing";
388
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
389
+ readonly when: "The vault path does not resolve to an existing note.";
390
+ readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
391
+ }, {
392
+ readonly reason: "no_active_file";
393
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
394
+ readonly when: "Target was `active` but no file is currently open in Obsidian.";
395
+ readonly recovery: "Open a note in Obsidian or pass an explicit path target instead.";
396
+ }, {
397
+ readonly reason: "periodic_not_found";
398
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
399
+ readonly when: "Target was `periodic` but no matching periodic note exists.";
400
+ readonly recovery: "Create the periodic note first or pass an explicit path target.";
401
+ }, {
402
+ readonly reason: "periodic_disabled";
403
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
404
+ readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
405
+ readonly recovery: "Enable the period in Obsidian's Periodic Notes plugin settings, or pass an explicit path target instead.";
406
+ }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
407
+ target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
408
+ type: import("zod").ZodLiteral<"path">;
409
+ path: import("zod").ZodString;
410
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
411
+ type: import("zod").ZodLiteral<"active">;
412
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
413
+ type: import("zod").ZodLiteral<"periodic">;
414
+ period: import("zod").ZodEnum<{
415
+ daily: "daily";
416
+ weekly: "weekly";
417
+ monthly: "monthly";
418
+ quarterly: "quarterly";
419
+ yearly: "yearly";
420
+ }>;
421
+ date: import("zod").ZodOptional<import("zod").ZodString>;
422
+ }, import("zod/v4/core").$strip>], "type">;
423
+ operation: import("zod").ZodEnum<{
424
+ list: "list";
425
+ add: "add";
426
+ remove: "remove";
427
+ }>;
428
+ tags: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
429
+ location: import("zod").ZodDefault<import("zod").ZodEnum<{
430
+ frontmatter: "frontmatter";
431
+ inline: "inline";
432
+ both: "both";
433
+ }>>;
434
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
435
+ result: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
436
+ operation: import("zod").ZodLiteral<"list">;
437
+ path: import("zod").ZodString;
438
+ tags: import("zod").ZodObject<{
439
+ frontmatter: import("zod").ZodArray<import("zod").ZodString>;
440
+ inline: import("zod").ZodArray<import("zod").ZodString>;
441
+ all: import("zod").ZodArray<import("zod").ZodString>;
442
+ }, import("zod/v4/core").$strip>;
443
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
444
+ operation: import("zod").ZodLiteral<"add">;
445
+ path: import("zod").ZodString;
446
+ applied: import("zod").ZodArray<import("zod").ZodString>;
447
+ skipped: import("zod").ZodArray<import("zod").ZodString>;
448
+ tags: import("zod").ZodArray<import("zod").ZodString>;
449
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
450
+ operation: import("zod").ZodLiteral<"remove">;
451
+ path: import("zod").ZodString;
452
+ applied: import("zod").ZodArray<import("zod").ZodString>;
453
+ skipped: import("zod").ZodArray<import("zod").ZodString>;
454
+ tags: import("zod").ZodArray<import("zod").ZodString>;
455
+ }, import("zod/v4/core").$strip>], "operation">;
456
+ }, import("zod/v4/core").$strip>, readonly [{
457
+ readonly reason: "path_forbidden";
458
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
459
+ readonly when: "`list` requires the path to be readable; `add`/`remove` require it to be inside OBSIDIAN_WRITE_PATHS, with OBSIDIAN_READ_ONLY=false.";
460
+ readonly recovery: "Use a path inside the configured scope, or unset OBSIDIAN_READ_ONLY for writes. The error data echoes the active scope; check the server startup banner for the active configuration.";
461
+ }, {
462
+ readonly reason: "tags_required";
463
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
464
+ readonly when: "`operation` is \"add\" or \"remove\" but `tags` was empty or omitted.";
465
+ readonly recovery: "Pass a non-empty `tags` array (without `#`), e.g. `[\"draft\", \"wip\"]`.";
466
+ }, {
467
+ readonly reason: "note_missing";
468
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
469
+ readonly when: "The vault path does not resolve to an existing note.";
470
+ readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
471
+ }, {
472
+ readonly reason: "no_active_file";
473
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
474
+ readonly when: "Target was `active` but no file is currently open in Obsidian.";
475
+ readonly recovery: "Open a note in Obsidian or pass an explicit path target instead.";
476
+ }, {
477
+ readonly reason: "periodic_not_found";
478
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
479
+ readonly when: "Target was `periodic` but no matching periodic note exists.";
480
+ readonly recovery: "Create the periodic note first or pass an explicit path target.";
481
+ }, {
482
+ readonly reason: "periodic_disabled";
483
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
484
+ readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
485
+ readonly recovery: "Enable the period in Obsidian's Periodic Notes plugin settings, or pass an explicit path target instead.";
486
+ }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
487
+ target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
488
+ type: import("zod").ZodLiteral<"path">;
489
+ path: import("zod").ZodString;
490
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
491
+ type: import("zod").ZodLiteral<"active">;
492
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
493
+ type: import("zod").ZodLiteral<"periodic">;
494
+ period: import("zod").ZodEnum<{
495
+ daily: "daily";
496
+ weekly: "weekly";
497
+ monthly: "monthly";
498
+ quarterly: "quarterly";
499
+ yearly: "yearly";
500
+ }>;
501
+ date: import("zod").ZodOptional<import("zod").ZodString>;
502
+ }, import("zod/v4/core").$strip>], "type">;
503
+ section: import("zod").ZodObject<{
504
+ type: import("zod").ZodEnum<{
505
+ heading: "heading";
506
+ block: "block";
507
+ frontmatter: "frontmatter";
508
+ }>;
509
+ target: import("zod").ZodString;
510
+ }, import("zod/v4/core").$strip>;
511
+ operation: import("zod").ZodEnum<{
512
+ replace: "replace";
513
+ append: "append";
514
+ prepend: "prepend";
515
+ }>;
516
+ content: import("zod").ZodString;
517
+ contentType: import("zod").ZodDefault<import("zod").ZodEnum<{
518
+ markdown: "markdown";
519
+ json: "json";
520
+ }>>;
521
+ patchOptions: import("zod").ZodOptional<import("zod").ZodObject<{
522
+ createTargetIfMissing: import("zod").ZodDefault<import("zod").ZodBoolean>;
523
+ applyIfContentPreexists: import("zod").ZodDefault<import("zod").ZodBoolean>;
524
+ trimTargetWhitespace: import("zod").ZodDefault<import("zod").ZodBoolean>;
525
+ }, import("zod/v4/core").$strip>>;
526
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
527
+ path: import("zod").ZodString;
528
+ section: import("zod").ZodObject<{
529
+ type: import("zod").ZodEnum<{
530
+ heading: "heading";
531
+ block: "block";
532
+ frontmatter: "frontmatter";
533
+ }>;
534
+ target: import("zod").ZodString;
535
+ }, import("zod/v4/core").$strip>;
536
+ operation: import("zod").ZodEnum<{
537
+ replace: "replace";
538
+ append: "append";
539
+ prepend: "prepend";
540
+ }>;
541
+ }, import("zod/v4/core").$strip>, readonly [{
542
+ readonly reason: "path_forbidden";
543
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
544
+ readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
545
+ readonly recovery: "Use a path inside the configured write scope, or unset OBSIDIAN_READ_ONLY. The error data echoes the active scope; check the server startup banner for the active configuration.";
546
+ }, {
547
+ readonly reason: "note_missing";
548
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
549
+ readonly when: "The vault path does not resolve to an existing note.";
550
+ readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
551
+ }, {
552
+ readonly reason: "no_active_file";
553
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
554
+ readonly when: "Target was `active` but no file is currently open in Obsidian.";
555
+ readonly recovery: "Open a note in Obsidian or pass an explicit path target instead.";
556
+ }, {
557
+ readonly reason: "periodic_not_found";
558
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
559
+ readonly when: "Target was `periodic` but no matching periodic note exists.";
560
+ readonly recovery: "Create the periodic note first or pass an explicit path target.";
561
+ }, {
562
+ readonly reason: "periodic_disabled";
563
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
564
+ readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
565
+ readonly recovery: "Enable the period in Obsidian's Periodic Notes plugin settings, or pass an explicit path target instead.";
566
+ }, {
567
+ readonly reason: "section_target_missing";
568
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
569
+ 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.";
570
+ readonly recovery: "Call obsidian_get_note with format document-map to discover the available targets.";
571
+ }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
572
+ target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
573
+ type: import("zod").ZodLiteral<"path">;
574
+ path: import("zod").ZodString;
575
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
576
+ type: import("zod").ZodLiteral<"active">;
577
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
578
+ type: import("zod").ZodLiteral<"periodic">;
579
+ period: import("zod").ZodEnum<{
580
+ daily: "daily";
581
+ weekly: "weekly";
582
+ monthly: "monthly";
583
+ quarterly: "quarterly";
584
+ yearly: "yearly";
585
+ }>;
586
+ date: import("zod").ZodOptional<import("zod").ZodString>;
587
+ }, import("zod/v4/core").$strip>], "type">;
588
+ replacements: import("zod").ZodArray<import("zod").ZodObject<{
589
+ search: import("zod").ZodString;
590
+ replace: import("zod").ZodString;
591
+ useRegex: import("zod").ZodDefault<import("zod").ZodBoolean>;
592
+ caseSensitive: import("zod").ZodDefault<import("zod").ZodBoolean>;
593
+ wholeWord: import("zod").ZodDefault<import("zod").ZodBoolean>;
594
+ flexibleWhitespace: import("zod").ZodDefault<import("zod").ZodBoolean>;
595
+ replaceAll: import("zod").ZodDefault<import("zod").ZodBoolean>;
596
+ }, import("zod/v4/core").$strip>>;
597
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
598
+ path: import("zod").ZodString;
599
+ totalReplacements: import("zod").ZodNumber;
600
+ perReplacement: import("zod").ZodArray<import("zod").ZodObject<{
601
+ search: import("zod").ZodString;
602
+ count: import("zod").ZodNumber;
603
+ }, import("zod/v4/core").$strip>>;
604
+ }, import("zod/v4/core").$strip>, readonly [{
605
+ readonly reason: "path_forbidden";
606
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
607
+ 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.)";
608
+ readonly recovery: "Use a path inside the configured write scope, or unset OBSIDIAN_READ_ONLY. The error data echoes the active scope; check the server startup banner for the active configuration.";
609
+ }, {
610
+ readonly reason: "regex_invalid";
611
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
612
+ readonly when: "A `useRegex: true` replacement supplied a `search` pattern that is not a valid ECMAScript regex.";
613
+ readonly recovery: "Test the pattern in a JS regex tester, or set useRegex to false to match `search` as a literal string.";
614
+ }, {
615
+ readonly reason: "note_missing";
616
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
617
+ readonly when: "The vault path does not resolve to an existing note.";
618
+ readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
619
+ }, {
620
+ readonly reason: "no_active_file";
621
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
622
+ readonly when: "Target was `active` but no file is currently open in Obsidian.";
623
+ readonly recovery: "Open a note in Obsidian or pass an explicit path target instead.";
624
+ }, {
625
+ readonly reason: "periodic_not_found";
626
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
627
+ readonly when: "Target was `periodic` but no matching periodic note exists.";
628
+ readonly recovery: "Create the periodic note first or pass an explicit path target.";
629
+ }, {
630
+ readonly reason: "periodic_disabled";
631
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
632
+ readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
633
+ readonly recovery: "Enable the period in Obsidian's Periodic Notes plugin settings, or pass an explicit path target instead.";
634
+ }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
635
+ target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
636
+ type: import("zod").ZodLiteral<"path">;
637
+ path: import("zod").ZodString;
638
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
639
+ type: import("zod").ZodLiteral<"active">;
640
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
641
+ type: import("zod").ZodLiteral<"periodic">;
642
+ period: import("zod").ZodEnum<{
643
+ daily: "daily";
644
+ weekly: "weekly";
645
+ monthly: "monthly";
646
+ quarterly: "quarterly";
647
+ yearly: "yearly";
648
+ }>;
649
+ date: import("zod").ZodOptional<import("zod").ZodString>;
650
+ }, import("zod/v4/core").$strip>], "type">;
651
+ content: import("zod").ZodString;
652
+ section: import("zod").ZodOptional<import("zod").ZodObject<{
653
+ type: import("zod").ZodEnum<{
654
+ heading: "heading";
655
+ block: "block";
656
+ frontmatter: "frontmatter";
657
+ }>;
658
+ target: import("zod").ZodString;
659
+ }, import("zod/v4/core").$strip>>;
660
+ contentType: import("zod").ZodDefault<import("zod").ZodEnum<{
661
+ markdown: "markdown";
662
+ json: "json";
663
+ }>>;
664
+ overwrite: import("zod").ZodDefault<import("zod").ZodBoolean>;
665
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
666
+ path: import("zod").ZodString;
667
+ sectionTargeted: import("zod").ZodBoolean;
668
+ created: import("zod").ZodBoolean;
669
+ }, import("zod/v4/core").$strip>, readonly [{
670
+ readonly reason: "file_exists";
671
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
672
+ readonly when: "Whole-file write was attempted against an existing note and `overwrite` was not set to `true`.";
673
+ readonly recovery: "Retry with overwrite true or use obsidian_patch_note for in-place edits.";
674
+ }, {
675
+ readonly reason: "path_forbidden";
676
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
677
+ readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
678
+ readonly recovery: "Use a path inside the configured write scope, or unset OBSIDIAN_READ_ONLY. The error data echoes the active scope; check the server startup banner for the active configuration.";
679
+ }]>)[];
680
+ /** Combined base set — preserves the previous registration order. */
10
681
  export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
11
682
  target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
12
683
  type: import("zod").ZodLiteral<"path">;
@@ -41,7 +712,12 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
41
712
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
42
713
  path: import("zod").ZodString;
43
714
  sectionTargeted: import("zod").ZodBoolean;
44
- }, import("zod/v4/core").$strip>, undefined> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
715
+ }, import("zod/v4/core").$strip>, readonly [{
716
+ readonly reason: "path_forbidden";
717
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
718
+ readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
719
+ readonly recovery: "Use a path inside the configured write scope, or unset OBSIDIAN_READ_ONLY. The error data echoes the active scope; check the server startup banner for the active configuration.";
720
+ }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
45
721
  target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
46
722
  type: import("zod").ZodLiteral<"path">;
47
723
  path: import("zod").ZodString;
@@ -62,21 +738,35 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
62
738
  path: import("zod").ZodString;
63
739
  deleted: import("zod").ZodBoolean;
64
740
  }, import("zod/v4/core").$strip>, readonly [{
741
+ readonly reason: "path_forbidden";
742
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
743
+ readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
744
+ readonly recovery: "Use a path inside the configured write scope, or unset OBSIDIAN_READ_ONLY. The error data echoes the active scope; check the server startup banner for the active configuration.";
745
+ }, {
65
746
  readonly reason: "cancelled";
66
747
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.InvalidRequest;
67
748
  readonly when: "User declined the deletion via interactive elicitation.";
749
+ readonly recovery: "Re-run the tool when the user is ready to confirm deletion.";
68
750
  }, {
69
751
  readonly reason: "note_missing";
70
752
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
71
753
  readonly when: "The vault path does not resolve to an existing note.";
754
+ readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
72
755
  }, {
73
756
  readonly reason: "no_active_file";
74
757
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
75
758
  readonly when: "Target was `active` but no file is currently open in Obsidian.";
759
+ readonly recovery: "Open a note in Obsidian or pass an explicit path target instead.";
76
760
  }, {
77
761
  readonly reason: "periodic_not_found";
78
762
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
79
763
  readonly when: "Target was `periodic` but no matching periodic note exists.";
764
+ readonly recovery: "Pass an explicit path target — periodic notes must already exist.";
765
+ }, {
766
+ readonly reason: "periodic_disabled";
767
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
768
+ readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
769
+ readonly recovery: "Enable the period in Obsidian's Periodic Notes plugin settings, or pass an explicit path target instead.";
80
770
  }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
81
771
  format: import("zod").ZodEnum<{
82
772
  content: "content";
@@ -148,18 +838,32 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
148
838
  readonly reason: "section_required";
149
839
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
150
840
  readonly when: "`format` is \"section\" but no `section` locator was provided.";
841
+ readonly recovery: "Pass `section: { type, target }` (e.g. `{ type: \"heading\", target: \"Intro\" }`), or use `format: \"full\"` / `\"document-map\"` instead.";
842
+ }, {
843
+ readonly reason: "path_forbidden";
844
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
845
+ readonly when: "The target path is outside OBSIDIAN_READ_PATHS (and OBSIDIAN_WRITE_PATHS, since write paths imply read access).";
846
+ readonly recovery: "Use a path inside the configured read scope. The error data echoes the active scope; check the server startup banner for the active configuration.";
151
847
  }, {
152
848
  readonly reason: "note_missing";
153
849
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
154
850
  readonly when: "The vault path does not resolve to an existing note.";
851
+ readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
155
852
  }, {
156
853
  readonly reason: "no_active_file";
157
854
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
158
855
  readonly when: "Target was `active` but no file is currently open in Obsidian.";
856
+ readonly recovery: "Open a note in Obsidian or pass an explicit path target instead.";
159
857
  }, {
160
858
  readonly reason: "periodic_not_found";
161
859
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
162
860
  readonly when: "Target was `periodic` but no matching periodic note exists.";
861
+ readonly recovery: "Create the periodic note first or pass an explicit path target.";
862
+ }, {
863
+ readonly reason: "periodic_disabled";
864
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
865
+ readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
866
+ readonly recovery: "Enable the period in Obsidian's Periodic Notes plugin settings, or pass an explicit path target instead.";
163
867
  }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
164
868
  path: import("zod").ZodOptional<import("zod").ZodString>;
165
869
  extension: import("zod").ZodOptional<import("zod").ZodString>;
@@ -194,10 +898,17 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
194
898
  readonly reason: "regex_invalid";
195
899
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
196
900
  readonly when: "The supplied `nameRegex` is not a valid ECMAScript regex.";
901
+ readonly recovery: "Test the pattern (e.g. `^Project.*\\.md$`) in a JS regex tester, or omit nameRegex to disable filtering.";
902
+ }, {
903
+ readonly reason: "path_forbidden";
904
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
905
+ readonly when: "The supplied `path` is outside OBSIDIAN_READ_PATHS (root listings always pass; specific subdirectories must be readable).";
906
+ 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.";
197
907
  }, {
198
908
  readonly reason: "note_missing";
199
909
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
200
910
  readonly when: "The supplied `path` does not exist in the vault. Sub-directories that disappear mid-walk are silently skipped — only the root path surfaces this error.";
911
+ readonly recovery: "List a parent directory to find the correct casing or check the spelling.";
201
912
  }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
202
913
  tags: import("zod").ZodArray<import("zod").ZodObject<{
203
914
  name: import("zod").ZodString;
@@ -246,21 +957,35 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
246
957
  frontmatter: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
247
958
  }, import("zod/v4/core").$strip>], "operation">;
248
959
  }, import("zod/v4/core").$strip>, readonly [{
960
+ readonly reason: "path_forbidden";
961
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
962
+ readonly when: "`get` requires the path to be readable; `set`/`delete` require it to be inside OBSIDIAN_WRITE_PATHS, with OBSIDIAN_READ_ONLY=false.";
963
+ readonly recovery: "Use a path inside the configured scope, or unset OBSIDIAN_READ_ONLY for writes. The error data echoes the active scope; check the server startup banner for the active configuration.";
964
+ }, {
249
965
  readonly reason: "value_required";
250
966
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
251
967
  readonly when: "`operation` is \"set\" but no `value` was supplied.";
968
+ readonly recovery: "Pass `value` as any JSON-typed value: string, number, boolean, array, or object (e.g. `\"draft\"`, `42`, `true`, `[\"a\",\"b\"]`).";
252
969
  }, {
253
970
  readonly reason: "note_missing";
254
971
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
255
972
  readonly when: "The vault path does not resolve to an existing note.";
973
+ readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
256
974
  }, {
257
975
  readonly reason: "no_active_file";
258
976
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
259
977
  readonly when: "Target was `active` but no file is currently open in Obsidian.";
978
+ readonly recovery: "Open a note in Obsidian or pass an explicit path target instead.";
260
979
  }, {
261
980
  readonly reason: "periodic_not_found";
262
981
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
263
982
  readonly when: "Target was `periodic` but no matching periodic note exists.";
983
+ readonly recovery: "Create the periodic note first or pass an explicit path target.";
984
+ }, {
985
+ readonly reason: "periodic_disabled";
986
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
987
+ readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
988
+ readonly recovery: "Enable the period in Obsidian's Periodic Notes plugin settings, or pass an explicit path target instead.";
264
989
  }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
265
990
  target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
266
991
  type: import("zod").ZodLiteral<"path">;
@@ -312,21 +1037,35 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
312
1037
  tags: import("zod").ZodArray<import("zod").ZodString>;
313
1038
  }, import("zod/v4/core").$strip>], "operation">;
314
1039
  }, import("zod/v4/core").$strip>, readonly [{
1040
+ readonly reason: "path_forbidden";
1041
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
1042
+ readonly when: "`list` requires the path to be readable; `add`/`remove` require it to be inside OBSIDIAN_WRITE_PATHS, with OBSIDIAN_READ_ONLY=false.";
1043
+ readonly recovery: "Use a path inside the configured scope, or unset OBSIDIAN_READ_ONLY for writes. The error data echoes the active scope; check the server startup banner for the active configuration.";
1044
+ }, {
315
1045
  readonly reason: "tags_required";
316
1046
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
317
1047
  readonly when: "`operation` is \"add\" or \"remove\" but `tags` was empty or omitted.";
1048
+ readonly recovery: "Pass a non-empty `tags` array (without `#`), e.g. `[\"draft\", \"wip\"]`.";
318
1049
  }, {
319
1050
  readonly reason: "note_missing";
320
1051
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
321
1052
  readonly when: "The vault path does not resolve to an existing note.";
1053
+ readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
322
1054
  }, {
323
1055
  readonly reason: "no_active_file";
324
1056
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
325
1057
  readonly when: "Target was `active` but no file is currently open in Obsidian.";
1058
+ readonly recovery: "Open a note in Obsidian or pass an explicit path target instead.";
326
1059
  }, {
327
1060
  readonly reason: "periodic_not_found";
328
1061
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
329
1062
  readonly when: "Target was `periodic` but no matching periodic note exists.";
1063
+ readonly recovery: "Create the periodic note first or pass an explicit path target.";
1064
+ }, {
1065
+ readonly reason: "periodic_disabled";
1066
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
1067
+ readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
1068
+ readonly recovery: "Enable the period in Obsidian's Periodic Notes plugin settings, or pass an explicit path target instead.";
330
1069
  }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
331
1070
  path: import("zod").ZodString;
332
1071
  failIfMissing: import("zod").ZodDefault<import("zod").ZodBoolean>;
@@ -336,9 +1075,15 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
336
1075
  opened: import("zod").ZodBoolean;
337
1076
  createdIfMissing: import("zod").ZodBoolean;
338
1077
  }, import("zod/v4/core").$strip>, readonly [{
1078
+ readonly reason: "path_forbidden";
1079
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
1080
+ readonly when: "The target path is outside OBSIDIAN_READ_PATHS (and OBSIDIAN_WRITE_PATHS, since write paths imply read access).";
1081
+ readonly recovery: "Use a path inside the configured read scope. The error data echoes the active scope; check the server startup banner for the active configuration.";
1082
+ }, {
339
1083
  readonly reason: "note_missing";
340
1084
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
341
1085
  readonly when: "`failIfMissing: true` (default) and the path does not exist in the vault. Pass `failIfMissing: false` to allow Obsidian to create the file on open.";
1086
+ readonly recovery: "Verify the path with obsidian_list_notes or pass failIfMissing false to create on open.";
342
1087
  }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
343
1088
  target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
344
1089
  type: import("zod").ZodLiteral<"path">;
@@ -365,9 +1110,9 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
365
1110
  target: import("zod").ZodString;
366
1111
  }, import("zod/v4/core").$strip>;
367
1112
  operation: import("zod").ZodEnum<{
1113
+ replace: "replace";
368
1114
  append: "append";
369
1115
  prepend: "prepend";
370
- replace: "replace";
371
1116
  }>;
372
1117
  content: import("zod").ZodString;
373
1118
  contentType: import("zod").ZodDefault<import("zod").ZodEnum<{
@@ -390,26 +1135,40 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
390
1135
  target: import("zod").ZodString;
391
1136
  }, import("zod/v4/core").$strip>;
392
1137
  operation: import("zod").ZodEnum<{
1138
+ replace: "replace";
393
1139
  append: "append";
394
1140
  prepend: "prepend";
395
- replace: "replace";
396
1141
  }>;
397
1142
  }, import("zod/v4/core").$strip>, readonly [{
1143
+ readonly reason: "path_forbidden";
1144
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
1145
+ readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
1146
+ readonly recovery: "Use a path inside the configured write scope, or unset OBSIDIAN_READ_ONLY. The error data echoes the active scope; check the server startup banner for the active configuration.";
1147
+ }, {
398
1148
  readonly reason: "note_missing";
399
1149
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
400
1150
  readonly when: "The vault path does not resolve to an existing note.";
1151
+ readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
401
1152
  }, {
402
1153
  readonly reason: "no_active_file";
403
1154
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
404
1155
  readonly when: "Target was `active` but no file is currently open in Obsidian.";
1156
+ readonly recovery: "Open a note in Obsidian or pass an explicit path target instead.";
405
1157
  }, {
406
1158
  readonly reason: "periodic_not_found";
407
1159
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
408
1160
  readonly when: "Target was `periodic` but no matching periodic note exists.";
1161
+ readonly recovery: "Create the periodic note first or pass an explicit path target.";
1162
+ }, {
1163
+ readonly reason: "periodic_disabled";
1164
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
1165
+ readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
1166
+ readonly recovery: "Enable the period in Obsidian's Periodic Notes plugin settings, or pass an explicit path target instead.";
409
1167
  }, {
410
1168
  readonly reason: "section_target_missing";
411
1169
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
412
1170
  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.";
1171
+ readonly recovery: "Call obsidian_get_note with format document-map to discover the available targets.";
413
1172
  }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
414
1173
  target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
415
1174
  type: import("zod").ZodLiteral<"path">;
@@ -444,21 +1203,35 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
444
1203
  count: import("zod").ZodNumber;
445
1204
  }, import("zod/v4/core").$strip>>;
446
1205
  }, import("zod/v4/core").$strip>, readonly [{
1206
+ readonly reason: "path_forbidden";
1207
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
1208
+ 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.)";
1209
+ readonly recovery: "Use a path inside the configured write scope, or unset OBSIDIAN_READ_ONLY. The error data echoes the active scope; check the server startup banner for the active configuration.";
1210
+ }, {
447
1211
  readonly reason: "regex_invalid";
448
1212
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
449
1213
  readonly when: "A `useRegex: true` replacement supplied a `search` pattern that is not a valid ECMAScript regex.";
1214
+ readonly recovery: "Test the pattern in a JS regex tester, or set useRegex to false to match `search` as a literal string.";
450
1215
  }, {
451
1216
  readonly reason: "note_missing";
452
1217
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
453
1218
  readonly when: "The vault path does not resolve to an existing note.";
1219
+ readonly recovery: "Verify the path with obsidian_list_notes or use obsidian_search_notes to locate the note.";
454
1220
  }, {
455
1221
  readonly reason: "no_active_file";
456
1222
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
457
1223
  readonly when: "Target was `active` but no file is currently open in Obsidian.";
1224
+ readonly recovery: "Open a note in Obsidian or pass an explicit path target instead.";
458
1225
  }, {
459
1226
  readonly reason: "periodic_not_found";
460
1227
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
461
1228
  readonly when: "Target was `periodic` but no matching periodic note exists.";
1229
+ readonly recovery: "Create the periodic note first or pass an explicit path target.";
1230
+ }, {
1231
+ readonly reason: "periodic_disabled";
1232
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
1233
+ readonly when: "Target was `periodic` but the requested period is not enabled in Obsidian's Periodic Notes plugin settings.";
1234
+ readonly recovery: "Enable the period in Obsidian's Periodic Notes plugin settings, or pass an explicit path target instead.";
462
1235
  }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
463
1236
  mode: import("zod").ZodEnum<{
464
1237
  text: "text";
@@ -515,14 +1288,17 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
515
1288
  readonly reason: "path_prefix_invalid_mode";
516
1289
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
517
1290
  readonly when: "`pathPrefix` was provided in a non-text mode (only `text` supports prefix filtering).";
1291
+ readonly recovery: "Drop pathPrefix or switch mode to text for prefix filtering.";
518
1292
  }, {
519
1293
  readonly reason: "query_required";
520
1294
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
521
1295
  readonly when: "`query` is missing for `text` or `dataview` mode (required for both).";
1296
+ readonly recovery: "Pass `query` — search terms for text mode (e.g. \"TODO\"), or DQL like \"TABLE WHERE file.mtime > date(today)\" for dataview mode.";
522
1297
  }, {
523
1298
  readonly reason: "logic_required";
524
1299
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.ValidationError;
525
1300
  readonly when: "`logic` is missing for `jsonlogic` mode.";
1301
+ readonly recovery: "Pass a JSONLogic tree as `logic`, e.g. `{\"glob\": [{\"var\": \"path\"}, \"Projects/*.md\"]}`.";
526
1302
  }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
527
1303
  target: import("zod").ZodDiscriminatedUnion<[import("zod").ZodObject<{
528
1304
  type: import("zod").ZodLiteral<"path">;
@@ -562,8 +1338,14 @@ export declare const baseToolDefinitions: (import("@cyanheads/mcp-ts-core").Tool
562
1338
  readonly reason: "file_exists";
563
1339
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Conflict;
564
1340
  readonly when: "Whole-file write was attempted against an existing note and `overwrite` was not set to `true`.";
1341
+ readonly recovery: "Retry with overwrite true or use obsidian_patch_note for in-place edits.";
1342
+ }, {
1343
+ readonly reason: "path_forbidden";
1344
+ readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.Forbidden;
1345
+ readonly when: "The target path is outside OBSIDIAN_WRITE_PATHS, or OBSIDIAN_READ_ONLY=true denies all writes.";
1346
+ readonly recovery: "Use a path inside the configured write scope, or unset OBSIDIAN_READ_ONLY. The error data echoes the active scope; check the server startup banner for the active configuration.";
565
1347
  }]>)[];
566
- /** Command-palette tools — registered only when `OBSIDIAN_ENABLE_COMMANDS=true`. */
1348
+ /** Command-palette tools — opt-in via `OBSIDIAN_ENABLE_COMMANDS=true`; suppressed by `OBSIDIAN_READ_ONLY=true`. */
567
1349
  export declare const commandToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
568
1350
  commandId: import("zod").ZodString;
569
1351
  }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
@@ -573,6 +1355,7 @@ export declare const commandToolDefinitions: (import("@cyanheads/mcp-ts-core").T
573
1355
  readonly reason: "command_unknown";
574
1356
  readonly code: import("@cyanheads/mcp-ts-core/errors").JsonRpcErrorCode.NotFound;
575
1357
  readonly when: "The supplied `commandId` is not registered in Obsidian. Use `obsidian_list_commands` to discover valid IDs.";
1358
+ readonly recovery: "Call obsidian_list_commands to discover the registered command IDs.";
576
1359
  }]> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
577
1360
  commands: import("zod").ZodArray<import("zod").ZodObject<{
578
1361
  id: import("zod").ZodString;