obsidian-mcp-server 2.0.6 → 3.0.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 (253) 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/template.md +51 -0
  7. package/dist/config/server-config.d.ts +19 -0
  8. package/dist/config/server-config.d.ts.map +1 -0
  9. package/dist/config/server-config.js +55 -0
  10. package/dist/config/server-config.js.map +1 -0
  11. package/dist/index.d.ts +7 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +23 -295
  14. package/dist/index.js.map +1 -0
  15. package/dist/mcp-server/prompts/definitions/index.d.ts +8 -0
  16. package/dist/mcp-server/prompts/definitions/index.d.ts.map +1 -0
  17. package/dist/mcp-server/prompts/definitions/index.js +8 -0
  18. package/dist/mcp-server/prompts/definitions/index.js.map +1 -0
  19. package/dist/mcp-server/resources/definitions/index.d.ts +36 -0
  20. package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -0
  21. package/dist/mcp-server/resources/definitions/index.js +9 -0
  22. package/dist/mcp-server/resources/definitions/index.js.map +1 -0
  23. package/dist/mcp-server/resources/definitions/obsidian-status.resource.d.ts +23 -0
  24. package/dist/mcp-server/resources/definitions/obsidian-status.resource.d.ts.map +1 -0
  25. package/dist/mcp-server/resources/definitions/obsidian-status.resource.js +47 -0
  26. package/dist/mcp-server/resources/definitions/obsidian-status.resource.js.map +1 -0
  27. package/dist/mcp-server/resources/definitions/obsidian-tags.resource.d.ts +13 -0
  28. package/dist/mcp-server/resources/definitions/obsidian-tags.resource.d.ts.map +1 -0
  29. package/dist/mcp-server/resources/definitions/obsidian-tags.resource.js +30 -0
  30. package/dist/mcp-server/resources/definitions/obsidian-tags.resource.js.map +1 -0
  31. package/dist/mcp-server/resources/definitions/obsidian-vault-note.resource.d.ts +21 -0
  32. package/dist/mcp-server/resources/definitions/obsidian-vault-note.resource.d.ts.map +1 -0
  33. package/dist/mcp-server/resources/definitions/obsidian-vault-note.resource.js +38 -0
  34. package/dist/mcp-server/resources/definitions/obsidian-vault-note.resource.js.map +1 -0
  35. package/dist/mcp-server/tools/definitions/_shared/schemas.d.ts +45 -0
  36. package/dist/mcp-server/tools/definitions/_shared/schemas.d.ts.map +1 -0
  37. package/dist/mcp-server/tools/definitions/_shared/schemas.js +66 -0
  38. package/dist/mcp-server/tools/definitions/_shared/schemas.js.map +1 -0
  39. package/dist/mcp-server/tools/definitions/_shared/suggest-paths.d.ts +51 -0
  40. package/dist/mcp-server/tools/definitions/_shared/suggest-paths.d.ts.map +1 -0
  41. package/dist/mcp-server/tools/definitions/_shared/suggest-paths.js +120 -0
  42. package/dist/mcp-server/tools/definitions/_shared/suggest-paths.js.map +1 -0
  43. package/dist/mcp-server/tools/definitions/index.d.ts +531 -0
  44. package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
  45. package/dist/mcp-server/tools/definitions/index.js +38 -0
  46. package/dist/mcp-server/tools/definitions/index.js.map +1 -0
  47. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts +42 -0
  48. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts.map +1 -0
  49. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js +58 -0
  50. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js.map +1 -0
  51. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts +46 -0
  52. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts.map +1 -0
  53. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.js +66 -0
  54. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.js.map +1 -0
  55. package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.d.ts +19 -0
  56. package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.d.ts.map +1 -0
  57. package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.js +43 -0
  58. package/dist/mcp-server/tools/definitions/obsidian-execute-command.tool.js.map +1 -0
  59. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.d.ts +92 -0
  60. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.d.ts.map +1 -0
  61. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.js +245 -0
  62. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.js.map +1 -0
  63. package/dist/mcp-server/tools/definitions/obsidian-list-commands.tool.d.ts +13 -0
  64. package/dist/mcp-server/tools/definitions/obsidian-list-commands.tool.d.ts.map +1 -0
  65. package/dist/mcp-server/tools/definitions/obsidian-list-commands.tool.js +38 -0
  66. package/dist/mcp-server/tools/definitions/obsidian-list-commands.tool.js.map +1 -0
  67. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.d.ts +59 -0
  68. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.d.ts.map +1 -0
  69. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.js +273 -0
  70. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.js.map +1 -0
  71. package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.d.ts +13 -0
  72. package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.d.ts.map +1 -0
  73. package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.js +38 -0
  74. package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.js.map +1 -0
  75. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts +68 -0
  76. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts.map +1 -0
  77. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.js +178 -0
  78. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.js.map +1 -0
  79. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts +77 -0
  80. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts.map +1 -0
  81. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.js +172 -0
  82. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.js.map +1 -0
  83. package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.d.ts +22 -0
  84. package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.d.ts.map +1 -0
  85. package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.js +88 -0
  86. package/dist/mcp-server/tools/definitions/obsidian-open-in-ui.tool.js.map +1 -0
  87. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts +81 -0
  88. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts.map +1 -0
  89. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js +83 -0
  90. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js.map +1 -0
  91. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts +59 -0
  92. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts.map +1 -0
  93. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js +167 -0
  94. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js.map +1 -0
  95. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts +76 -0
  96. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts.map +1 -0
  97. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js +244 -0
  98. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js.map +1 -0
  99. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts +41 -0
  100. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts.map +1 -0
  101. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js +76 -0
  102. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js.map +1 -0
  103. package/dist/services/obsidian/frontmatter-ops.d.ts +34 -0
  104. package/dist/services/obsidian/frontmatter-ops.d.ts.map +1 -0
  105. package/dist/services/obsidian/frontmatter-ops.js +230 -0
  106. package/dist/services/obsidian/frontmatter-ops.js.map +1 -0
  107. package/dist/services/obsidian/obsidian-service.d.ts +73 -0
  108. package/dist/services/obsidian/obsidian-service.d.ts.map +1 -0
  109. package/dist/services/obsidian/obsidian-service.js +399 -0
  110. package/dist/services/obsidian/obsidian-service.js.map +1 -0
  111. package/dist/services/obsidian/section-extractor.d.ts +13 -0
  112. package/dist/services/obsidian/section-extractor.d.ts.map +1 -0
  113. package/dist/services/obsidian/section-extractor.js +124 -0
  114. package/dist/services/obsidian/section-extractor.js.map +1 -0
  115. package/dist/services/obsidian/types.d.ts +91 -0
  116. package/dist/services/obsidian/types.d.ts.map +1 -0
  117. package/dist/services/obsidian/types.js +7 -0
  118. package/dist/services/obsidian/types.js.map +1 -0
  119. package/package.json +63 -69
  120. package/server.json +167 -0
  121. package/CHANGELOG.md +0 -118
  122. package/dist/config/index.d.ts +0 -41
  123. package/dist/config/index.js +0 -191
  124. package/dist/mcp-server/server.d.ts +0 -33
  125. package/dist/mcp-server/server.js +0 -211
  126. package/dist/mcp-server/tools/obsidianDeleteNoteTool/index.d.ts +0 -12
  127. package/dist/mcp-server/tools/obsidianDeleteNoteTool/index.js +0 -12
  128. package/dist/mcp-server/tools/obsidianDeleteNoteTool/logic.d.ts +0 -51
  129. package/dist/mcp-server/tools/obsidianDeleteNoteTool/logic.js +0 -168
  130. package/dist/mcp-server/tools/obsidianDeleteNoteTool/registration.d.ts +0 -19
  131. package/dist/mcp-server/tools/obsidianDeleteNoteTool/registration.js +0 -91
  132. package/dist/mcp-server/tools/obsidianGlobalSearchTool/index.d.ts +0 -12
  133. package/dist/mcp-server/tools/obsidianGlobalSearchTool/index.js +0 -12
  134. package/dist/mcp-server/tools/obsidianGlobalSearchTool/logic.d.ts +0 -77
  135. package/dist/mcp-server/tools/obsidianGlobalSearchTool/logic.js +0 -341
  136. package/dist/mcp-server/tools/obsidianGlobalSearchTool/registration.d.ts +0 -18
  137. package/dist/mcp-server/tools/obsidianGlobalSearchTool/registration.js +0 -69
  138. package/dist/mcp-server/tools/obsidianListNotesTool/index.d.ts +0 -12
  139. package/dist/mcp-server/tools/obsidianListNotesTool/index.js +0 -12
  140. package/dist/mcp-server/tools/obsidianListNotesTool/logic.d.ts +0 -68
  141. package/dist/mcp-server/tools/obsidianListNotesTool/logic.js +0 -215
  142. package/dist/mcp-server/tools/obsidianListNotesTool/registration.d.ts +0 -23
  143. package/dist/mcp-server/tools/obsidianListNotesTool/registration.js +0 -98
  144. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/index.d.ts +0 -3
  145. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/index.js +0 -2
  146. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/logic.d.ts +0 -42
  147. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/logic.js +0 -152
  148. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/registration.d.ts +0 -3
  149. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/registration.js +0 -52
  150. package/dist/mcp-server/tools/obsidianManageTagsTool/index.d.ts +0 -3
  151. package/dist/mcp-server/tools/obsidianManageTagsTool/index.js +0 -2
  152. package/dist/mcp-server/tools/obsidianManageTagsTool/logic.d.ts +0 -28
  153. package/dist/mcp-server/tools/obsidianManageTagsTool/logic.js +0 -161
  154. package/dist/mcp-server/tools/obsidianManageTagsTool/registration.d.ts +0 -3
  155. package/dist/mcp-server/tools/obsidianManageTagsTool/registration.js +0 -52
  156. package/dist/mcp-server/tools/obsidianReadNoteTool/index.d.ts +0 -12
  157. package/dist/mcp-server/tools/obsidianReadNoteTool/index.js +0 -12
  158. package/dist/mcp-server/tools/obsidianReadNoteTool/logic.d.ts +0 -87
  159. package/dist/mcp-server/tools/obsidianReadNoteTool/logic.js +0 -216
  160. package/dist/mcp-server/tools/obsidianReadNoteTool/registration.d.ts +0 -20
  161. package/dist/mcp-server/tools/obsidianReadNoteTool/registration.js +0 -101
  162. package/dist/mcp-server/tools/obsidianSearchReplaceTool/index.d.ts +0 -12
  163. package/dist/mcp-server/tools/obsidianSearchReplaceTool/index.js +0 -12
  164. package/dist/mcp-server/tools/obsidianSearchReplaceTool/logic.d.ts +0 -255
  165. package/dist/mcp-server/tools/obsidianSearchReplaceTool/logic.js +0 -583
  166. package/dist/mcp-server/tools/obsidianSearchReplaceTool/registration.d.ts +0 -22
  167. package/dist/mcp-server/tools/obsidianSearchReplaceTool/registration.js +0 -111
  168. package/dist/mcp-server/tools/obsidianUpdateNoteTool/index.d.ts +0 -12
  169. package/dist/mcp-server/tools/obsidianUpdateNoteTool/index.js +0 -12
  170. package/dist/mcp-server/tools/obsidianUpdateNoteTool/logic.d.ts +0 -183
  171. package/dist/mcp-server/tools/obsidianUpdateNoteTool/logic.js +0 -490
  172. package/dist/mcp-server/tools/obsidianUpdateNoteTool/registration.d.ts +0 -21
  173. package/dist/mcp-server/tools/obsidianUpdateNoteTool/registration.js +0 -108
  174. package/dist/mcp-server/transports/auth/core/authContext.d.ts +0 -33
  175. package/dist/mcp-server/transports/auth/core/authContext.js +0 -24
  176. package/dist/mcp-server/transports/auth/core/authTypes.d.ts +0 -17
  177. package/dist/mcp-server/transports/auth/core/authTypes.js +0 -5
  178. package/dist/mcp-server/transports/auth/core/authUtils.d.ts +0 -18
  179. package/dist/mcp-server/transports/auth/core/authUtils.js +0 -45
  180. package/dist/mcp-server/transports/auth/index.d.ts +0 -10
  181. package/dist/mcp-server/transports/auth/index.js +0 -9
  182. package/dist/mcp-server/transports/auth/strategies/jwt/jwtMiddleware.d.ts +0 -27
  183. package/dist/mcp-server/transports/auth/strategies/jwt/jwtMiddleware.js +0 -149
  184. package/dist/mcp-server/transports/auth/strategies/oauth/oauthMiddleware.d.ts +0 -20
  185. package/dist/mcp-server/transports/auth/strategies/oauth/oauthMiddleware.js +0 -124
  186. package/dist/mcp-server/transports/httpErrorHandler.d.ts +0 -26
  187. package/dist/mcp-server/transports/httpErrorHandler.js +0 -73
  188. package/dist/mcp-server/transports/httpTransport.d.ts +0 -21
  189. package/dist/mcp-server/transports/httpTransport.js +0 -208
  190. package/dist/mcp-server/transports/stdioTransport.d.ts +0 -42
  191. package/dist/mcp-server/transports/stdioTransport.js +0 -63
  192. package/dist/services/obsidianRestAPI/index.d.ts +0 -15
  193. package/dist/services/obsidianRestAPI/index.js +0 -17
  194. package/dist/services/obsidianRestAPI/methods/activeFileMethods.d.ts +0 -38
  195. package/dist/services/obsidianRestAPI/methods/activeFileMethods.js +0 -62
  196. package/dist/services/obsidianRestAPI/methods/commandMethods.d.ts +0 -22
  197. package/dist/services/obsidianRestAPI/methods/commandMethods.js +0 -31
  198. package/dist/services/obsidianRestAPI/methods/openMethods.d.ts +0 -16
  199. package/dist/services/obsidianRestAPI/methods/openMethods.js +0 -21
  200. package/dist/services/obsidianRestAPI/methods/patchMethods.d.ts +0 -37
  201. package/dist/services/obsidianRestAPI/methods/patchMethods.js +0 -94
  202. package/dist/services/obsidianRestAPI/methods/periodicNoteMethods.d.ts +0 -42
  203. package/dist/services/obsidianRestAPI/methods/periodicNoteMethods.js +0 -66
  204. package/dist/services/obsidianRestAPI/methods/searchMethods.d.ts +0 -25
  205. package/dist/services/obsidianRestAPI/methods/searchMethods.js +0 -36
  206. package/dist/services/obsidianRestAPI/methods/vaultMethods.d.ts +0 -58
  207. package/dist/services/obsidianRestAPI/methods/vaultMethods.js +0 -144
  208. package/dist/services/obsidianRestAPI/service.d.ts +0 -195
  209. package/dist/services/obsidianRestAPI/service.js +0 -379
  210. package/dist/services/obsidianRestAPI/types.d.ts +0 -127
  211. package/dist/services/obsidianRestAPI/types.js +0 -7
  212. package/dist/services/obsidianRestAPI/vaultCache/index.d.ts +0 -4
  213. package/dist/services/obsidianRestAPI/vaultCache/index.js +0 -4
  214. package/dist/services/obsidianRestAPI/vaultCache/service.d.ts +0 -88
  215. package/dist/services/obsidianRestAPI/vaultCache/service.js +0 -299
  216. package/dist/types-global/errors.d.ts +0 -73
  217. package/dist/types-global/errors.js +0 -71
  218. package/dist/utils/index.d.ts +0 -5
  219. package/dist/utils/index.js +0 -13
  220. package/dist/utils/internal/asyncUtils.d.ts +0 -54
  221. package/dist/utils/internal/asyncUtils.js +0 -101
  222. package/dist/utils/internal/errorHandler.d.ts +0 -176
  223. package/dist/utils/internal/errorHandler.js +0 -351
  224. package/dist/utils/internal/index.d.ts +0 -4
  225. package/dist/utils/internal/index.js +0 -4
  226. package/dist/utils/internal/logger.d.ts +0 -141
  227. package/dist/utils/internal/logger.js +0 -406
  228. package/dist/utils/internal/requestContext.d.ts +0 -83
  229. package/dist/utils/internal/requestContext.js +0 -72
  230. package/dist/utils/metrics/index.d.ts +0 -1
  231. package/dist/utils/metrics/index.js +0 -1
  232. package/dist/utils/metrics/tokenCounter.d.ts +0 -27
  233. package/dist/utils/metrics/tokenCounter.js +0 -128
  234. package/dist/utils/obsidian/index.d.ts +0 -5
  235. package/dist/utils/obsidian/index.js +0 -5
  236. package/dist/utils/obsidian/obsidianApiUtils.d.ts +0 -14
  237. package/dist/utils/obsidian/obsidianApiUtils.js +0 -29
  238. package/dist/utils/obsidian/obsidianStatUtils.d.ts +0 -68
  239. package/dist/utils/obsidian/obsidianStatUtils.js +0 -143
  240. package/dist/utils/parsing/dateParser.d.ts +0 -56
  241. package/dist/utils/parsing/dateParser.js +0 -104
  242. package/dist/utils/parsing/index.d.ts +0 -2
  243. package/dist/utils/parsing/index.js +0 -3
  244. package/dist/utils/parsing/jsonParser.d.ts +0 -80
  245. package/dist/utils/parsing/jsonParser.js +0 -133
  246. package/dist/utils/security/idGenerator.d.ts +0 -140
  247. package/dist/utils/security/idGenerator.js +0 -194
  248. package/dist/utils/security/index.d.ts +0 -3
  249. package/dist/utils/security/index.js +0 -3
  250. package/dist/utils/security/rateLimiter.d.ts +0 -156
  251. package/dist/utils/security/rateLimiter.js +0 -235
  252. package/dist/utils/security/sanitization.d.ts +0 -244
  253. package/dist/utils/security/sanitization.js +0 -599
