@sunub/obsidian-mcp-server 0.3.15 → 0.3.17

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 (224) hide show
  1. package/{build → dist}/config.d.ts +1 -1
  2. package/dist/config.d.ts.map +1 -0
  3. package/dist/config.js +59 -0
  4. package/dist/config.js.map +1 -0
  5. package/dist/db.js +58 -0
  6. package/dist/db.js.map +1 -0
  7. package/dist/index.js +52 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/server.js +42 -0
  10. package/dist/server.js.map +1 -0
  11. package/dist/setup.js +114 -0
  12. package/dist/setup.js.map +1 -0
  13. package/{build → dist}/tools/create_document_with_properties/index.d.ts +1 -1
  14. package/dist/tools/create_document_with_properties/index.js +115 -0
  15. package/dist/tools/create_document_with_properties/index.js.map +1 -0
  16. package/{build → dist}/tools/create_document_with_properties/params.d.ts +2 -2
  17. package/dist/tools/create_document_with_properties/params.js +33 -0
  18. package/dist/tools/create_document_with_properties/params.js.map +1 -0
  19. package/{build → dist}/tools/generate_property/index.d.ts +1 -1
  20. package/dist/tools/generate_property/index.js +86 -0
  21. package/dist/tools/generate_property/index.js.map +1 -0
  22. package/dist/tools/generate_property/params.js +55 -0
  23. package/dist/tools/generate_property/params.js.map +1 -0
  24. package/dist/tools/index.js +13 -0
  25. package/dist/tools/index.js.map +1 -0
  26. package/{build → dist}/tools/organize_attachments/index.d.ts +1 -1
  27. package/dist/tools/organize_attachments/index.js +86 -0
  28. package/dist/tools/organize_attachments/index.js.map +1 -0
  29. package/dist/tools/organize_attachments/params.js +61 -0
  30. package/dist/tools/organize_attachments/params.js.map +1 -0
  31. package/{build → dist}/tools/organize_attachments/utils.d.ts +1 -1
  32. package/dist/tools/organize_attachments/utils.js +66 -0
  33. package/dist/tools/organize_attachments/utils.js.map +1 -0
  34. package/{build → dist}/tools/vault/index.d.ts +1 -1
  35. package/dist/tools/vault/index.js +104 -0
  36. package/dist/tools/vault/index.js.map +1 -0
  37. package/dist/tools/vault/metrics.js +130 -0
  38. package/dist/tools/vault/metrics.js.map +1 -0
  39. package/{build → dist}/tools/vault/params.d.ts +2 -2
  40. package/dist/tools/vault/params.js +148 -0
  41. package/dist/tools/vault/params.js.map +1 -0
  42. package/dist/tools/vault/types/collect_context.js +103 -0
  43. package/dist/tools/vault/types/collect_context.js.map +1 -0
  44. package/dist/tools/vault/types/list_all.js +53 -0
  45. package/dist/tools/vault/types/list_all.js.map +1 -0
  46. package/dist/tools/vault/types/read_specific.js +41 -0
  47. package/dist/tools/vault/types/read_specific.js.map +1 -0
  48. package/dist/tools/vault/types/search.js +59 -0
  49. package/dist/tools/vault/types/search.js.map +1 -0
  50. package/dist/tools/vault/utils/actions/collect_context.d.ts +5 -0
  51. package/dist/tools/vault/utils/actions/collect_context.js +765 -0
  52. package/dist/tools/vault/utils/actions/collect_context.js.map +1 -0
  53. package/dist/tools/vault/utils/actions/index_rag.js +27 -0
  54. package/dist/tools/vault/utils/actions/index_rag.js.map +1 -0
  55. package/dist/tools/vault/utils/actions/list_all.d.ts +5 -0
  56. package/dist/tools/vault/utils/actions/list_all.js +43 -0
  57. package/dist/tools/vault/utils/actions/list_all.js.map +1 -0
  58. package/dist/tools/vault/utils/actions/load_memory.d.ts +5 -0
  59. package/dist/tools/vault/utils/actions/load_memory.js +186 -0
  60. package/dist/tools/vault/utils/actions/load_memory.js.map +1 -0
  61. package/{build → dist}/tools/vault/utils/actions/read.d.ts +2 -2
  62. package/dist/tools/vault/utils/actions/read.js +68 -0
  63. package/dist/tools/vault/utils/actions/read.js.map +1 -0
  64. package/{build → dist}/tools/vault/utils/actions/search.d.ts +2 -2
  65. package/dist/tools/vault/utils/actions/search.js +104 -0
  66. package/dist/tools/vault/utils/actions/search.js.map +1 -0
  67. package/{build → dist}/tools/vault/utils/actions/stats.d.ts +1 -1
  68. package/dist/tools/vault/utils/actions/stats.js +9 -0
  69. package/dist/tools/vault/utils/actions/stats.js.map +1 -0
  70. package/dist/tools/vault/utils/constants.js +3 -0
  71. package/dist/tools/vault/utils/constants.js.map +1 -0
  72. package/{build → dist}/tools/vault/utils/document.d.ts +3 -3
  73. package/dist/tools/vault/utils/document.js +50 -0
  74. package/dist/tools/vault/utils/document.js.map +1 -0
  75. package/{build → dist}/tools/vault/utils/shared.d.ts +1 -1
  76. package/dist/tools/vault/utils/shared.js +75 -0
  77. package/dist/tools/vault/utils/shared.js.map +1 -0
  78. package/dist/tools/vault/utils.d.ts +8 -0
  79. package/dist/tools/vault/utils.js +8 -0
  80. package/dist/tools/vault/utils.js.map +1 -0
  81. package/{build → dist}/tools/write_property/index.d.ts +1 -1
  82. package/dist/tools/write_property/index.js +120 -0
  83. package/dist/tools/write_property/index.js.map +1 -0
  84. package/dist/tools/write_property/params.js +52 -0
  85. package/dist/tools/write_property/params.js.map +1 -0
  86. package/{build → dist}/utils/DirectoryWalker.d.ts +1 -1
  87. package/dist/utils/DirectoryWalker.js +52 -0
  88. package/dist/utils/DirectoryWalker.js.map +1 -0
  89. package/dist/utils/Embedder.js +46 -0
  90. package/dist/utils/Embedder.js.map +1 -0
  91. package/{build → dist}/utils/Indexer.d.ts +2 -2
  92. package/dist/utils/Indexer.js +169 -0
  93. package/dist/utils/Indexer.js.map +1 -0
  94. package/dist/utils/LLMClient.js +112 -0
  95. package/dist/utils/LLMClient.js.map +1 -0
  96. package/dist/utils/LocalReranker.js +71 -0
  97. package/dist/utils/LocalReranker.js.map +1 -0
  98. package/{build → dist}/utils/RAGIndexer.d.ts +1 -1
  99. package/dist/utils/RAGIndexer.js +238 -0
  100. package/dist/utils/RAGIndexer.js.map +1 -0
  101. package/dist/utils/RerankerClient.js +89 -0
  102. package/dist/utils/RerankerClient.js.map +1 -0
  103. package/{build → dist}/utils/VaultManger/VaultManager.d.ts +3 -3
  104. package/dist/utils/VaultManger/VaultManager.js +459 -0
  105. package/dist/utils/VaultManger/VaultManager.js.map +1 -0
  106. package/dist/utils/VaultManger/VaultPathError.js +13 -0
  107. package/dist/utils/VaultManger/VaultPathError.js.map +1 -0
  108. package/dist/utils/VaultManger/index.d.ts +4 -0
  109. package/dist/utils/VaultManger/index.js +3 -0
  110. package/dist/utils/VaultManger/index.js.map +1 -0
  111. package/{build → dist}/utils/VaultManger/types.d.ts +1 -1
  112. package/dist/utils/VaultManger/types.js +2 -0
  113. package/dist/utils/VaultManger/types.js.map +1 -0
  114. package/dist/utils/VaultWatcher.js +60 -0
  115. package/dist/utils/VaultWatcher.js.map +1 -0
  116. package/dist/utils/VectorDB.js +268 -0
  117. package/dist/utils/VectorDB.js.map +1 -0
  118. package/dist/utils/constants.js +14 -0
  119. package/dist/utils/constants.js.map +1 -0
  120. package/dist/utils/createToolError.js +16 -0
  121. package/dist/utils/createToolError.js.map +1 -0
  122. package/dist/utils/getVaultManager.d.ts +3 -0
  123. package/dist/utils/getVaultManager.js +15 -0
  124. package/dist/utils/getVaultManager.js.map +1 -0
  125. package/dist/utils/processor/LinkExtractor.js +31 -0
  126. package/dist/utils/processor/LinkExtractor.js.map +1 -0
  127. package/dist/utils/processor/MatterParser.d.ts +3 -0
  128. package/dist/utils/processor/MatterParser.js +28 -0
  129. package/dist/utils/processor/MatterParser.js.map +1 -0
  130. package/dist/utils/processor/types.js +22 -0
  131. package/dist/utils/processor/types.js.map +1 -0
  132. package/dist/utils/semaphore.js +26 -0
  133. package/dist/utils/semaphore.js.map +1 -0
  134. package/package.json +19 -12
  135. package/build/config.d.ts.map +0 -1
  136. package/build/index.js +0 -127331
  137. package/build/index.js.map +0 -828
  138. package/build/lancedb.linux-x64-gnu-1e1af8yx.node +0 -0
  139. package/build/tools/vault/utils/actions/collect_context.d.ts +0 -5
  140. package/build/tools/vault/utils/actions/list_all.d.ts +0 -5
  141. package/build/tools/vault/utils/actions/load_memory.d.ts +0 -5
  142. package/build/tools/vault/utils.d.ts +0 -8
  143. package/build/utils/VaultManger/index.d.ts +0 -4
  144. package/build/utils/getVaultManager.d.ts +0 -3
  145. package/build/utils/processor/MatterParser.d.ts +0 -3
  146. /package/{build → dist}/db.d.ts +0 -0
  147. /package/{build → dist}/db.d.ts.map +0 -0
  148. /package/{build → dist}/index.d.ts +0 -0
  149. /package/{build → dist}/index.d.ts.map +0 -0
  150. /package/{build → dist}/server.d.ts +0 -0
  151. /package/{build → dist}/server.d.ts.map +0 -0
  152. /package/{build → dist}/setup.d.ts +0 -0
  153. /package/{build → dist}/setup.d.ts.map +0 -0
  154. /package/{build → dist}/tools/create_document_with_properties/index.d.ts.map +0 -0
  155. /package/{build → dist}/tools/create_document_with_properties/params.d.ts.map +0 -0
  156. /package/{build → dist}/tools/generate_property/index.d.ts.map +0 -0
  157. /package/{build → dist}/tools/generate_property/params.d.ts +0 -0
  158. /package/{build → dist}/tools/generate_property/params.d.ts.map +0 -0
  159. /package/{build → dist}/tools/index.d.ts +0 -0
  160. /package/{build → dist}/tools/index.d.ts.map +0 -0
  161. /package/{build → dist}/tools/organize_attachments/index.d.ts.map +0 -0
  162. /package/{build → dist}/tools/organize_attachments/params.d.ts +0 -0
  163. /package/{build → dist}/tools/organize_attachments/params.d.ts.map +0 -0
  164. /package/{build → dist}/tools/organize_attachments/utils.d.ts.map +0 -0
  165. /package/{build → dist}/tools/vault/index.d.ts.map +0 -0
  166. /package/{build → dist}/tools/vault/metrics.d.ts +0 -0
  167. /package/{build → dist}/tools/vault/metrics.d.ts.map +0 -0
  168. /package/{build → dist}/tools/vault/params.d.ts.map +0 -0
  169. /package/{build → dist}/tools/vault/types/collect_context.d.ts +0 -0
  170. /package/{build → dist}/tools/vault/types/collect_context.d.ts.map +0 -0
  171. /package/{build → dist}/tools/vault/types/list_all.d.ts +0 -0
  172. /package/{build → dist}/tools/vault/types/list_all.d.ts.map +0 -0
  173. /package/{build → dist}/tools/vault/types/read_specific.d.ts +0 -0
  174. /package/{build → dist}/tools/vault/types/read_specific.d.ts.map +0 -0
  175. /package/{build → dist}/tools/vault/types/search.d.ts +0 -0
  176. /package/{build → dist}/tools/vault/types/search.d.ts.map +0 -0
  177. /package/{build → dist}/tools/vault/utils/actions/collect_context.d.ts.map +0 -0
  178. /package/{build → dist}/tools/vault/utils/actions/index_rag.d.ts +0 -0
  179. /package/{build → dist}/tools/vault/utils/actions/index_rag.d.ts.map +0 -0
  180. /package/{build → dist}/tools/vault/utils/actions/list_all.d.ts.map +0 -0
  181. /package/{build → dist}/tools/vault/utils/actions/load_memory.d.ts.map +0 -0
  182. /package/{build → dist}/tools/vault/utils/actions/read.d.ts.map +0 -0
  183. /package/{build → dist}/tools/vault/utils/actions/search.d.ts.map +0 -0
  184. /package/{build → dist}/tools/vault/utils/actions/stats.d.ts.map +0 -0
  185. /package/{build → dist}/tools/vault/utils/constants.d.ts +0 -0
  186. /package/{build → dist}/tools/vault/utils/constants.d.ts.map +0 -0
  187. /package/{build → dist}/tools/vault/utils/document.d.ts.map +0 -0
  188. /package/{build → dist}/tools/vault/utils/shared.d.ts.map +0 -0
  189. /package/{build → dist}/tools/vault/utils.d.ts.map +0 -0
  190. /package/{build → dist}/tools/write_property/index.d.ts.map +0 -0
  191. /package/{build → dist}/tools/write_property/params.d.ts +0 -0
  192. /package/{build → dist}/tools/write_property/params.d.ts.map +0 -0
  193. /package/{build → dist}/utils/DirectoryWalker.d.ts.map +0 -0
  194. /package/{build → dist}/utils/Embedder.d.ts +0 -0
  195. /package/{build → dist}/utils/Embedder.d.ts.map +0 -0
  196. /package/{build → dist}/utils/Indexer.d.ts.map +0 -0
  197. /package/{build → dist}/utils/LLMClient.d.ts +0 -0
  198. /package/{build → dist}/utils/LLMClient.d.ts.map +0 -0
  199. /package/{build → dist}/utils/LocalReranker.d.ts +0 -0
  200. /package/{build → dist}/utils/LocalReranker.d.ts.map +0 -0
  201. /package/{build → dist}/utils/RAGIndexer.d.ts.map +0 -0
  202. /package/{build → dist}/utils/RerankerClient.d.ts +0 -0
  203. /package/{build → dist}/utils/RerankerClient.d.ts.map +0 -0
  204. /package/{build → dist}/utils/VaultManger/VaultManager.d.ts.map +0 -0
  205. /package/{build → dist}/utils/VaultManger/VaultPathError.d.ts +0 -0
  206. /package/{build → dist}/utils/VaultManger/VaultPathError.d.ts.map +0 -0
  207. /package/{build → dist}/utils/VaultManger/index.d.ts.map +0 -0
  208. /package/{build → dist}/utils/VaultManger/types.d.ts.map +0 -0
  209. /package/{build → dist}/utils/VaultWatcher.d.ts +0 -0
  210. /package/{build → dist}/utils/VaultWatcher.d.ts.map +0 -0
  211. /package/{build → dist}/utils/VectorDB.d.ts +0 -0
  212. /package/{build → dist}/utils/VectorDB.d.ts.map +0 -0
  213. /package/{build → dist}/utils/constants.d.ts +0 -0
  214. /package/{build → dist}/utils/constants.d.ts.map +0 -0
  215. /package/{build → dist}/utils/createToolError.d.ts +0 -0
  216. /package/{build → dist}/utils/createToolError.d.ts.map +0 -0
  217. /package/{build → dist}/utils/getVaultManager.d.ts.map +0 -0
  218. /package/{build → dist}/utils/processor/LinkExtractor.d.ts +0 -0
  219. /package/{build → dist}/utils/processor/LinkExtractor.d.ts.map +0 -0
  220. /package/{build → dist}/utils/processor/MatterParser.d.ts.map +0 -0
  221. /package/{build → dist}/utils/processor/types.d.ts +0 -0
  222. /package/{build → dist}/utils/processor/types.d.ts.map +0 -0
  223. /package/{build → dist}/utils/semaphore.d.ts +0 -0
  224. /package/{build → dist}/utils/semaphore.d.ts.map +0 -0
