obsidian-mcp-server 2.0.7 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/CLAUDE.md +364 -0
  2. package/Dockerfile +99 -0
  3. package/LICENSE +4 -6
  4. package/README.md +246 -206
  5. package/changelog/3.0.x/3.0.0.md +102 -0
  6. package/changelog/3.1.x/3.1.0.md +26 -0
  7. package/changelog/template.md +51 -0
  8. package/dist/config/server-config.d.ts +19 -0
  9. package/dist/config/server-config.d.ts.map +1 -0
  10. package/dist/config/server-config.js +55 -0
  11. package/dist/config/server-config.js.map +1 -0
  12. package/dist/index.d.ts +7 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +23 -295
  15. package/dist/index.js.map +1 -0
  16. package/dist/mcp-server/prompts/definitions/index.d.ts +8 -0
  17. package/dist/mcp-server/prompts/definitions/index.d.ts.map +1 -0
  18. package/dist/mcp-server/prompts/definitions/index.js +8 -0
  19. package/dist/mcp-server/prompts/definitions/index.js.map +1 -0
  20. package/dist/mcp-server/resources/definitions/index.d.ts +36 -0
  21. package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -0
  22. package/dist/mcp-server/resources/definitions/index.js +9 -0
  23. package/dist/mcp-server/resources/definitions/index.js.map +1 -0
  24. package/dist/mcp-server/resources/definitions/obsidian-status.resource.d.ts +23 -0
  25. package/dist/mcp-server/resources/definitions/obsidian-status.resource.d.ts.map +1 -0
  26. package/dist/mcp-server/resources/definitions/obsidian-status.resource.js +47 -0
  27. package/dist/mcp-server/resources/definitions/obsidian-status.resource.js.map +1 -0
  28. package/dist/mcp-server/resources/definitions/obsidian-tags.resource.d.ts +13 -0
  29. package/dist/mcp-server/resources/definitions/obsidian-tags.resource.d.ts.map +1 -0
  30. package/dist/mcp-server/resources/definitions/obsidian-tags.resource.js +30 -0
  31. package/dist/mcp-server/resources/definitions/obsidian-tags.resource.js.map +1 -0
  32. package/dist/mcp-server/resources/definitions/obsidian-vault-note.resource.d.ts +21 -0
  33. package/dist/mcp-server/resources/definitions/obsidian-vault-note.resource.d.ts.map +1 -0
  34. package/dist/mcp-server/resources/definitions/obsidian-vault-note.resource.js +38 -0
  35. package/dist/mcp-server/resources/definitions/obsidian-vault-note.resource.js.map +1 -0
  36. package/dist/mcp-server/tools/definitions/_shared/schemas.d.ts +45 -0
  37. package/dist/mcp-server/tools/definitions/_shared/schemas.d.ts.map +1 -0
  38. package/dist/mcp-server/tools/definitions/_shared/schemas.js +66 -0
  39. package/dist/mcp-server/tools/definitions/_shared/schemas.js.map +1 -0
  40. package/dist/mcp-server/tools/definitions/_shared/suggest-paths.d.ts +51 -0
  41. package/dist/mcp-server/tools/definitions/_shared/suggest-paths.d.ts.map +1 -0
  42. package/dist/mcp-server/tools/definitions/_shared/suggest-paths.js +120 -0
  43. package/dist/mcp-server/tools/definitions/_shared/suggest-paths.js.map +1 -0
  44. package/dist/mcp-server/tools/definitions/index.d.ts +582 -0
  45. package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
  46. package/dist/mcp-server/tools/definitions/index.js +40 -0
  47. package/dist/mcp-server/tools/definitions/index.js.map +1 -0
  48. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts +42 -0
  49. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts.map +1 -0
  50. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js +58 -0
  51. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js.map +1 -0
  52. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts +46 -0
  53. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts.map +1 -0
  54. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.js +66 -0
  55. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.js.map +1 -0
  56. package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.d.ts +19 -0
  57. package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.d.ts.map +1 -0
  58. package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.js +43 -0
  59. package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.js.map +1 -0
  60. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.d.ts +92 -0
  61. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.d.ts.map +1 -0
  62. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.js +245 -0
  63. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.js.map +1 -0
  64. package/dist/mcp-server/tools/definitions/obsidian-list-commands.tool.d.ts +13 -0
  65. package/dist/mcp-server/tools/definitions/obsidian-list-commands.tool.d.ts.map +1 -0
  66. package/dist/mcp-server/tools/definitions/obsidian-list-commands.tool.js +38 -0
  67. package/dist/mcp-server/tools/definitions/obsidian-list-commands.tool.js.map +1 -0
  68. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.d.ts +59 -0
  69. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.d.ts.map +1 -0
  70. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.js +273 -0
  71. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.js.map +1 -0
  72. package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.d.ts +13 -0
  73. package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.d.ts.map +1 -0
  74. package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.js +38 -0
  75. package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.js.map +1 -0
  76. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts +68 -0
  77. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts.map +1 -0
  78. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.js +178 -0
  79. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.js.map +1 -0
  80. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts +77 -0
  81. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts.map +1 -0
  82. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.js +172 -0
  83. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.js.map +1 -0
  84. package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.d.ts +22 -0
  85. package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.d.ts.map +1 -0
  86. package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.js +88 -0
  87. package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.js.map +1 -0
  88. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts +81 -0
  89. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts.map +1 -0
  90. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js +83 -0
  91. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js.map +1 -0
  92. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts +59 -0
  93. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts.map +1 -0
  94. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js +167 -0
  95. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js.map +1 -0
  96. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts +76 -0
  97. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts.map +1 -0
  98. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js +244 -0
  99. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js.map +1 -0
  100. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts +48 -0
  101. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts.map +1 -0
  102. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js +100 -0
  103. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js.map +1 -0
  104. package/dist/services/obsidian/frontmatter-ops.d.ts +34 -0
  105. package/dist/services/obsidian/frontmatter-ops.d.ts.map +1 -0
  106. package/dist/services/obsidian/frontmatter-ops.js +230 -0
  107. package/dist/services/obsidian/frontmatter-ops.js.map +1 -0
  108. package/dist/services/obsidian/obsidian-service.d.ts +83 -0
  109. package/dist/services/obsidian/obsidian-service.d.ts.map +1 -0
  110. package/dist/services/obsidian/obsidian-service.js +435 -0
  111. package/dist/services/obsidian/obsidian-service.js.map +1 -0
  112. package/dist/services/obsidian/section-extractor.d.ts +13 -0
  113. package/dist/services/obsidian/section-extractor.d.ts.map +1 -0
  114. package/dist/services/obsidian/section-extractor.js +124 -0
  115. package/dist/services/obsidian/section-extractor.js.map +1 -0
  116. package/dist/services/obsidian/types.d.ts +91 -0
  117. package/dist/services/obsidian/types.d.ts.map +1 -0
  118. package/dist/services/obsidian/types.js +7 -0
  119. package/dist/services/obsidian/types.js.map +1 -0
  120. package/package.json +63 -69
  121. package/server.json +167 -0
  122. package/CHANGELOG.md +0 -124
  123. package/dist/config/index.d.ts +0 -41
  124. package/dist/config/index.js +0 -191
  125. package/dist/mcp-server/server.d.ts +0 -33
  126. package/dist/mcp-server/server.js +0 -211
  127. package/dist/mcp-server/tools/obsidianDeleteNoteTool/index.d.ts +0 -12
  128. package/dist/mcp-server/tools/obsidianDeleteNoteTool/index.js +0 -12
  129. package/dist/mcp-server/tools/obsidianDeleteNoteTool/logic.d.ts +0 -51
  130. package/dist/mcp-server/tools/obsidianDeleteNoteTool/logic.js +0 -168
  131. package/dist/mcp-server/tools/obsidianDeleteNoteTool/registration.d.ts +0 -19
  132. package/dist/mcp-server/tools/obsidianDeleteNoteTool/registration.js +0 -91
  133. package/dist/mcp-server/tools/obsidianGlobalSearchTool/index.d.ts +0 -12
  134. package/dist/mcp-server/tools/obsidianGlobalSearchTool/index.js +0 -12
  135. package/dist/mcp-server/tools/obsidianGlobalSearchTool/logic.d.ts +0 -77
  136. package/dist/mcp-server/tools/obsidianGlobalSearchTool/logic.js +0 -341
  137. package/dist/mcp-server/tools/obsidianGlobalSearchTool/registration.d.ts +0 -18
  138. package/dist/mcp-server/tools/obsidianGlobalSearchTool/registration.js +0 -69
  139. package/dist/mcp-server/tools/obsidianListNotesTool/index.d.ts +0 -12
  140. package/dist/mcp-server/tools/obsidianListNotesTool/index.js +0 -12
  141. package/dist/mcp-server/tools/obsidianListNotesTool/logic.d.ts +0 -68
  142. package/dist/mcp-server/tools/obsidianListNotesTool/logic.js +0 -215
  143. package/dist/mcp-server/tools/obsidianListNotesTool/registration.d.ts +0 -23
  144. package/dist/mcp-server/tools/obsidianListNotesTool/registration.js +0 -98
  145. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/index.d.ts +0 -3
  146. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/index.js +0 -2
  147. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/logic.d.ts +0 -42
  148. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/logic.js +0 -152
  149. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/registration.d.ts +0 -3
  150. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/registration.js +0 -52
  151. package/dist/mcp-server/tools/obsidianManageTagsTool/index.d.ts +0 -3
  152. package/dist/mcp-server/tools/obsidianManageTagsTool/index.js +0 -2
  153. package/dist/mcp-server/tools/obsidianManageTagsTool/logic.d.ts +0 -28
  154. package/dist/mcp-server/tools/obsidianManageTagsTool/logic.js +0 -161
  155. package/dist/mcp-server/tools/obsidianManageTagsTool/registration.d.ts +0 -3
  156. package/dist/mcp-server/tools/obsidianManageTagsTool/registration.js +0 -52
  157. package/dist/mcp-server/tools/obsidianReadNoteTool/index.d.ts +0 -12
  158. package/dist/mcp-server/tools/obsidianReadNoteTool/index.js +0 -12
  159. package/dist/mcp-server/tools/obsidianReadNoteTool/logic.d.ts +0 -87
  160. package/dist/mcp-server/tools/obsidianReadNoteTool/logic.js +0 -216
  161. package/dist/mcp-server/tools/obsidianReadNoteTool/registration.d.ts +0 -20
  162. package/dist/mcp-server/tools/obsidianReadNoteTool/registration.js +0 -101
  163. package/dist/mcp-server/tools/obsidianSearchReplaceTool/index.d.ts +0 -12
  164. package/dist/mcp-server/tools/obsidianSearchReplaceTool/index.js +0 -12
  165. package/dist/mcp-server/tools/obsidianSearchReplaceTool/logic.d.ts +0 -255
  166. package/dist/mcp-server/tools/obsidianSearchReplaceTool/logic.js +0 -583
  167. package/dist/mcp-server/tools/obsidianSearchReplaceTool/registration.d.ts +0 -22
  168. package/dist/mcp-server/tools/obsidianSearchReplaceTool/registration.js +0 -111
  169. package/dist/mcp-server/tools/obsidianUpdateNoteTool/index.d.ts +0 -12
  170. package/dist/mcp-server/tools/obsidianUpdateNoteTool/index.js +0 -12
  171. package/dist/mcp-server/tools/obsidianUpdateNoteTool/logic.d.ts +0 -183
  172. package/dist/mcp-server/tools/obsidianUpdateNoteTool/logic.js +0 -490
  173. package/dist/mcp-server/tools/obsidianUpdateNoteTool/registration.d.ts +0 -21
  174. package/dist/mcp-server/tools/obsidianUpdateNoteTool/registration.js +0 -108
  175. package/dist/mcp-server/transports/auth/core/authContext.d.ts +0 -33
  176. package/dist/mcp-server/transports/auth/core/authContext.js +0 -24
  177. package/dist/mcp-server/transports/auth/core/authTypes.d.ts +0 -17
  178. package/dist/mcp-server/transports/auth/core/authTypes.js +0 -5
  179. package/dist/mcp-server/transports/auth/core/authUtils.d.ts +0 -18
  180. package/dist/mcp-server/transports/auth/core/authUtils.js +0 -45
  181. package/dist/mcp-server/transports/auth/index.d.ts +0 -10
  182. package/dist/mcp-server/transports/auth/index.js +0 -9
  183. package/dist/mcp-server/transports/auth/strategies/jwt/jwtMiddleware.d.ts +0 -27
  184. package/dist/mcp-server/transports/auth/strategies/jwt/jwtMiddleware.js +0 -149
  185. package/dist/mcp-server/transports/auth/strategies/oauth/oauthMiddleware.d.ts +0 -20
  186. package/dist/mcp-server/transports/auth/strategies/oauth/oauthMiddleware.js +0 -124
  187. package/dist/mcp-server/transports/httpErrorHandler.d.ts +0 -26
  188. package/dist/mcp-server/transports/httpErrorHandler.js +0 -73
  189. package/dist/mcp-server/transports/httpTransport.d.ts +0 -21
  190. package/dist/mcp-server/transports/httpTransport.js +0 -208
  191. package/dist/mcp-server/transports/stdioTransport.d.ts +0 -42
  192. package/dist/mcp-server/transports/stdioTransport.js +0 -63
  193. package/dist/services/obsidianRestAPI/index.d.ts +0 -15
  194. package/dist/services/obsidianRestAPI/index.js +0 -17
  195. package/dist/services/obsidianRestAPI/methods/activeFileMethods.d.ts +0 -38
  196. package/dist/services/obsidianRestAPI/methods/activeFileMethods.js +0 -62
  197. package/dist/services/obsidianRestAPI/methods/commandMethods.d.ts +0 -22
  198. package/dist/services/obsidianRestAPI/methods/commandMethods.js +0 -31
  199. package/dist/services/obsidianRestAPI/methods/openMethods.d.ts +0 -16
  200. package/dist/services/obsidianRestAPI/methods/openMethods.js +0 -21
  201. package/dist/services/obsidianRestAPI/methods/patchMethods.d.ts +0 -37
  202. package/dist/services/obsidianRestAPI/methods/patchMethods.js +0 -94
  203. package/dist/services/obsidianRestAPI/methods/periodicNoteMethods.d.ts +0 -42
  204. package/dist/services/obsidianRestAPI/methods/periodicNoteMethods.js +0 -66
  205. package/dist/services/obsidianRestAPI/methods/searchMethods.d.ts +0 -25
  206. package/dist/services/obsidianRestAPI/methods/searchMethods.js +0 -36
  207. package/dist/services/obsidianRestAPI/methods/vaultMethods.d.ts +0 -58
  208. package/dist/services/obsidianRestAPI/methods/vaultMethods.js +0 -144
  209. package/dist/services/obsidianRestAPI/service.d.ts +0 -195
  210. package/dist/services/obsidianRestAPI/service.js +0 -379
  211. package/dist/services/obsidianRestAPI/types.d.ts +0 -127
  212. package/dist/services/obsidianRestAPI/types.js +0 -7
  213. package/dist/services/obsidianRestAPI/vaultCache/index.d.ts +0 -4
  214. package/dist/services/obsidianRestAPI/vaultCache/index.js +0 -4
  215. package/dist/services/obsidianRestAPI/vaultCache/service.d.ts +0 -88
  216. package/dist/services/obsidianRestAPI/vaultCache/service.js +0 -299
  217. package/dist/types-global/errors.d.ts +0 -73
  218. package/dist/types-global/errors.js +0 -71
  219. package/dist/utils/index.d.ts +0 -5
  220. package/dist/utils/index.js +0 -13
  221. package/dist/utils/internal/asyncUtils.d.ts +0 -54
  222. package/dist/utils/internal/asyncUtils.js +0 -101
  223. package/dist/utils/internal/errorHandler.d.ts +0 -176
  224. package/dist/utils/internal/errorHandler.js +0 -351
  225. package/dist/utils/internal/index.d.ts +0 -4
  226. package/dist/utils/internal/index.js +0 -4
  227. package/dist/utils/internal/logger.d.ts +0 -141
  228. package/dist/utils/internal/logger.js +0 -406
  229. package/dist/utils/internal/requestContext.d.ts +0 -83
  230. package/dist/utils/internal/requestContext.js +0 -72
  231. package/dist/utils/metrics/index.d.ts +0 -1
  232. package/dist/utils/metrics/index.js +0 -1
  233. package/dist/utils/metrics/tokenCounter.d.ts +0 -27
  234. package/dist/utils/metrics/tokenCounter.js +0 -128
  235. package/dist/utils/obsidian/index.d.ts +0 -5
  236. package/dist/utils/obsidian/index.js +0 -5
  237. package/dist/utils/obsidian/obsidianApiUtils.d.ts +0 -14
  238. package/dist/utils/obsidian/obsidianApiUtils.js +0 -29
  239. package/dist/utils/obsidian/obsidianStatUtils.d.ts +0 -68
  240. package/dist/utils/obsidian/obsidianStatUtils.js +0 -143
  241. package/dist/utils/parsing/dateParser.d.ts +0 -56
  242. package/dist/utils/parsing/dateParser.js +0 -104
  243. package/dist/utils/parsing/index.d.ts +0 -2
  244. package/dist/utils/parsing/index.js +0 -3
  245. package/dist/utils/parsing/jsonParser.d.ts +0 -80
  246. package/dist/utils/parsing/jsonParser.js +0 -133
  247. package/dist/utils/security/idGenerator.d.ts +0 -140
  248. package/dist/utils/security/idGenerator.js +0 -194
  249. package/dist/utils/security/index.d.ts +0 -3
  250. package/dist/utils/security/index.js +0 -3
  251. package/dist/utils/security/rateLimiter.d.ts +0 -156
  252. package/dist/utils/security/rateLimiter.js +0 -235
  253. package/dist/utils/security/sanitization.d.ts +0 -244
  254. package/dist/utils/security/sanitization.js +0 -599