@@ -1,379 +0,0 @@
1
- /**
2
- * @module ObsidianRestApiService
3
- * @description
4
- * This module provides the core implementation for the Obsidian REST API service.
5
- * It encapsulates the logic for making authenticated requests to the API endpoints.
6
- */
7
- import axios from "axios";
8
- import https from "node:https"; // Import the https module for Agent configuration
9
- import { config } from "../../config/index.js";
10
- import { BaseErrorCode, McpError } from "../../types-global/errors.js";
11
- import { ErrorHandler, logger, requestContextService, } from "../../utils/index.js"; // Added requestContextService
12
- import * as activeFileMethods from "./methods/activeFileMethods.js";
13
- import * as commandMethods from "./methods/commandMethods.js";
14
- import * as openMethods from "./methods/openMethods.js";
15
- import * as patchMethods from "./methods/patchMethods.js";
16
- import * as periodicNoteMethods from "./methods/periodicNoteMethods.js";
17
- import * as searchMethods from "./methods/searchMethods.js";
18
- import * as vaultMethods from "./methods/vaultMethods.js";
19
- export class ObsidianRestApiService {
20
- constructor() {
21
- this.apiKey = config.obsidianApiKey; // Get from central config
22
- if (!this.apiKey) {
23
- // Config validation should prevent this, but double-check
24
- throw new McpError(BaseErrorCode.CONFIGURATION_ERROR, "Obsidian API Key is missing in configuration.", {});
25
- }
26
- const httpsAgent = new https.Agent({
27
- rejectUnauthorized: config.obsidianVerifySsl,
28
- });
29
- this.axiosInstance = axios.create({
30
- baseURL: config.obsidianBaseUrl.replace(/\/$/, ""), // Remove trailing slash
31
- headers: {
32
- Authorization: `Bearer ${this.apiKey}`,
33
- Accept: "application/json", // Default accept type
34
- },
35
- timeout: 60000, // Increased timeout to 60 seconds (was 15000)
36
- httpsAgent,
37
- });
38
- logger.info(`ObsidianRestApiService initialized with base URL: ${this.axiosInstance.defaults.baseURL}, Verify SSL: ${config.obsidianVerifySsl}`, requestContextService.createRequestContext({
39
- operation: "ObsidianServiceInit",
40
- }));
41
- }
42
- /**
43
- * Private helper to make requests and handle common errors.
44
- * @param config - Axios request configuration.
45
- * @param context - Request context for logging.
46
- * @param operationName - Name of the operation for logging context.
47
- * @returns The response data.
48
- * @throws {McpError} If the request fails.
49
- */
50
- async _request(requestConfig, context, operationName) {
51
- const operationContext = {
52
- ...context,
53
- operation: `ObsidianAPI_${operationName}`,
54
- };
55
- logger.debug(`Making Obsidian API request: ${requestConfig.method} ${requestConfig.url}`, operationContext);
56
- return await ErrorHandler.tryCatch(async () => {
57
- try {
58
- const response = await this.axiosInstance.request(requestConfig);
59
- logger.debug(`Obsidian API request successful: ${requestConfig.method} ${requestConfig.url}`, { ...operationContext, status: response.status });
60
- // For HEAD requests, we need the headers, so return the whole response.
61
- // For other requests, returning response.data is fine.
62
- if (requestConfig.method === "HEAD") {
63
- return response;
64
- }
65
- return response.data;
66
- }
67
- catch (error) {
68
- const axiosError = error;
69
- let errorCode = BaseErrorCode.INTERNAL_ERROR;
70
- let errorMessage = `Obsidian API request failed: ${axiosError.message}`;
71
- const errorDetails = {
72
- requestUrl: requestConfig.url,
73
- requestMethod: requestConfig.method,
74
- responseStatus: axiosError.response?.status,
75
- responseData: axiosError.response?.data,
76
- };
77
- if (axiosError.response) {
78
- // Handle specific HTTP status codes
79
- switch (axiosError.response.status) {
80
- case 400:
81
- errorCode = BaseErrorCode.VALIDATION_ERROR;
82
- errorMessage = `Obsidian API Bad Request: ${JSON.stringify(axiosError.response.data)}`;
83
- break;
84
- case 401:
85
- errorCode = BaseErrorCode.UNAUTHORIZED;
86
- errorMessage = "Obsidian API Unauthorized: Invalid API Key.";
87
- break;
88
- case 403:
89
- errorCode = BaseErrorCode.FORBIDDEN;
90
- errorMessage = "Obsidian API Forbidden: Check permissions.";
91
- break;
92
- case 404:
93
- errorCode = BaseErrorCode.NOT_FOUND;
94
- errorMessage = `Obsidian API Not Found: ${requestConfig.url}`;
95
- // Log 404s at debug level, as they might be expected (e.g., checking existence)
96
- logger.debug(errorMessage, {
97
- ...operationContext,
98
- ...errorDetails,
99
- });
100
- throw new McpError(errorCode, errorMessage, operationContext);
101
- // NOTE: We throw immediately after logging debug for 404, skipping the general error log below.
102
- case 405:
103
- errorCode = BaseErrorCode.VALIDATION_ERROR; // Method not allowed often implies incorrect usage
104
- errorMessage = `Obsidian API Method Not Allowed: ${requestConfig.method} on ${requestConfig.url}`;
105
- break;
106
- case 503:
107
- errorCode = BaseErrorCode.SERVICE_UNAVAILABLE;
108
- errorMessage = "Obsidian API Service Unavailable.";
109
- break;
110
- }
111
- // General error logging for non-404 client/server errors handled above
112
- logger.error(errorMessage, {
113
- ...operationContext,
114
- ...errorDetails,
115
- });
116
- throw new McpError(errorCode, errorMessage, operationContext);
117
- }
118
- else if (axiosError.request) {
119
- // Network error (no response received)
120
- errorCode = BaseErrorCode.SERVICE_UNAVAILABLE;
121
- errorMessage = `Obsidian API Network Error: No response received from ${requestConfig.url}. This may be due to Obsidian not running, the Local REST API plugin being disabled, or a network issue.`;
122
- logger.error(errorMessage, {
123
- ...operationContext,
124
- ...errorDetails,
125
- });
126
- throw new McpError(errorCode, errorMessage, operationContext);
127
- }
128
- else {
129
- // Other errors (e.g., setup issues)
130
- // Pass error object correctly if it's an Error instance
131
- logger.error(errorMessage, error instanceof Error ? error : undefined, {
132
- ...operationContext,
133
- ...errorDetails,
134
- originalError: String(error),
135
- });
136
- throw new McpError(errorCode, errorMessage, operationContext);
137
- }
138
- }
139
- }, {
140
- operation: `ObsidianAPI_${operationName}_Wrapper`,
141
- context: context,
142
- input: requestConfig, // Log request config (sanitized by ErrorHandler)
143
- errorCode: BaseErrorCode.INTERNAL_ERROR, // Default if wrapper itself fails
144
- });
145
- }
146
- // --- API Methods ---
147
- /**
148
- * Checks the status and authentication of the Obsidian Local REST API.
149
- * @param context - The request context for logging and correlation.
150
- * @returns {Promise<ApiStatusResponse>} - The status object from the API.
151
- */
152
- async checkStatus(context) {
153
- // Note: This is the only endpoint that doesn't strictly require auth,
154
- // but sending the key helps check if it's valid.
155
- // This one is simple enough to keep inline or could be extracted too.
156
- return this._request({
157
- method: "GET",
158
- url: "/",
159
- }, context, "checkStatus");
160
- }
161
- // --- Vault Methods ---
162
- /**
163
- * Gets the content of a specific file in the vault.
164
- * @param filePath - Vault-relative path to the file.
165
- * @param format - 'markdown' or 'json' (for NoteJson).
166
- * @param context - Request context.
167
- * @returns The file content (string) or NoteJson object.
168
- */
169
- async getFileContent(filePath, format = "markdown", context) {
170
- return vaultMethods.getFileContent(this._request.bind(this), filePath, format, context);
171
- }
172
- /**
173
- * Updates (overwrites) the content of a file or creates it if it doesn't exist.
174
- * @param filePath - Vault-relative path to the file.
175
- * @param content - The new content for the file.
176
- * @param context - Request context.
177
- * @returns {Promise<void>} Resolves on success (204 No Content).
178
- */
179
- async updateFileContent(filePath, content, context) {
180
- return vaultMethods.updateFileContent(this._request.bind(this), filePath, content, context);
181
- }
182
- /**
183
- * Appends content to the end of a file. Creates the file if it doesn't exist.
184
- * @param filePath - Vault-relative path to the file.
185
- * @param content - The content to append.
186
- * @param context - Request context.
187
- * @returns {Promise<void>} Resolves on success (204 No Content).
188
- */
189
- async appendFileContent(filePath, content, context) {
190
- return vaultMethods.appendFileContent(this._request.bind(this), filePath, content, context);
191
- }
192
- /**
193
- * Deletes a specific file in the vault.
194
- * @param filePath - Vault-relative path to the file.
195
- * @param context - Request context.
196
- * @returns {Promise<void>} Resolves on success (204 No Content).
197
- */
198
- async deleteFile(filePath, context) {
199
- return vaultMethods.deleteFile(this._request.bind(this), filePath, context);
200
- }
201
- /**
202
- * Lists files within a specified directory in the vault.
203
- * @param dirPath - Vault-relative path to the directory. Use empty string "" or "/" for the root.
204
- * @param context - Request context.
205
- * @returns A list of file and directory names.
206
- */
207
- async listFiles(dirPath, context) {
208
- return vaultMethods.listFiles(this._request.bind(this), dirPath, context);
209
- }
210
- /**
211
- * Gets the metadata (stat) of a specific file using a lightweight HEAD request.
212
- * @param filePath - Vault-relative path to the file.
213
- * @param context - Request context.
214
- * @returns The file's metadata.
215
- */
216
- async getFileMetadata(filePath, context) {
217
- return vaultMethods.getFileMetadata(this._request.bind(this), filePath, context);
218
- }
219
- // --- Search Methods ---
220
- /**
221
- * Performs a simple text search across the vault.
222
- * @param query - The text query string.
223
- * @param contextLength - Number of characters surrounding each match (default 100).
224
- * @param context - Request context.
225
- * @returns An array of search results.
226
- */
227
- async searchSimple(query, contextLength = 100, context) {
228
- return searchMethods.searchSimple(this._request.bind(this), query, contextLength, context);
229
- }
230
- /**
231
- * Performs a complex search using Dataview DQL or JsonLogic.
232
- * @param query - The query string (DQL) or JSON object (JsonLogic).
233
- * @param contentType - The content type header indicating the query format.
234
- * @param context - Request context.
235
- * @returns An array of search results.
236
- */
237
- async searchComplex(query, contentType, context) {
238
- return searchMethods.searchComplex(this._request.bind(this), query, contentType, context);
239
- }
240
- // --- Command Methods ---
241
- /**
242
- * Executes a registered Obsidian command by its ID.
243
- * @param commandId - The ID of the command (e.g., "app:go-back").
244
- * @param context - Request context.
245
- * @returns {Promise<void>} Resolves on success (204 No Content).
246
- */
247
- async executeCommand(commandId, context) {
248
- return commandMethods.executeCommand(this._request.bind(this), commandId, context);
249
- }
250
- /**
251
- * Lists all available Obsidian commands.
252
- * @param context - Request context.
253
- * @returns A list of available commands.
254
- */
255
- async listCommands(context) {
256
- return commandMethods.listCommands(this._request.bind(this), context);
257
- }
258
- // --- Open Methods ---
259
- /**
260
- * Opens a specific file in Obsidian. Creates the file if it doesn't exist.
261
- * @param filePath - Vault-relative path to the file.
262
- * @param newLeaf - Whether to open the file in a new editor tab (leaf).
263
- * @param context - Request context.
264
- * @returns {Promise<void>} Resolves on success (200 OK, but no body expected).
265
- */
266
- async openFile(filePath, newLeaf = false, context) {
267
- return openMethods.openFile(this._request.bind(this), filePath, newLeaf, context);
268
- }
269
- // --- Active File Methods ---
270
- /**
271
- * Gets the content of the currently active file in Obsidian.
272
- * @param format - 'markdown' or 'json' (for NoteJson).
273
- * @param context - Request context.
274
- * @returns The file content (string) or NoteJson object.
275
- */
276
- async getActiveFile(format = "markdown", context) {
277
- return activeFileMethods.getActiveFile(this._request.bind(this), format, context);
278
- }
279
- /**
280
- * Updates (overwrites) the content of the currently active file.
281
- * @param content - The new content.
282
- * @param context - Request context.
283
- * @returns {Promise<void>} Resolves on success (204 No Content).
284
- */
285
- async updateActiveFile(content, context) {
286
- return activeFileMethods.updateActiveFile(this._request.bind(this), content, context);
287
- }
288
- /**
289
- * Appends content to the end of the currently active file.
290
- * @param content - The content to append.
291
- * @param context - Request context.
292
- * @returns {Promise<void>} Resolves on success (204 No Content).
293
- */
294
- async appendActiveFile(content, context) {
295
- return activeFileMethods.appendActiveFile(this._request.bind(this), content, context);
296
- }
297
- /**
298
- * Deletes the currently active file.
299
- * @param context - Request context.
300
- * @returns {Promise<void>} Resolves on success (204 No Content).
301
- */
302
- async deleteActiveFile(context) {
303
- return activeFileMethods.deleteActiveFile(this._request.bind(this), context);
304
- }
305
- // --- Periodic Notes Methods ---
306
- // PATCH methods for periodic notes are complex and omitted for brevity
307
- /**
308
- * Gets the content of a periodic note (daily, weekly, etc.).
309
- * @param period - The period type ('daily', 'weekly', 'monthly', 'quarterly', 'yearly').
310
- * @param format - 'markdown' or 'json'.
311
- * @param context - Request context.
312
- * @returns The note content or NoteJson.
313
- */
314
- async getPeriodicNote(period, format = "markdown", context) {
315
- return periodicNoteMethods.getPeriodicNote(this._request.bind(this), period, format, context);
316
- }
317
- /**
318
- * Updates (overwrites) the content of a periodic note. Creates if needed.
319
- * @param period - The period type.
320
- * @param content - The new content.
321
- * @param context - Request context.
322
- * @returns {Promise<void>} Resolves on success (204 No Content).
323
- */
324
- async updatePeriodicNote(period, content, context) {
325
- return periodicNoteMethods.updatePeriodicNote(this._request.bind(this), period, content, context);
326
- }
327
- /**
328
- * Appends content to a periodic note. Creates if needed.
329
- * @param period - The period type.
330
- * @param content - The content to append.
331
- * @param context - Request context.
332
- * @returns {Promise<void>} Resolves on success (204 No Content).
333
- */
334
- async appendPeriodicNote(period, content, context) {
335
- return periodicNoteMethods.appendPeriodicNote(this._request.bind(this), period, content, context);
336
- }
337
- /**
338
- * Deletes a periodic note.
339
- * @param period - The period type.
340
- * @param context - Request context.
341
- * @returns {Promise<void>} Resolves on success (204 No Content).
342
- */
343
- async deletePeriodicNote(period, context) {
344
- return periodicNoteMethods.deletePeriodicNote(this._request.bind(this), period, context);
345
- }
346
- // --- Patch Methods ---
347
- /**
348
- * Patches a specific file in the vault using granular controls.
349
- * @param filePath - Vault-relative path to the file.
350
- * @param content - The content to insert/replace (string or JSON for tables/frontmatter).
351
- * @param options - Patch operation details (operation, targetType, target, etc.).
352
- * @param context - Request context.
353
- * @returns {Promise<void>} Resolves on success (200 OK).
354
- */
355
- async patchFile(filePath, content, options, context) {
356
- return patchMethods.patchFile(this._request.bind(this), filePath, content, options, context);
357
- }
358
- /**
359
- * Patches the currently active file in Obsidian using granular controls.
360
- * @param content - The content to insert/replace.
361
- * @param options - Patch operation details.
362
- * @param context - Request context.
363
- * @returns {Promise<void>} Resolves on success (200 OK).
364
- */
365
- async patchActiveFile(content, options, context) {
366
- return patchMethods.patchActiveFile(this._request.bind(this), content, options, context);
367
- }
368
- /**
369
- * Patches a periodic note using granular controls.
370
- * @param period - The period type ('daily', 'weekly', etc.).
371
- * @param content - The content to insert/replace.
372
- * @param options - Patch operation details.
373
- * @param context - Request context.
374
- * @returns {Promise<void>} Resolves on success (200 OK).
375
- */
376
- async patchPeriodicNote(period, content, options, context) {
377
- return patchMethods.patchPeriodicNote(this._request.bind(this), period, content, options, context);
378
- }
379
- }
@@ -1,127 +0,0 @@
1
- /**
2
- * @module ObsidianRestApiTypes
3
- * @description
4
- * Type definitions for interacting with the Obsidian Local REST API,
5
- * based on its OpenAPI specification.
6
- */
7
- import { AxiosRequestConfig } from "axios";
8
- import { RequestContext } from "../../utils/index.js";
9
- /**
10
- * Defines the signature for the internal request function passed to method implementations.
11
- * This function is bound to the `ObsidianRestApiService` instance and handles the core
12
- * logic of making an HTTP request, including authentication, error handling, and logging.
13
- *
14
- * @template T The expected return type of the API call.
15
- * @param config The Axios request configuration.
16
- * @param context The request context for logging and correlation.
17
- * @param operationName A descriptive name for the operation being performed, used for logging.
18
- * @returns A promise that resolves with the data of type `T`.
19
- */
20
- export type RequestFunction = <T = any>(config: AxiosRequestConfig, context: RequestContext, operationName: string) => Promise<T>;
21
- /**
22
- * Filesystem metadata for a note.
23
- */
24
- export interface NoteStat {
25
- ctime: number;
26
- mtime: number;
27
- size: number;
28
- }
29
- /**
30
- * JSON representation of an Obsidian note.
31
- * Returned when requesting with Accept: application/vnd.olrapi.note+json
32
- */
33
- export interface NoteJson {
34
- content: string;
35
- frontmatter: Record<string, any>;
36
- path: string;
37
- stat: NoteStat;
38
- tags: string[];
39
- }
40
- /**
41
- * Response structure for listing files in a directory.
42
- */
43
- export interface FileListResponse {
44
- files: string[];
45
- }
46
- /**
47
- * Match details within a simple search result.
48
- */
49
- export interface SimpleSearchMatchDetail {
50
- start: number;
51
- end: number;
52
- }
53
- /**
54
- * Contextual match information for simple search.
55
- */
56
- export interface SimpleSearchMatch {
57
- context: string;
58
- match: SimpleSearchMatchDetail;
59
- }
60
- /**
61
- * Result item for a simple text search.
62
- */
63
- export interface SimpleSearchResult {
64
- filename: string;
65
- matches: SimpleSearchMatch[];
66
- score: number;
67
- }
68
- /**
69
- * Result item for a complex (Dataview/JsonLogic) search.
70
- */
71
- export interface ComplexSearchResult {
72
- filename: string;
73
- result: any;
74
- }
75
- /**
76
- * Structure for an available Obsidian command.
77
- */
78
- export interface ObsidianCommand {
79
- id: string;
80
- name: string;
81
- }
82
- /**
83
- * Response structure for listing available commands.
84
- */
85
- export interface CommandListResponse {
86
- commands: ObsidianCommand[];
87
- }
88
- /**
89
- * Basic status response from the API root.
90
- */
91
- export interface ApiStatusResponse {
92
- authenticated: boolean;
93
- ok: string;
94
- service: string;
95
- versions: {
96
- obsidian: string;
97
- self: string;
98
- };
99
- }
100
- /**
101
- * Standard error response structure from the API.
102
- */
103
- export interface ApiError {
104
- errorCode: number;
105
- message: string;
106
- }
107
- /**
108
- * Options for PATCH operations.
109
- */
110
- export interface PatchOptions {
111
- operation: "append" | "prepend" | "replace";
112
- targetType: "heading" | "block" | "frontmatter";
113
- target: string;
114
- targetDelimiter?: string;
115
- trimTargetWhitespace?: boolean;
116
- /**
117
- * If true, creates the target if it's missing.
118
- * This is implemented via the `Create-Target-If-Missing` HTTP header.
119
- * Particularly useful for adding new frontmatter keys.
120
- */
121
- createTargetIfMissing?: boolean;
122
- contentType?: "text/markdown" | "application/json";
123
- }
124
- /**
125
- * Type alias for periodic note periods.
126
- */
127
- export type Period = "daily" | "weekly" | "monthly" | "quarterly" | "yearly";
@@ -1,7 +0,0 @@
1
- /**
2
- * @module ObsidianRestApiTypes
3
- * @description
4
- * Type definitions for interacting with the Obsidian Local REST API,
5
- * based on its OpenAPI specification.
6
- */
7
- export {};
@@ -1,4 +0,0 @@
1
- /**
2
- * Barrel file for the VaultCacheService.
3
- */
4
- export * from "./service.js";
@@ -1,4 +0,0 @@
1
- /**
2
- * Barrel file for the VaultCacheService.
3
- */
4
- export * from "./service.js";
@@ -1,88 +0,0 @@
1
- /**
2
- * @module VaultCacheService
3
- * @description Service for building and managing an in-memory cache of Obsidian vault content.
4
- */
5
- import { RequestContext } from "../../../utils/index.js";
6
- import { ObsidianRestApiService } from "../index.js";
7
- interface CacheEntry {
8
- content: string;
9
- mtime: number;
10
- }
11
- /**
12
- * Manages an in-memory cache of the Obsidian vault's file structure and metadata.
13
- *
14
- * __Is the cache safe and secure?__
15
- * Yes, the cache is safe and secure for its purpose within this application. Here's why:
16
- * 1. __In-Memory Storage:__ The cache exists only in the server's memory. It is not written to disk or transmitted over the network, so its attack surface is limited to the server process itself.
17
- * 2. __Local Data Source:__ The data populating the cache comes directly from your own Obsidian vault via the local REST API. It is not fetching data from external, untrusted sources.
18
- *
19
- * __Warning: High Memory Usage__
20
- * This service stores the entire content of every markdown file in the vault in memory. For users with very large vaults (e.g., many gigabytes of markdown files), this can lead to significant RAM consumption. If you experience high memory usage, consider disabling the cache via the `OBSIDIAN_ENABLE_CACHE` environment variable.
21
- */
22
- export declare class VaultCacheService {
23
- private vaultContentCache;
24
- private isCacheReady;
25
- private isBuilding;
26
- private obsidianService;
27
- private refreshIntervalId;
28
- constructor(obsidianService: ObsidianRestApiService);
29
- /**
30
- * Starts the periodic cache refresh mechanism.
31
- * The interval is controlled by the `OBSIDIAN_CACHE_REFRESH_INTERVAL_MIN` config setting.
32
- */
33
- startPeriodicRefresh(): void;
34
- /**
35
- * Stops the periodic cache refresh mechanism.
36
- * Should be called during graceful shutdown.
37
- */
38
- stopPeriodicRefresh(): void;
39
- /**
40
- * Checks if the cache has been successfully built.
41
- * @returns {boolean} True if the cache is ready, false otherwise.
42
- */
43
- isReady(): boolean;
44
- /**
45
- * Checks if the cache is currently being built.
46
- * @returns {boolean} True if the cache build is in progress, false otherwise.
47
- */
48
- getIsBuilding(): boolean;
49
- /**
50
- * Returns the entire vault content cache.
51
- * Use with caution for large vaults due to potential memory usage.
52
- * @returns {ReadonlyMap<string, CacheEntry>} The cache map.
53
- */
54
- getCache(): ReadonlyMap<string, CacheEntry>;
55
- /**
56
- * Retrieves a specific entry from the cache.
57
- * @param {string} filePath - The vault-relative path of the file.
58
- * @returns {CacheEntry | undefined} The cache entry or undefined if not found.
59
- */
60
- getEntry(filePath: string): CacheEntry | undefined;
61
- /**
62
- * Immediately fetches the latest data for a single file and updates its entry in the cache.
63
- * This is useful for ensuring cache consistency immediately after a file modification.
64
- * @param {string} filePath - The vault-relative path of the file to update.
65
- * @param {RequestContext} context - The request context for logging.
66
- */
67
- updateCacheForFile(filePath: string, context: RequestContext): Promise<void>;
68
- /**
69
- * Builds the in-memory cache by fetching all markdown files and their content.
70
- * This is intended to be run once at startup. Subsequent updates are handled by `refreshCache`.
71
- */
72
- buildVaultCache(): Promise<void>;
73
- /**
74
- * Refreshes the cache by comparing remote file modification times with cached ones.
75
- * Only fetches content for new or updated files.
76
- * @param isInitialBuild - If true, forces a full build and sets the cache readiness flag.
77
- */
78
- refreshCache(isInitialBuild?: boolean): Promise<void>;
79
- /**
80
- * Helper to recursively list all markdown files. Similar to the one in search logic.
81
- * @param dirPath - Starting directory path.
82
- * @param context - Request context.
83
- * @param visitedDirs - Set to track visited directories.
84
- * @returns Array of file paths.
85
- */
86
- private listAllMarkdownFiles;
87
- }
88
- export {};