@@ -0,0 +1,86 @@
1
+ import { obsidianPropertyQueryParamsSchema, } from "../../tools/generate_property/params.js";
2
+ import { createToolError } from "../../utils/createToolError.js";
3
+ import { getGlobalVaultManager } from "../../utils/getVaultManager.js";
4
+ export const name = "generate_property";
5
+ export const annotations = {
6
+ title: "Generate Obsidian Property",
7
+ openWorldHint: true,
8
+ };
9
+ export const description = `
10
+ Reads a target markdown document and returns an AI-facing payload for generating frontmatter properties.
11
+
12
+ This tool does not write to disk. It returns content_preview and a target output schema so an AI can produce a valid property object.
13
+
14
+ Use Cases:
15
+ - After completing a draft, when you need property suggestions from content.
16
+ - When missing frontmatter fields (title, tags, summary, slug, date, category, completed) should be generated.
17
+
18
+ To apply generated properties to a file, call 'write_property' with the resulting JSON.
19
+ `;
20
+ export const register = (mcpServer) => {
21
+ mcpServer.registerTool(name, {
22
+ title: annotations.title || name,
23
+ description: description,
24
+ inputSchema: obsidianPropertyQueryParamsSchema.shape,
25
+ annotations: annotations,
26
+ }, execute);
27
+ };
28
+ export const execute = async (params) => {
29
+ const response = { content: [], isError: false };
30
+ let vaultManager = null;
31
+ try {
32
+ vaultManager = getGlobalVaultManager();
33
+ }
34
+ catch (e) {
35
+ return createToolError(e.message);
36
+ }
37
+ try {
38
+ const document = await vaultManager.getDocumentInfo(params.filename);
39
+ if (document === null) {
40
+ return createToolError(`Document not found: ${params.filename}`, "Use 'list_all' action to see available documents");
41
+ }
42
+ const documentData = {
43
+ filename: params.filename,
44
+ content_preview: `${document.content.substring(0, 300).replace(/\s+/g, " ")}...`,
45
+ instructions: {
46
+ purpose: "Generate or update the document's frontmatter properties based on its content.",
47
+ usage: "Analyze the provided content_preview. If more detail is needed to generate accurate properties, you MUST call the 'vault' tool with action='read' to get the full document content.",
48
+ content_type: "markdown",
49
+ overwrite: params.overwrite || false,
50
+ output_format: "Return a JSON object with the following structure",
51
+ schema: {
52
+ title: "string - Title representing the core topic",
53
+ tags: "string[] - Array of relevant tags from content keywords",
54
+ summary: "string - 1-2 sentence summary of the document",
55
+ slug: "string - URL-friendly hyphenated identifier",
56
+ date: "string - ISO 8601 date format",
57
+ completed: "boolean - Whether content is finalized",
58
+ aliases: "string[] - (Optional) Alternative names or synonyms",
59
+ category: "string - (Optional) Document category",
60
+ },
61
+ },
62
+ };
63
+ response.content.push({
64
+ type: "text",
65
+ text: JSON.stringify(documentData, null, 2),
66
+ });
67
+ }
68
+ catch (error) {
69
+ return createToolError(error.message, "Ensure the VAULT_DIR_PATH environment variable is set to your Obsidian vault directory and the filename is correct.");
70
+ }
71
+ return response;
72
+ };
73
+ export const shorthandDescription = {
74
+ en: `Returns document content and an output schema for generating Markdown frontmatter properties. Read-only; must be paired with 'write_property' to apply changes.`,
75
+ ko: "대상 마크다운 문서를 읽어 프론트매터 속성(제목, 태그, 요약 등) 생성을 위한 AI용 페이로드(내용 및 스키마)를 반환합니다. 읽기 전용 도구이며, 생성된 속성을 실제 파일에 적용하려면 'write_property'를 호출해야 합니다.",
76
+ };
77
+ export default {
78
+ name,
79
+ description,
80
+ annotations,
81
+ inputSchema: obsidianPropertyQueryParamsSchema.shape,
82
+ execute,
83
+ register,
84
+ shorthandDescription,
85
+ };
86
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/generate_property/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { z } from "zod";
2
+ // input properties
3
+ const obsidianGenerateInputFilename = z
4
+ .string()
5
+ .describe('The name or path of the file to analyze and add properties to (e.g., "my-first-post.md")');
6
+ const obsidianGenerateInputOverwrite = z
7
+ .boolean()
8
+ .default(true)
9
+ .describe("If set to true, existing properties will be overwritten by the AI-generated content. Default: false.");
10
+ // input schema
11
+ export const obsidianPropertyQueryParamsSchema = z
12
+ .object({
13
+ filename: obsidianGenerateInputFilename,
14
+ overwrite: obsidianGenerateInputOverwrite.optional(),
15
+ })
16
+ .describe("Parameters for generating or updating Obsidian document properties");
17
+ // output properties
18
+ export const obsidianCssClassesProperty = z
19
+ .array(z.string())
20
+ .describe("List of CSS classes associated with the document");
21
+ export const obsidianTagsProperty = z
22
+ .array(z.string())
23
+ .describe("List of tags associated with the document");
24
+ export const obsidianTitleProperty = z
25
+ .string()
26
+ .describe("Title of the document");
27
+ export const obsidianDateProperty = z
28
+ .string()
29
+ .describe("Creation date of the document in ISO 8601 format");
30
+ export const obsidianSummaryProperty = z
31
+ .string()
32
+ .describe("Brief summary or abstract of the document");
33
+ export const obsidianSlugProperty = z
34
+ .string()
35
+ .describe("URL-friendly identifier for the document");
36
+ export const obsidianCategoryProperty = z
37
+ .string()
38
+ .describe("Category or classification of the document");
39
+ export const obsidianCompletedProperty = z
40
+ .boolean()
41
+ .describe("Indicates whether a task or item is completed");
42
+ // output schema
43
+ export const obsidianPropertyOutputSchema = z
44
+ .object({
45
+ cssclasses: obsidianCssClassesProperty.optional(),
46
+ tags: obsidianTagsProperty.optional(),
47
+ title: obsidianTitleProperty.optional(),
48
+ date: obsidianDateProperty.optional(),
49
+ summary: obsidianSummaryProperty.optional(),
50
+ slug: obsidianSlugProperty.optional(),
51
+ category: obsidianCategoryProperty.optional(),
52
+ completed: obsidianCompletedProperty.optional(),
53
+ })
54
+ .describe("Extracted properties from the Obsidian document content");
55
+ //# sourceMappingURL=params.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"params.js","sourceRoot":"","sources":["../../../src/tools/generate_property/params.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,mBAAmB;AACnB,MAAM,6BAA6B,GAAG,CAAC;KACrC,MAAM,EAAE;KACR,QAAQ,CACR,0FAA0F,CAC1F,CAAC;AACH,MAAM,8BAA8B,GAAG,CAAC;KACtC,OAAO,EAAE;KACT,OAAO,CAAC,IAAI,CAAC;KACb,QAAQ,CACR,sGAAsG,CACtG,CAAC;AAEH,eAAe;AACf,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC;KAChD,MAAM,CAAC;IACP,QAAQ,EAAE,6BAA6B;IACvC,SAAS,EAAE,8BAA8B,CAAC,QAAQ,EAAE;CACpD,CAAC;KACD,QAAQ,CACR,oEAAoE,CACpE,CAAC;AAMH,oBAAoB;AACpB,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC;KACzC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;KACjB,QAAQ,CAAC,kDAAkD,CAAC,CAAC;AAC/D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC;KACnC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;KACjB,QAAQ,CAAC,2CAA2C,CAAC,CAAC;AACxD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC;KACpC,MAAM,EAAE;KACR,QAAQ,CAAC,uBAAuB,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC;KACnC,MAAM,EAAE;KACR,QAAQ,CAAC,kDAAkD,CAAC,CAAC;AAC/D,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC;KACtC,MAAM,EAAE;KACR,QAAQ,CAAC,2CAA2C,CAAC,CAAC;AACxD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC;KACnC,MAAM,EAAE;KACR,QAAQ,CAAC,0CAA0C,CAAC,CAAC;AACvD,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC;KACvC,MAAM,EAAE;KACR,QAAQ,CAAC,4CAA4C,CAAC,CAAC;AACzD,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC;KACxC,OAAO,EAAE;KACT,QAAQ,CAAC,+CAA+C,CAAC,CAAC;AAE5D,gBAAgB;AAChB,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC;KAC3C,MAAM,CAAC;IACP,UAAU,EAAE,0BAA0B,CAAC,QAAQ,EAAE;IACjD,IAAI,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IACrC,KAAK,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IACvC,IAAI,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IACrC,OAAO,EAAE,uBAAuB,CAAC,QAAQ,EAAE;IAC3C,IAAI,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IACrC,QAAQ,EAAE,wBAAwB,CAAC,QAAQ,EAAE;IAC7C,SAAS,EAAE,yBAAyB,CAAC,QAAQ,EAAE;CAC/C,CAAC;KACD,QAAQ,CAAC,yDAAyD,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import CreateDocumentWithPropertyTool from "../tools/create_document_with_properties/index.js";
2
+ import GenerateObsidianVaultPropertiesTool from "../tools/generate_property/index.js";
3
+ import OrganizeAttachmentsTool from "../tools/organize_attachments/index.js";
4
+ import ObsidianVaultTool from "../tools/vault/index.js";
5
+ import WriteObsidianPropertyTool from "../tools/write_property/index.js";
6
+ export default {
7
+ ObsidianVaultTool,
8
+ GenerateObsidianVaultPropertiesTool,
9
+ WriteObsidianPropertyTool,
10
+ CreateDocumentWithPropertyTool,
11
+ OrganizeAttachmentsTool,
12
+ };
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,8BAA8B,MAAM,kDAAkD,CAAC;AAC9F,OAAO,mCAAmC,MAAM,oCAAoC,CAAC;AACrF,OAAO,uBAAuB,MAAM,uCAAuC,CAAC;AAC5E,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;AACvD,OAAO,yBAAyB,MAAM,iCAAiC,CAAC;AAExE,eAAe;IACd,iBAAiB;IACjB,mCAAmC;IACnC,yBAAyB;IACzB,8BAA8B;IAC9B,uBAAuB;CACvB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import type { CallToolResult, ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
3
- import { type OrganizeAttachmentsParams } from "@/tools/organize_attachments/params.js";
3
+ import { type OrganizeAttachmentsParams } from "../../tools/organize_attachments/params.js";
4
4
  export declare const name = "organize_attachments";
5
5
  export declare const annotations: ToolAnnotations;
6
6
  export declare const description = "\n Scans a specified markdown file for linked images (or other attachments),\n moves them to a dedicated folder named after the document's title,\n and updates the links within the markdown file automatically.\n\n Use Cases:\n - When a post is finalized and you want to clean up all associated images into a neat folder.\n - To automatically organize attachments for better vault management.\n\n Example Workflow:\n 1. Specify 'my-awesome-post.md' as the fileName.\n 2. The tool finds the 'title' property in the frontmatter (e.g., \"My Awesome Post\").\n 3. It finds all image links like ![[my-image.png]].\n 4. It creates a folder at '{vault}/images/My Awesome Post/'.\n 5. It moves 'my-image.png' into that new folder.\n 6. It updates the link in the markdown file to ![[images/My Awesome Post/my-image.png]].\n";
@@ -0,0 +1,86 @@
1
+ import state from "../../config.js";
2
+ import { organizeAttachmentsParamsSchema, } from "../../tools/organize_attachments/params.js";
3
+ import { genreateOrganizationTasks } from "../../tools/organize_attachments/utils.js";
4
+ import { createToolError } from "../../utils/createToolError.js";
5
+ import { getGlobalVaultManager } from "../../utils/getVaultManager.js";
6
+ export const name = "organize_attachments";
7
+ export const annotations = {
8
+ title: "Organize Attachments",
9
+ openWorldHint: true,
10
+ };
11
+ export const description = `
12
+ Scans a specified markdown file for linked images (or other attachments),
13
+ moves them to a dedicated folder named after the document's title,
14
+ and updates the links within the markdown file automatically.
15
+
16
+ Use Cases:
17
+ - When a post is finalized and you want to clean up all associated images into a neat folder.
18
+ - To automatically organize attachments for better vault management.
19
+
20
+ Example Workflow:
21
+ 1. Specify 'my-awesome-post.md' as the fileName.
22
+ 2. The tool finds the 'title' property in the frontmatter (e.g., "My Awesome Post").
23
+ 3. It finds all image links like ![[my-image.png]].
24
+ 4. It creates a folder at '{vault}/images/My Awesome Post/'.
25
+ 5. It moves 'my-image.png' into that new folder.
26
+ 6. It updates the link in the markdown file to ![[images/My Awesome Post/my-image.png]].
27
+ `;
28
+ export const register = (mcpServer) => {
29
+ mcpServer.registerTool(name, {
30
+ title: annotations.title || name,
31
+ description: description,
32
+ inputSchema: organizeAttachmentsParamsSchema.shape,
33
+ annotations: annotations,
34
+ }, execute);
35
+ };
36
+ export const execute = async (params) => {
37
+ const vaultDirPath = state.vaultPath;
38
+ if (!vaultDirPath) {
39
+ return createToolError("VAULT_DIR_PATH is not set", "Set the VAULT_DIR_PATH environment variable to your Obsidian vault path.");
40
+ }
41
+ let vaultManager = null;
42
+ try {
43
+ vaultManager = getGlobalVaultManager();
44
+ }
45
+ catch (e) {
46
+ return createToolError(e.message);
47
+ }
48
+ try {
49
+ await vaultManager.initialize();
50
+ const documents = await vaultManager.searchDocuments(params.keyword);
51
+ if (documents.length === 0) {
52
+ return createToolError(`No document found for keyword: ${params.keyword}`, "Try a different keyword or use the vault tool with 'list_all' action to see available documents.");
53
+ }
54
+ const organizationTasks = genreateOrganizationTasks(documents, vaultDirPath);
55
+ const results = await Promise.all(organizationTasks.map((task) => task()));
56
+ return {
57
+ isError: false,
58
+ content: [
59
+ {
60
+ type: "text",
61
+ text: JSON.stringify({
62
+ summary: `Processed ${documents.length} document(s).`,
63
+ details: results,
64
+ }, null, 2),
65
+ },
66
+ ],
67
+ };
68
+ }
69
+ catch (error) {
70
+ return createToolError(error.message);
71
+ }
72
+ };
73
+ const shorthandDescription = {
74
+ ko: "지정된 마크다운 문서의 첨부 이미지들을 문서 제목 기반의 전용 폴더로 일괄 이동시키고, 문서 내 이미지 링크를 자동으로 업데이트합니다. Vault 내 에셋을 깔끔하게 정리할 때 사용합니다.",
75
+ en: "Organizes document attachments by moving linked images into a title-specific folder and automatically updating the Markdown links.",
76
+ };
77
+ export default {
78
+ name,
79
+ description,
80
+ annotations,
81
+ inputSchema: organizeAttachmentsParamsSchema.shape,
82
+ execute,
83
+ register,
84
+ shorthandDescription,
85
+ };
86
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/organize_attachments/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,aAAa,CAAC;AAChC,OAAO,EAEN,+BAA+B,GAC/B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,MAAM,CAAC,MAAM,IAAI,GAAG,sBAAsB,CAAC;AAE3C,MAAM,CAAC,MAAM,WAAW,GAAoB;IAC3C,KAAK,EAAE,sBAAsB;IAC7B,aAAa,EAAE,IAAI;CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;CAgB1B,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,SAAoB,EAAE,EAAE;IAChD,SAAS,CAAC,YAAY,CACrB,IAAI,EACJ;QACC,KAAK,EAAE,WAAW,CAAC,KAAK,IAAI,IAAI;QAChC,WAAW,EAAE,WAAW;QACxB,WAAW,EAAE,+BAA+B,CAAC,KAAK;QAClD,WAAW,EAAE,WAAW;KACxB,EACD,OAAO,CACP,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAC3B,MAAiC,EACP,EAAE;IAC5B,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC;IACrC,IAAI,CAAC,YAAY,EAAE,CAAC;QACnB,OAAO,eAAe,CACrB,2BAA2B,EAC3B,0EAA0E,CAC1E,CAAC;IACH,CAAC;IAED,IAAI,YAAY,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC;QACJ,YAAY,GAAG,qBAAqB,EAAE,CAAC;IACxC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,OAAO,eAAe,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,CAAC;QACJ,MAAM,YAAY,CAAC,UAAU,EAAE,CAAC;QAEhC,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,eAAe,CACrB,kCAAkC,MAAM,CAAC,OAAO,EAAE,EAClD,kGAAkG,CAClG,CAAC;QACH,CAAC;QAED,MAAM,iBAAiB,GAAG,yBAAyB,CAClD,SAAS,EACT,YAAY,CACZ,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAE3E,OAAO;YACN,OAAO,EAAE,KAAK;YACd,OAAO,EAAE;gBACR;oBACC,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CACnB;wBACC,OAAO,EAAE,aAAa,SAAS,CAAC,MAAM,eAAe;wBACrD,OAAO,EAAE,OAAO;qBAChB,EACD,IAAI,EACJ,CAAC,CACD;iBACD;aACD;SACD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,eAAe,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;AACF,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG;IAC5B,EAAE,EAAE,2GAA2G;IAC/G,EAAE,EAAE,oIAAoI;CACxI,CAAC;AAEF,eAAe;IACd,IAAI;IACJ,WAAW;IACX,WAAW;IACX,WAAW,EAAE,+BAA+B,CAAC,KAAK;IAClD,OAAO;IACP,QAAQ;IACR,oBAAoB;CACpB,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { z } from "zod";
2
+ export const organizeAttachmentsParamsSchema = z
3
+ .object({
4
+ keyword: z
5
+ .string()
6
+ .describe("A keyword to search for the markdown file within the vault."),
7
+ destination: z
8
+ .string()
9
+ .optional()
10
+ .default("images")
11
+ .describe('The base folder to move attachments into. Defaults to "images".'),
12
+ useTitleAsFolderName: z
13
+ .boolean()
14
+ .optional()
15
+ .default(true)
16
+ .describe("If true, creates a subfolder named after the document title. Defaults to true."),
17
+ quiet: z
18
+ .boolean()
19
+ .optional()
20
+ .default(false)
21
+ .describe("If true, returns a minimal success message."),
22
+ })
23
+ .describe("Parameters for organizing attachments of a markdown file");
24
+ export const OrganizeAttachmentsDetailSchema = z
25
+ .object({
26
+ document: z
27
+ .string()
28
+ .describe("The path of the processed markdown document."),
29
+ status: z
30
+ .enum(["skipped", "completed", "success", "moved", "error"])
31
+ .describe("The status of the operation."),
32
+ message: z
33
+ .string()
34
+ .optional()
35
+ .describe("A message providing additional information, especially if skipped."),
36
+ movedFiles: z
37
+ .number()
38
+ .optional()
39
+ .describe('The number of files successfully moved. Present if status is "completed" or "moved".'),
40
+ targetDirectory: z
41
+ .string()
42
+ .optional()
43
+ .describe('The directory where attachments were moved. Present if status is "completed" or "moved".'),
44
+ errors: z
45
+ .array(z.object({
46
+ imageName: z
47
+ .string()
48
+ .describe("The name of the image that failed to move."),
49
+ reason: z.string().describe("The reason for the failure."),
50
+ }))
51
+ .optional()
52
+ .describe("List of errors encountered during the move operation. Present if any errors occurred."),
53
+ })
54
+ .describe("Result of organizing attachments for a single document");
55
+ export const OrganizeAttachmentsResultSchema = z.object({
56
+ summary: z.string().describe("A summary message of the overall operation."),
57
+ details: z
58
+ .array(OrganizeAttachmentsDetailSchema)
59
+ .describe("Array of results for each processed document."),
60
+ });
61
+ //# sourceMappingURL=params.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"params.js","sourceRoot":"","sources":["../../../src/tools/organize_attachments/params.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC;KAC9C,MAAM,CAAC;IACP,OAAO,EAAE,CAAC;SACR,MAAM,EAAE;SACR,QAAQ,CAAC,6DAA6D,CAAC;IACzE,WAAW,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,OAAO,CAAC,QAAQ,CAAC;SACjB,QAAQ,CACR,iEAAiE,CACjE;IACF,oBAAoB,EAAE,CAAC;SACrB,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CACR,gFAAgF,CAChF;IACF,KAAK,EAAE,CAAC;SACN,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,6CAA6C,CAAC;CACzD,CAAC;KACD,QAAQ,CAAC,0DAA0D,CAAC,CAAC;AAMvE,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC;KAC9C,MAAM,CAAC;IACP,QAAQ,EAAE,CAAC;SACT,MAAM,EAAE;SACR,QAAQ,CAAC,8CAA8C,CAAC;IAC1D,MAAM,EAAE,CAAC;SACP,IAAI,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;SAC3D,QAAQ,CAAC,8BAA8B,CAAC;IAC1C,OAAO,EAAE,CAAC;SACR,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACR,oEAAoE,CACpE;IACF,UAAU,EAAE,CAAC;SACX,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACR,sFAAsF,CACtF;IACF,eAAe,EAAE,CAAC;SAChB,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACR,0FAA0F,CAC1F;IACF,MAAM,EAAE,CAAC;SACP,KAAK,CACL,CAAC,CAAC,MAAM,CAAC;QACR,SAAS,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,CAAC,4CAA4C,CAAC;QACxD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;KAC1D,CAAC,CACF;SACA,QAAQ,EAAE;SACV,QAAQ,CACR,uFAAuF,CACvF;CACF,CAAC;KACD,QAAQ,CAAC,wDAAwD,CAAC,CAAC;AAErE,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC,MAAM,CAAC;IACvD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;IAC3E,OAAO,EAAE,CAAC;SACR,KAAK,CAAC,+BAA+B,CAAC;SACtC,QAAQ,CAAC,+CAA+C,CAAC;CAC3D,CAAC,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { DocumentIndex } from "@/utils/processor/types.js";
1
+ import type { DocumentIndex } from "../../utils/processor/types.js";
2
2
  type MoveError = {
3
3
  status: "error";
4
4
  imageName: string;
@@ -0,0 +1,66 @@
1
+ import { existsSync } from "node:fs";
2
+ import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
3
+ import { basename, dirname, join } from "node:path";
4
+ export function genreateOrganizationTasks(documents, vaultDirPath) {
5
+ return documents.map((doc) => async () => {
6
+ const docTitle = doc.frontmatter?.title || basename(doc.filePath, ".md");
7
+ const sanitizedTitle = docTitle.replace(/[\\?%*:|"<>]/g, "-");
8
+ const imageLinks = doc.imageLinks || [];
9
+ if (imageLinks.length === 0) {
10
+ return {
11
+ document: doc.filePath,
12
+ status: "skipped",
13
+ message: "No image links found.",
14
+ movedFiles: [],
15
+ };
16
+ }
17
+ const destinationFolder = "images";
18
+ const targetDir = join(destinationFolder, sanitizedTitle);
19
+ const targetDirFullPath = join(vaultDirPath, targetDir);
20
+ await mkdir(targetDirFullPath, { recursive: true });
21
+ const docDir = dirname(doc.filePath);
22
+ const movePromises = imageLinks.map(async (imageName) => {
23
+ const originalImagePath = join(vaultDirPath, imageName);
24
+ const originalImagePathInDocDir = join(docDir, imageName);
25
+ let sourcePath;
26
+ if (existsSync(originalImagePath)) {
27
+ sourcePath = originalImagePath;
28
+ }
29
+ else if (existsSync(originalImagePathInDocDir)) {
30
+ sourcePath = originalImagePathInDocDir;
31
+ }
32
+ else {
33
+ return { imageName, status: "error", reason: "File not found" };
34
+ }
35
+ const newImageName = basename(imageName);
36
+ const newImagePath = join(targetDirFullPath, newImageName);
37
+ const newLinkPath = join(targetDir, newImageName).replace(/\\/g, "/");
38
+ try {
39
+ await rename(sourcePath, newImagePath);
40
+ return {
41
+ originalLink: `![[${imageName}]]`,
42
+ newLink: `![[${newLinkPath}]]`,
43
+ status: "moved",
44
+ };
45
+ }
46
+ catch (e) {
47
+ return { imageName, status: "error", reason: e.message };
48
+ }
49
+ });
50
+ const moveResults = await Promise.all(movePromises);
51
+ let content = await readFile(doc.filePath, "utf-8");
52
+ const successfullyMoved = moveResults.filter((result) => result.status === "moved");
53
+ for (const result of successfullyMoved) {
54
+ content = content.replace(result.originalLink, result.newLink);
55
+ }
56
+ await writeFile(doc.filePath, content, "utf-8");
57
+ return {
58
+ document: doc.filePath,
59
+ status: "success",
60
+ targetDirectory: targetDir,
61
+ movedFiles: successfullyMoved.length,
62
+ errors: moveResults.filter((r) => r.status === "error"),
63
+ };
64
+ });
65
+ }
66
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/tools/organize_attachments/utils.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import type { CallToolResult, ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
3
- import { type ObsidianContentQueryParams } from "@/tools/vault/params.js";
3
+ import { type ObsidianContentQueryParams } from "../../tools/vault/params.js";
4
4
  export declare const name = "vault";
5
5
  export declare const annotations: ToolAnnotations;
6
6
  export declare const description = "\n Retrieves and searches the content of Markdown (.md, .mdx) documents stored in an Obsidian vault. Use this tool to find notes related to a specific topic or keyword and understand their core content.\n\n When to use:\n - When you need to find a specific note by its title or a keyword to check its content.\n - When you want to synthesize and summarize information scattered across multiple notes.\n - When looking for answers to questions based on your saved records, such as \"What was the project deadline?\"\n - To discover connections by finding all notes that link to a specific note.\n - When you need to retrieve a list of unfinished tasks (- [ ]) from daily notes or meeting minutes.\n - Use \"index_vault_to_vectordb\" to manually trigger a full re-indexing of the vault for the vector database.\n\n Returns the content of the most relevant document(s) in text format. It can also include metadata such as the document's title, tags, and creation date.\n\n Requirements: The user's Obsidian Vault path must be correctly configured in an environment variable or a similar setting. For searches, use the exact filename or include core keywords for content-based queries.\n\n IMPORTANT INSTRUCTION FOR AI:\n If the tool response includes a 'diagnostic_message' (usually found at the beginning of the text or in a <system_directive> tag), you MUST relay this information to the user exactly once. It contains essential advice on how to improve search quality by running a local setup script via 'bunx obsidian-mcp-setup'. Do not ignore it.\n";
@@ -0,0 +1,104 @@
1
+ import state from "../../config.js";
2
+ import { recordVaultResponseMetric } from "../../tools/vault/metrics.js";
3
+ import { obsidianContentQueryParamsZod, } from "../../tools/vault/params.js";
4
+ import { collectContext, listAllDocuments, loadMemory, readSpecificFile, searchDocuments, statsAllDocuments, triggerIndexing, } from "../../tools/vault/utils.js";
5
+ import { createToolError } from "../../utils/createToolError.js";
6
+ import { getGlobalVaultManager } from "../../utils/getVaultManager.js";
7
+ export const name = "vault";
8
+ export const annotations = {
9
+ title: "Obsidian Content Getter",
10
+ openWorldHint: true,
11
+ };
12
+ export const description = `
13
+ Retrieves and searches the content of Markdown (.md, .mdx) documents stored in an Obsidian vault. Use this tool to find notes related to a specific topic or keyword and understand their core content.
14
+
15
+ When to use:
16
+ - When you need to find a specific note by its title or a keyword to check its content.
17
+ - When you want to synthesize and summarize information scattered across multiple notes.
18
+ - When looking for answers to questions based on your saved records, such as "What was the project deadline?"
19
+ - To discover connections by finding all notes that link to a specific note.
20
+ - When you need to retrieve a list of unfinished tasks (- [ ]) from daily notes or meeting minutes.
21
+ - Use "index_vault_to_vectordb" to manually trigger a full re-indexing of the vault for the vector database.
22
+
23
+ Returns the content of the most relevant document(s) in text format. It can also include metadata such as the document's title, tags, and creation date.
24
+
25
+ Requirements: The user's Obsidian Vault path must be correctly configured in an environment variable or a similar setting. For searches, use the exact filename or include core keywords for content-based queries.
26
+
27
+ IMPORTANT INSTRUCTION FOR AI:
28
+ If the tool response includes a 'diagnostic_message' (usually found at the beginning of the text or in a <system_directive> tag), you MUST relay this information to the user exactly once. It contains essential advice on how to improve search quality by running a local setup script via 'bunx obsidian-mcp-setup'. Do not ignore it.
29
+ `;
30
+ export const register = (mcpServer) => {
31
+ mcpServer.registerTool(name, {
32
+ title: annotations.title || name,
33
+ description: description,
34
+ inputSchema: obsidianContentQueryParamsZod.shape,
35
+ annotations: annotations,
36
+ }, execute);
37
+ };
38
+ export const execute = async (params) => {
39
+ const vaultDirPath = state.vaultPath;
40
+ // Vault 경로 검증
41
+ if (!vaultDirPath) {
42
+ return createToolError("VAULT_DIR_PATH environment variable is not set", "Set VAULT_DIR_PATH to your Obsidian vault directory");
43
+ }
44
+ let vaultManager = null;
45
+ try {
46
+ vaultManager = getGlobalVaultManager();
47
+ }
48
+ catch (e) {
49
+ return createToolError(e.message);
50
+ }
51
+ try {
52
+ let result;
53
+ switch (params.action) {
54
+ case "search":
55
+ if (!params.keyword?.trim()) {
56
+ return createToolError("keyword parameter is required for search action", 'Provide a keyword, e.g. { action: "search", keyword: "project" }');
57
+ }
58
+ result = await searchDocuments(vaultManager, params);
59
+ break;
60
+ case "read":
61
+ if (!params.filename?.trim()) {
62
+ return createToolError("filename parameter is required for read action", 'Provide a filename, e.g. { action: "read", filename: "meeting-notes.md" }');
63
+ }
64
+ result = await readSpecificFile(vaultManager, params);
65
+ break;
66
+ case "list_all":
67
+ result = await listAllDocuments(vaultManager, params);
68
+ break;
69
+ case "stats":
70
+ result = await statsAllDocuments(vaultManager);
71
+ break;
72
+ case "collect_context":
73
+ result = await collectContext(vaultManager, params);
74
+ break;
75
+ case "load_memory":
76
+ result = await loadMemory(vaultManager, params);
77
+ break;
78
+ case "index_vault_to_vectordb":
79
+ result = await triggerIndexing();
80
+ break;
81
+ default:
82
+ return createToolError(`Unknown action: ${params.action}`, "Valid actions are: search, read, list_all, stats, collect_context, load_memory, index_vault_to_vectordb");
83
+ }
84
+ await recordVaultResponseMetric(params.action, result);
85
+ return result;
86
+ }
87
+ catch (error) {
88
+ return createToolError(`Execution failed: ${error instanceof Error ? error.message : String(error)}`);
89
+ }
90
+ };
91
+ export const shorthandDescription = {
92
+ ko: "키워드나 제목을 기반으로 설정된 Obsidian Vault 내의 Markdown 문서(.md, .mdx)를 검색하고 조회합니다. 특정 노트 확인, 정보 요약, 백링크 탐색, 미완료 할 일 추출에 사용되며 문서의 본문과 메타데이터를 반환합니다.",
93
+ en: "Retrieves Obsidian vault Markdown files by keyword or title to extract content, metadata, links, and unfinished tasks.",
94
+ };
95
+ export default {
96
+ name,
97
+ description,
98
+ annotations,
99
+ inputSchema: obsidianContentQueryParamsZod.shape,
100
+ execute,
101
+ register,
102
+ shorthandDescription,
103
+ };
104
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/vault/index.ts"],"names":[],"mappings":"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"}