@@ -0,0 +1,178 @@
1
+ /**
2
+ * @fileoverview obsidian_manage_frontmatter — atomic get/set/delete on a single
3
+ * frontmatter key. `set` PATCHes the field; `delete` reads-modifies-writes the
4
+ * file because PATCH has no `delete` operation.
5
+ * @module mcp-server/tools/definitions/obsidian-manage-frontmatter.tool
6
+ */
7
+ import { tool, z } from '@cyanheads/mcp-ts-core';
8
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
9
+ import { deleteFrontmatterKey } from '../../../services/obsidian/frontmatter-ops.js';
10
+ import { getObsidianService } from '../../../services/obsidian/obsidian-service.js';
11
+ import { TargetSchema } from './_shared/schemas.js';
12
+ export const obsidianManageFrontmatter = tool('obsidian_manage_frontmatter', {
13
+ description: 'Atomic `get` / `set` / `delete` on a single frontmatter key. `set` requires `value` (any JSON-typed value: string, number, boolean, array, or object).',
14
+ annotations: { destructiveHint: true },
15
+ input: z.object({
16
+ operation: z
17
+ .enum(['get', 'set', 'delete'])
18
+ .describe('Which mutation/read to perform on the key.'),
19
+ target: TargetSchema.describe('Where the note lives.'),
20
+ key: z.string().min(1).describe('Frontmatter field name.'),
21
+ value: z
22
+ .unknown()
23
+ .optional()
24
+ .describe('Required when `operation` is `"set"`. JSON-typed value to write — strings, numbers, booleans, arrays, and objects all accepted.'),
25
+ }),
26
+ output: z.object({
27
+ result: z
28
+ .discriminatedUnion('operation', [
29
+ z
30
+ .object({
31
+ operation: z.literal('get').describe('Echoed operation.'),
32
+ path: z.string().describe('Resolved vault-relative path.'),
33
+ key: z.string().describe('Echoed frontmatter key.'),
34
+ exists: z.boolean().describe('True when the key was present in the frontmatter.'),
35
+ value: z.unknown().describe('Current value, or `null` when the key is absent.'),
36
+ })
37
+ .describe('Result for `get`.'),
38
+ z
39
+ .object({
40
+ operation: z.literal('set').describe('Echoed operation.'),
41
+ path: z.string().describe('Resolved vault-relative path.'),
42
+ key: z.string().describe('Echoed frontmatter key.'),
43
+ frontmatter: z
44
+ .record(z.string(), z.unknown())
45
+ .describe('Full frontmatter after the change.'),
46
+ })
47
+ .describe('Result for `set`.'),
48
+ z
49
+ .object({
50
+ operation: z.literal('delete').describe('Echoed operation.'),
51
+ path: z.string().describe('Resolved vault-relative path.'),
52
+ key: z.string().describe('Echoed frontmatter key.'),
53
+ frontmatter: z
54
+ .record(z.string(), z.unknown())
55
+ .describe('Full frontmatter after the change.'),
56
+ })
57
+ .describe('Result for `delete`.'),
58
+ ])
59
+ .describe('Operation-discriminated result payload.'),
60
+ }),
61
+ auth: ['tool:obsidian_manage_frontmatter:write'],
62
+ errors: [
63
+ {
64
+ reason: 'value_required',
65
+ code: JsonRpcErrorCode.ValidationError,
66
+ when: '`operation` is "set" but no `value` was supplied.',
67
+ },
68
+ {
69
+ reason: 'note_missing',
70
+ code: JsonRpcErrorCode.NotFound,
71
+ when: 'The vault path does not resolve to an existing note.',
72
+ },
73
+ {
74
+ reason: 'no_active_file',
75
+ code: JsonRpcErrorCode.NotFound,
76
+ when: 'Target was `active` but no file is currently open in Obsidian.',
77
+ },
78
+ {
79
+ reason: 'periodic_not_found',
80
+ code: JsonRpcErrorCode.NotFound,
81
+ when: 'Target was `periodic` but no matching periodic note exists.',
82
+ },
83
+ ],
84
+ async handler(input, ctx) {
85
+ const svc = getObsidianService();
86
+ const { target } = input;
87
+ if (input.operation === 'get') {
88
+ const note = await svc.getNoteJson(ctx, target);
89
+ const exists = input.key in note.frontmatter;
90
+ return {
91
+ result: {
92
+ operation: 'get',
93
+ path: note.path,
94
+ key: input.key,
95
+ exists,
96
+ value: exists ? note.frontmatter[input.key] : null,
97
+ },
98
+ };
99
+ }
100
+ if (input.operation === 'set') {
101
+ if (input.value === undefined) {
102
+ throw ctx.fail('value_required', '`value` is required when operation is "set".', {
103
+ operation: input.operation,
104
+ });
105
+ }
106
+ await svc.patchNote(ctx, target, JSON.stringify(input.value), {
107
+ operation: 'replace',
108
+ targetType: 'frontmatter',
109
+ target: input.key,
110
+ contentType: 'json',
111
+ createTargetIfMissing: true,
112
+ });
113
+ const note = await svc.getNoteJson(ctx, target);
114
+ return {
115
+ result: {
116
+ operation: 'set',
117
+ path: note.path,
118
+ key: input.key,
119
+ frontmatter: note.frontmatter,
120
+ },
121
+ };
122
+ }
123
+ const note = await svc.getNoteJson(ctx, target);
124
+ const newContent = deleteFrontmatterKey(note.content, input.key);
125
+ if (newContent !== note.content) {
126
+ await svc.writeNote(ctx, target, newContent, 'markdown');
127
+ }
128
+ const projected = { ...note.frontmatter };
129
+ delete projected[input.key];
130
+ return {
131
+ result: {
132
+ operation: 'delete',
133
+ path: note.path,
134
+ key: input.key,
135
+ frontmatter: projected,
136
+ },
137
+ };
138
+ },
139
+ format: ({ result }) => {
140
+ if (result.operation === 'get') {
141
+ const valueStr = result.exists ? formatValue(result.value) : '_(absent)_';
142
+ return [
143
+ {
144
+ type: 'text',
145
+ text: [
146
+ `**Frontmatter ${result.operation} \`${result.key}\` in ${result.path}**`,
147
+ `*Exists:* ${result.exists}`,
148
+ '*Value:*',
149
+ valueStr,
150
+ ].join('\n'),
151
+ },
152
+ ];
153
+ }
154
+ const fmKeys = Object.keys(result.frontmatter);
155
+ const lines = [
156
+ `**Frontmatter ${result.operation} \`${result.key}\` in ${result.path}**`,
157
+ '',
158
+ `**Frontmatter (${fmKeys.length} keys after change)**`,
159
+ ];
160
+ if (fmKeys.length === 0) {
161
+ lines.push('_(empty)_');
162
+ }
163
+ else {
164
+ for (const k of fmKeys) {
165
+ lines.push(`- \`${k}\`: ${formatValue(result.frontmatter[k])}`);
166
+ }
167
+ }
168
+ return [{ type: 'text', text: lines.join('\n') }];
169
+ },
170
+ });
171
+ function formatValue(v) {
172
+ if (v === null || v === undefined)
173
+ return '`null`';
174
+ if (typeof v === 'string')
175
+ return v;
176
+ return `\`${JSON.stringify(v)}\``;
177
+ }
178
+ //# sourceMappingURL=obsidian-manage-frontmatter.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obsidian-manage-frontmatter.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @fileoverview obsidian_manage_tags — add/remove/list tags across both
3
+ * frontmatter (`tags:` array) and inline (`#tag`) syntax. The service layer
4
+ * reconciles both representations; inline matches inside fenced code blocks
5
+ * are left alone.
6
+ * @module mcp-server/tools/definitions/obsidian-manage-tags.tool
7
+ */
8
+ import { z } from '@cyanheads/mcp-ts-core';
9
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
10
+ export declare const obsidianManageTags: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
11
+ target: z.ZodDiscriminatedUnion<[z.ZodObject<{
12
+ type: z.ZodLiteral<"path">;
13
+ path: z.ZodString;
14
+ }, z.core.$strip>, z.ZodObject<{
15
+ type: z.ZodLiteral<"active">;
16
+ }, z.core.$strip>, z.ZodObject<{
17
+ type: z.ZodLiteral<"periodic">;
18
+ period: z.ZodEnum<{
19
+ daily: "daily";
20
+ weekly: "weekly";
21
+ monthly: "monthly";
22
+ quarterly: "quarterly";
23
+ yearly: "yearly";
24
+ }>;
25
+ date: z.ZodOptional<z.ZodString>;
26
+ }, z.core.$strip>], "type">;
27
+ operation: z.ZodEnum<{
28
+ list: "list";
29
+ add: "add";
30
+ remove: "remove";
31
+ }>;
32
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
33
+ location: z.ZodDefault<z.ZodEnum<{
34
+ frontmatter: "frontmatter";
35
+ inline: "inline";
36
+ both: "both";
37
+ }>>;
38
+ }, z.core.$strip>, z.ZodObject<{
39
+ result: z.ZodDiscriminatedUnion<[z.ZodObject<{
40
+ operation: z.ZodLiteral<"list">;
41
+ path: z.ZodString;
42
+ tags: z.ZodObject<{
43
+ frontmatter: z.ZodArray<z.ZodString>;
44
+ inline: z.ZodArray<z.ZodString>;
45
+ all: z.ZodArray<z.ZodString>;
46
+ }, z.core.$strip>;
47
+ }, z.core.$strip>, z.ZodObject<{
48
+ operation: z.ZodLiteral<"add">;
49
+ path: z.ZodString;
50
+ applied: z.ZodArray<z.ZodString>;
51
+ skipped: z.ZodArray<z.ZodString>;
52
+ tags: z.ZodArray<z.ZodString>;
53
+ }, z.core.$strip>, z.ZodObject<{
54
+ operation: z.ZodLiteral<"remove">;
55
+ path: z.ZodString;
56
+ applied: z.ZodArray<z.ZodString>;
57
+ skipped: z.ZodArray<z.ZodString>;
58
+ tags: z.ZodArray<z.ZodString>;
59
+ }, z.core.$strip>], "operation">;
60
+ }, z.core.$strip>, readonly [{
61
+ readonly reason: "tags_required";
62
+ readonly code: JsonRpcErrorCode.ValidationError;
63
+ readonly when: "`operation` is \"add\" or \"remove\" but `tags` was empty or omitted.";
64
+ }, {
65
+ readonly reason: "note_missing";
66
+ readonly code: JsonRpcErrorCode.NotFound;
67
+ readonly when: "The vault path does not resolve to an existing note.";
68
+ }, {
69
+ readonly reason: "no_active_file";
70
+ readonly code: JsonRpcErrorCode.NotFound;
71
+ readonly when: "Target was `active` but no file is currently open in Obsidian.";
72
+ }, {
73
+ readonly reason: "periodic_not_found";
74
+ readonly code: JsonRpcErrorCode.NotFound;
75
+ readonly when: "Target was `periodic` but no matching periodic note exists.";
76
+ }]>;
77
+ //# sourceMappingURL=obsidian-manage-tags.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obsidian-manage-tags.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-manage-tags.tool.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAUjE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiK7B,CAAC"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * @fileoverview obsidian_manage_tags — add/remove/list tags across both
3
+ * frontmatter (`tags:` array) and inline (`#tag`) syntax. The service layer
4
+ * reconciles both representations; inline matches inside fenced code blocks
5
+ * are left alone.
6
+ * @module mcp-server/tools/definitions/obsidian-manage-tags.tool
7
+ */
8
+ import { tool, z } from '@cyanheads/mcp-ts-core';
9
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
10
+ import { listTagsFromContent, reconcileTags } from '../../../services/obsidian/frontmatter-ops.js';
11
+ import { getObsidianService } from '../../../services/obsidian/obsidian-service.js';
12
+ import { TargetSchema } from './_shared/schemas.js';
13
+ const LocationSchema = z
14
+ .enum(['frontmatter', 'inline', 'both'])
15
+ .default('both')
16
+ .describe('Where to apply the change. Default `both` reconciles both representations.');
17
+ export const obsidianManageTags = tool('obsidian_manage_tags', {
18
+ description: "Add, remove, or list a note's tags. The server reconciles both representations — frontmatter `tags:` array and inline `#tag` syntax — so an `add` ensures the tag is present in the requested location(s), and a `remove` strips it. Inline `#tag` occurrences inside fenced code blocks are intentionally left alone. Inline-location additions append the new tag at the end of the file. `list` ignores the `tags` field.",
19
+ annotations: { destructiveHint: true },
20
+ input: z.object({
21
+ target: TargetSchema.describe('Where the note lives.'),
22
+ operation: z
23
+ .enum(['add', 'remove', 'list'])
24
+ .describe('`add` and `remove` mutate the note; `list` reads the current tag set.'),
25
+ tags: z
26
+ .array(z.string().min(1))
27
+ .optional()
28
+ .describe('Tags to add or remove. Omit the leading `#`. Required for add/remove.'),
29
+ location: LocationSchema,
30
+ }),
31
+ output: z.object({
32
+ result: z
33
+ .discriminatedUnion('operation', [
34
+ z
35
+ .object({
36
+ operation: z.literal('list').describe('Echoed operation.'),
37
+ path: z.string().describe('Resolved vault-relative path.'),
38
+ tags: z
39
+ .object({
40
+ frontmatter: z.array(z.string()).describe('Tags from frontmatter `tags:` array.'),
41
+ inline: z.array(z.string()).describe('Tags found in inline `#tag` syntax.'),
42
+ all: z
43
+ .array(z.string())
44
+ .describe('Deduplicated union of frontmatter and inline tags.'),
45
+ })
46
+ .describe('Tags split by location plus the deduplicated union.'),
47
+ })
48
+ .describe('Result for `list`.'),
49
+ z
50
+ .object({
51
+ operation: z.literal('add').describe('Echoed operation.'),
52
+ path: z.string().describe('Resolved vault-relative path.'),
53
+ applied: z.array(z.string()).describe('Tags actually changed by this call.'),
54
+ skipped: z
55
+ .array(z.string())
56
+ .describe('Tags already present at the targeted location(s).'),
57
+ tags: z.array(z.string()).describe('All tags on the note after the change.'),
58
+ })
59
+ .describe('Result for `add`.'),
60
+ z
61
+ .object({
62
+ operation: z.literal('remove').describe('Echoed operation.'),
63
+ path: z.string().describe('Resolved vault-relative path.'),
64
+ applied: z.array(z.string()).describe('Tags actually changed by this call.'),
65
+ skipped: z.array(z.string()).describe('Tags absent from the targeted location(s).'),
66
+ tags: z.array(z.string()).describe('All tags on the note after the change.'),
67
+ })
68
+ .describe('Result for `remove`.'),
69
+ ])
70
+ .describe('Operation-discriminated result payload.'),
71
+ }),
72
+ auth: ['tool:obsidian_manage_tags:write'],
73
+ errors: [
74
+ {
75
+ reason: 'tags_required',
76
+ code: JsonRpcErrorCode.ValidationError,
77
+ when: '`operation` is "add" or "remove" but `tags` was empty or omitted.',
78
+ },
79
+ {
80
+ reason: 'note_missing',
81
+ code: JsonRpcErrorCode.NotFound,
82
+ when: 'The vault path does not resolve to an existing note.',
83
+ },
84
+ {
85
+ reason: 'no_active_file',
86
+ code: JsonRpcErrorCode.NotFound,
87
+ when: 'Target was `active` but no file is currently open in Obsidian.',
88
+ },
89
+ {
90
+ reason: 'periodic_not_found',
91
+ code: JsonRpcErrorCode.NotFound,
92
+ when: 'Target was `periodic` but no matching periodic note exists.',
93
+ },
94
+ ],
95
+ async handler(input, ctx) {
96
+ const svc = getObsidianService();
97
+ const { target } = input;
98
+ const note = await svc.getNoteJson(ctx, target);
99
+ if (input.operation === 'list') {
100
+ const split = listTagsFromContent(note.content, note.frontmatter);
101
+ const all = Array.from(new Set([...split.frontmatter, ...split.inline]));
102
+ return {
103
+ result: {
104
+ operation: 'list',
105
+ path: note.path,
106
+ tags: { frontmatter: split.frontmatter, inline: split.inline, all },
107
+ },
108
+ };
109
+ }
110
+ if (!input.tags || input.tags.length === 0) {
111
+ throw ctx.fail('tags_required', '`tags` is required and must be non-empty for add/remove operations.', { operation: input.operation });
112
+ }
113
+ const reconciled = reconcileTags(note.content, input.tags, input.operation, input.location);
114
+ if (reconciled.applied.length === 0) {
115
+ return {
116
+ result: {
117
+ operation: input.operation,
118
+ path: note.path,
119
+ applied: reconciled.applied,
120
+ skipped: reconciled.skipped,
121
+ tags: note.tags,
122
+ },
123
+ };
124
+ }
125
+ await svc.writeNote(ctx, target, reconciled.content, 'markdown');
126
+ const after = await svc.getNoteJson(ctx, target);
127
+ if (input.operation === 'add') {
128
+ return {
129
+ result: {
130
+ operation: 'add',
131
+ path: after.path,
132
+ applied: reconciled.applied,
133
+ skipped: reconciled.skipped,
134
+ tags: after.tags,
135
+ },
136
+ };
137
+ }
138
+ return {
139
+ result: {
140
+ operation: 'remove',
141
+ path: after.path,
142
+ applied: reconciled.applied,
143
+ skipped: reconciled.skipped,
144
+ tags: after.tags,
145
+ },
146
+ };
147
+ },
148
+ format: ({ result }) => {
149
+ if (result.operation === 'list') {
150
+ const lines = [
151
+ `**Tags (operation: ${result.operation}) in ${result.path}**`,
152
+ `*Frontmatter (${result.tags.frontmatter.length}):* ${formatTags(result.tags.frontmatter)}`,
153
+ `*Inline (${result.tags.inline.length}):* ${formatTags(result.tags.inline)}`,
154
+ `*All (${result.tags.all.length}):* ${formatTags(result.tags.all)}`,
155
+ ];
156
+ return [{ type: 'text', text: lines.join('\n') }];
157
+ }
158
+ const lines = [
159
+ `**${result.operation === 'add' ? 'Added tags to' : 'Removed tags from'} ${result.path}** (operation: ${result.operation})`,
160
+ `*Applied (${result.applied.length}):* ${formatTags(result.applied)}`,
161
+ `*Skipped (${result.skipped.length}):* ${formatTags(result.skipped)}`,
162
+ `*All tags now (${result.tags.length}):* ${formatTags(result.tags)}`,
163
+ ];
164
+ return [{ type: 'text', text: lines.join('\n') }];
165
+ },
166
+ });
167
+ function formatTags(tags) {
168
+ if (tags.length === 0)
169
+ return '_(none)_';
170
+ return tags.map((t) => `\`#${t}\``).join(' ');
171
+ }
172
+ //# sourceMappingURL=obsidian-manage-tags.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obsidian-manage-tags.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-manage-tags.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @fileoverview obsidian_open_in_ui — open a file in the Obsidian app UI.
3
+ * Defaults to `failIfMissing: true` because Obsidian silently creates files on
4
+ * open otherwise; opt out for an "open or create" flow.
5
+ * @module mcp-server/tools/definitions/obsidian-open-in-ui.tool
6
+ */
7
+ import { z } from '@cyanheads/mcp-ts-core';
8
+ import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
9
+ export declare const obsidianOpenInUi: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
10
+ path: z.ZodString;
11
+ failIfMissing: z.ZodDefault<z.ZodBoolean>;
12
+ newLeaf: z.ZodDefault<z.ZodBoolean>;
13
+ }, z.core.$strip>, z.ZodObject<{
14
+ path: z.ZodString;
15
+ opened: z.ZodBoolean;
16
+ createdIfMissing: z.ZodBoolean;
17
+ }, z.core.$strip>, readonly [{
18
+ readonly reason: "note_missing";
19
+ readonly code: JsonRpcErrorCode.NotFound;
20
+ 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.";
21
+ }]>;
22
+ //# sourceMappingURL=obsidian-open-in-ui.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obsidian-open-in-ui.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-open-in-ui.tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAY,MAAM,+BAA+B,CAAC;AAK3E,eAAO,MAAM,gBAAgB;;;;;;;;;;;;GA2F3B,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @fileoverview obsidian_open_in_ui — open a file in the Obsidian app UI.
3
+ * Defaults to `failIfMissing: true` because Obsidian silently creates files on
4
+ * open otherwise; opt out for an "open or create" flow.
5
+ * @module mcp-server/tools/definitions/obsidian-open-in-ui.tool
6
+ */
7
+ import { tool, z } from '@cyanheads/mcp-ts-core';
8
+ import { JsonRpcErrorCode, McpError } from '@cyanheads/mcp-ts-core/errors';
9
+ import { getObsidianService } from '../../../services/obsidian/obsidian-service.js';
10
+ import { withCaseFallback } from './_shared/suggest-paths.js';
11
+ export const obsidianOpenInUi = tool('obsidian_open_in_ui', {
12
+ description: 'Open a file in the Obsidian app UI. By default fails when the path does not exist; the `failIfMissing` flag controls the open-or-create behavior.',
13
+ annotations: { openWorldHint: true },
14
+ input: z.object({
15
+ path: z.string().min(1).describe('Vault-relative path of the file to open.'),
16
+ failIfMissing: z
17
+ .boolean()
18
+ .default(true)
19
+ .describe('When true (default), fails if the file does not exist. When false, allows Obsidian to create the file on open.'),
20
+ newLeaf: z
21
+ .boolean()
22
+ .default(false)
23
+ .describe('Open in a new leaf (split pane) instead of the active one.'),
24
+ }),
25
+ output: z.object({
26
+ path: z.string().describe('Resolved vault-relative path that was opened.'),
27
+ opened: z.boolean().describe('True when the open call succeeded.'),
28
+ createdIfMissing: z
29
+ .boolean()
30
+ .describe('True when the file did not exist before the call and was created by Obsidian.'),
31
+ }),
32
+ auth: ['tool:obsidian_open_in_ui:write'],
33
+ errors: [
34
+ {
35
+ reason: 'note_missing',
36
+ code: JsonRpcErrorCode.NotFound,
37
+ 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.',
38
+ },
39
+ ],
40
+ async handler(input, ctx) {
41
+ const svc = getObsidianService();
42
+ const target = { type: 'path', path: input.path };
43
+ if (!input.failIfMissing) {
44
+ // Caller opted into "open or create" — skip the existence probe and let
45
+ // Obsidian create the file on open.
46
+ await svc.openInUi(ctx, input.path, { newLeaf: input.newLeaf });
47
+ return { path: input.path, opened: true, createdIfMissing: true };
48
+ }
49
+ let resolvedPath = input.path;
50
+ try {
51
+ const { resolvedPath: rp } = await withCaseFallback(ctx, svc, target, (t) => svc.getNoteJson(ctx, t));
52
+ resolvedPath = rp ?? input.path;
53
+ }
54
+ catch (err) {
55
+ // Match on `data.reason` rather than the JSON-RPC code so the handler text
56
+ // doesn't trip `error-contract-prefer-fail` on a comparison literal. The
57
+ // service tags path 404s with `reason: 'note_missing'` in its error data.
58
+ const reason = err instanceof McpError ? err.data?.reason : undefined;
59
+ if (reason !== 'note_missing')
60
+ throw err;
61
+ const suggestions = (err instanceof McpError && err.data?.suggestions) || [];
62
+ const hint = suggestions.length > 0
63
+ ? ` Did you mean: ${suggestions.map((s) => `"${s}"`).join(', ')}?`
64
+ : '';
65
+ throw ctx.fail('note_missing', `Cannot open '${input.path}' — file does not exist.${hint} Pass failIfMissing: false to create on open.`, {
66
+ path: input.path,
67
+ ...(suggestions.length > 0 ? { suggestions } : {}),
68
+ }, { cause: err });
69
+ }
70
+ await svc.openInUi(ctx, resolvedPath, { newLeaf: input.newLeaf });
71
+ return {
72
+ path: resolvedPath,
73
+ opened: true,
74
+ createdIfMissing: false,
75
+ };
76
+ },
77
+ format: (result) => [
78
+ {
79
+ type: 'text',
80
+ text: [
81
+ `**Opened ${result.path}**`,
82
+ `*Opened:* ${result.opened}`,
83
+ `*Created if missing:* ${result.createdIfMissing}`,
84
+ ].join('\n'),
85
+ },
86
+ ],
87
+ });
88
+ //# sourceMappingURL=obsidian-open-in-ui.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obsidian-open-in-ui.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-open-in-ui.tool.ts"],"names":[],"mappings":"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"}