obsidian-mcp-server 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)
4
4
  [![Model Context Protocol](https://img.shields.io/badge/MCP-1.4.0-green.svg)](https://modelcontextprotocol.io/)
5
- [![Version](https://img.shields.io/badge/Version-1.2.0-blue.svg)]()
5
+ [![Version](https://img.shields.io/badge/Version-1.2.2-blue.svg)]()
6
6
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
7
7
  [![Status](https://img.shields.io/badge/Status-Stable-blue.svg)]()
8
8
  [![GitHub](https://img.shields.io/github/stars/cyanheads/obsidian-mcp-server?style=social)](https://github.com/cyanheads/obsidian-mcp-server)
@@ -16,25 +16,21 @@ Requires the Local REST API plugin in Obsidian.
16
16
  ## Features
17
17
 
18
18
  ### File Operations
19
- - Path-based file/directory management with atomic updates
20
- - Content read/write operations with validation
19
+ - Atomic file/directory operations with validation
21
20
  - Resource monitoring and cleanup
22
21
 
23
22
  ### Search System
24
- - Full-text and JsonLogic-based complex search
25
- - Configurable context boundaries and token limits
26
- - Optimized query processing
23
+ - Full-text and JsonLogic search with context control
24
+ - Optimized query processing with token limits
27
25
 
28
26
  ### Property Management
29
- - YAML frontmatter parsing and validation
30
- - Intelligent property merging and updates
31
- - Automatic timestamp management
27
+ - YAML frontmatter parsing and intelligent merging
28
+ - Automatic timestamps (created by Obsidian, modified by server)
32
29
  - Custom field support
33
30
 
34
31
  ### Security & Performance
35
- - API key authentication and rate limiting
36
- - SSL verification options
37
- - Resource management and health monitoring
32
+ - API key auth with rate limiting and SSL options
33
+ - Resource monitoring and health checks
38
34
 
39
35
  ## Installation
40
36
 
@@ -138,9 +134,8 @@ obsidian_update_properties: {
138
134
  filepath: string, // Path relative to vault root
139
135
  properties: {
140
136
  title?: string,
141
- created?: string, // ISO date
142
- modified?: string, // ISO date (auto-updated)
143
137
  author?: string,
138
+ // Note: created/modified timestamps are managed automatically
144
139
  type?: Array<"concept" | "architecture" | "specification" |
145
140
  "protocol" | "api" | "research" | "implementation" |
146
141
  "guide" | "reference">,
@@ -161,28 +156,21 @@ obsidian_update_properties: {
161
156
  ## Best Practices
162
157
 
163
158
  ### File Operations
164
- - Use atomic operations
165
- - Validate content before modifications
166
- - Implement proper error handling
167
- - Monitor operation performance
159
+ - Use atomic operations with validation
160
+ - Handle errors and monitor performance
168
161
 
169
162
  ### Search Implementation
170
- - Optimize query specificity
171
- - Control context boundaries
172
- - Handle large result sets
173
- - Consider token limits
163
+ - Optimize queries and control context size
164
+ - Handle large results within token limits
174
165
 
175
166
  ### Property Management
176
- - Validate property values before updates
177
- - Use appropriate property types
178
- - Handle array merging appropriately
179
- - Consider custom field implications
167
+ - Use appropriate types and validate updates
168
+ - Handle arrays and custom fields properly
169
+ - Never set timestamps (managed automatically)
180
170
 
181
171
  ### Error Prevention
182
- - Validate inputs thoroughly
183
- - Handle API errors gracefully
184
- - Monitor error patterns
185
- - Check rate limits
172
+ - Validate inputs and handle errors gracefully
173
+ - Monitor patterns and respect rate limits
186
174
 
187
175
  ## Contributing
188
176
 
@@ -13,13 +13,19 @@ export class GetPropertiesToolHandler extends BaseToolHandler {
13
13
  getToolDescription() {
14
14
  return {
15
15
  name: this.name,
16
- description: "Get properties from an Obsidian note's frontmatter.",
16
+ description: "Get properties (title, tags, status, etc.) from an Obsidian note's YAML frontmatter. Returns all available properties including custom fields.",
17
17
  examples: [
18
18
  {
19
19
  description: "Get properties from a note",
20
20
  args: {
21
21
  filepath: "path/to/note.md"
22
22
  }
23
+ },
24
+ {
25
+ description: "Get properties from a documentation file",
26
+ args: {
27
+ filepath: "docs/architecture.md"
28
+ }
23
29
  }
24
30
  ],
25
31
  inputSchema: {
@@ -54,16 +60,40 @@ export class UpdatePropertiesToolHandler extends BaseToolHandler {
54
60
  getToolDescription() {
55
61
  return {
56
62
  name: this.name,
57
- description: "Update properties in an Obsidian note's frontmatter.",
63
+ description: "Update properties in an Obsidian note's YAML frontmatter. Intelligently merges arrays (tags, type, status), handles custom fields, and automatically updates the modified timestamp. Existing properties not included in the update are preserved.",
58
64
  examples: [
59
65
  {
60
- description: "Update note properties",
66
+ description: "Update basic metadata",
61
67
  args: {
62
68
  filepath: "path/to/note.md",
63
69
  properties: {
64
- title: "New Title",
65
- tags: ["#tag1", "#tag2"],
66
- status: ["in-progress"]
70
+ title: "Architecture Overview",
71
+ author: "Development Team",
72
+ type: ["architecture", "specification"]
73
+ }
74
+ }
75
+ },
76
+ {
77
+ description: "Update tags and status",
78
+ args: {
79
+ filepath: "docs/feature.md",
80
+ properties: {
81
+ tags: ["#feature", "#in-development", "#high-priority"],
82
+ status: ["in-progress"],
83
+ version: "2.0.0"
84
+ }
85
+ }
86
+ },
87
+ {
88
+ description: "Add custom fields",
89
+ args: {
90
+ filepath: "projects/project-x.md",
91
+ properties: {
92
+ custom: {
93
+ priority: "high",
94
+ reviewedBy: ["Alice", "Bob"],
95
+ dueDate: "2025-03-01"
96
+ }
67
97
  }
68
98
  }
69
99
  }
package/build/tools.js CHANGED
@@ -101,11 +101,31 @@ export class ListFilesInVaultToolHandler extends BaseToolHandler {
101
101
  getToolDescription() {
102
102
  return {
103
103
  name: this.name,
104
- description: "Lists all files and directories in the root directory of your Obsidian vault.",
104
+ description: "Lists all files and directories in the root directory of your Obsidian vault. Returns a hierarchical structure of files and folders, including metadata like file type.",
105
105
  examples: [
106
106
  {
107
107
  description: "List all files in vault",
108
108
  args: {}
109
+ },
110
+ {
111
+ description: "Example response",
112
+ args: {},
113
+ response: [
114
+ {
115
+ "path": "Daily Notes",
116
+ "type": "folder",
117
+ "children": [
118
+ { "path": "Daily Notes/2025-01-24.md", "type": "file" }
119
+ ]
120
+ },
121
+ {
122
+ "path": "Projects",
123
+ "type": "folder",
124
+ "children": [
125
+ { "path": "Projects/MCP.md", "type": "file" }
126
+ ]
127
+ }
128
+ ]
109
129
  }
110
130
  ],
111
131
  inputSchema: {
@@ -132,13 +152,36 @@ export class ListFilesInDirToolHandler extends BaseToolHandler {
132
152
  getToolDescription() {
133
153
  return {
134
154
  name: this.name,
135
- description: "Lists all files and directories that exist in a specific Obsidian directory.",
155
+ description: "Lists all files and directories that exist in a specific Obsidian directory. Returns a hierarchical structure showing files, folders, and their relationships. Useful for exploring vault organization and finding specific files.",
136
156
  examples: [
137
157
  {
138
158
  description: "List files in Documents folder",
139
159
  args: {
140
160
  dirpath: "Documents"
141
161
  }
162
+ },
163
+ {
164
+ description: "Example response structure",
165
+ args: {
166
+ dirpath: "Projects"
167
+ },
168
+ response: [
169
+ {
170
+ "path": "Projects/Active",
171
+ "type": "folder",
172
+ "children": [
173
+ { "path": "Projects/Active/ProjectA.md", "type": "file" },
174
+ { "path": "Projects/Active/ProjectB.md", "type": "file" }
175
+ ]
176
+ },
177
+ {
178
+ "path": "Projects/Archive",
179
+ "type": "folder",
180
+ "children": [
181
+ { "path": "Projects/Archive/OldProject.md", "type": "file" }
182
+ ]
183
+ }
184
+ ]
142
185
  }
143
186
  ],
144
187
  inputSchema: {
@@ -171,7 +214,21 @@ export class GetFileContentsToolHandler extends BaseToolHandler {
171
214
  getToolDescription() {
172
215
  return {
173
216
  name: this.name,
174
- description: "Return the content of a single file in your vault.",
217
+ description: "Return the content of a single file in your vault. Supports markdown files, text files, and other readable formats. Returns the raw content including any YAML frontmatter.",
218
+ examples: [
219
+ {
220
+ description: "Get content of a markdown note",
221
+ args: {
222
+ filepath: "Projects/research.md"
223
+ }
224
+ },
225
+ {
226
+ description: "Get content of a configuration file",
227
+ args: {
228
+ filepath: "configs/settings.yml"
229
+ }
230
+ }
231
+ ],
175
232
  inputSchema: {
176
233
  type: "object",
177
234
  properties: {
@@ -202,17 +259,43 @@ export class FindInFileToolHandler extends BaseToolHandler {
202
259
  getToolDescription() {
203
260
  return {
204
261
  name: this.name,
205
- description: "Simple search that returns filenames of documents matching a specified text query across all files in the vault.",
262
+ description: "Full-text search across all files in the vault. Returns matching files with surrounding context for each match. Useful for finding specific content, references, or patterns across notes.",
263
+ examples: [
264
+ {
265
+ description: "Search for a specific term",
266
+ args: {
267
+ query: "neural networks",
268
+ contextLength: 20
269
+ }
270
+ },
271
+ {
272
+ description: "Search with default context",
273
+ args: {
274
+ query: "#todo"
275
+ },
276
+ response: [
277
+ {
278
+ "filename": "Projects/AI.md",
279
+ "matches": [
280
+ {
281
+ "context": "Research needed:\n#todo Implement transformer architecture\nDeadline: Next week",
282
+ "match": { "start": 15, "end": 45 }
283
+ }
284
+ ]
285
+ }
286
+ ]
287
+ }
288
+ ],
206
289
  inputSchema: {
207
290
  type: "object",
208
291
  properties: {
209
292
  query: {
210
293
  type: "string",
211
- description: "Text to search for in the vault."
294
+ description: "Text pattern to search for. Can include tags, keywords, or phrases."
212
295
  },
213
296
  contextLength: {
214
297
  type: "integer",
215
- description: "How much context to use for matching (default: 10)",
298
+ description: "Number of characters to include before and after each match for context (default: 10)",
216
299
  default: 10
217
300
  }
218
301
  },
@@ -334,23 +417,45 @@ export class ComplexSearchToolHandler extends BaseToolHandler {
334
417
  getToolDescription() {
335
418
  return {
336
419
  name: this.name,
337
- description: "Complex search for documents using a JsonLogic query.",
420
+ description: "Advanced search functionality using JsonLogic queries. Enables complex file filtering based on paths, metadata, modification times, and content patterns. Supports logical operations, date comparisons, and pattern matching.",
338
421
  examples: [
339
422
  {
340
- description: "Find all markdown files",
423
+ description: "Find markdown files in a specific folder",
424
+ args: {
425
+ query: {
426
+ "and": [
427
+ { "glob": ["Projects/*.md", { "var": "path" }] },
428
+ { "contains": [{ "var": "content" }, "#active"] }
429
+ ]
430
+ }
431
+ }
432
+ },
433
+ {
434
+ description: "Find recently modified documentation",
341
435
  args: {
342
436
  query: {
343
- "glob": ["*.md", { "var": "path" }]
437
+ "and": [
438
+ { "glob": ["docs/*.md", { "var": "path" }] },
439
+ { ">=": [
440
+ { "var": "mtime" },
441
+ { "date": "-7 days" }
442
+ ] },
443
+ { "!=": [{ "var": "size" }, 0] }
444
+ ]
344
445
  }
345
446
  }
346
447
  },
347
448
  {
348
- description: "Find files modified in last week",
449
+ description: "Find files by multiple criteria",
349
450
  args: {
350
451
  query: {
351
- ">=": [
352
- { "var": "mtime" },
353
- { "date": "-7 days" }
452
+ "and": [
453
+ { "or": [
454
+ { "glob": ["*.md", { "var": "path" }] },
455
+ { "glob": ["*.txt", { "var": "path" }] }
456
+ ] },
457
+ { "contains": [{ "var": "content" }, "TODO"] },
458
+ { "<": [{ "var": "size" }, 10000] }
354
459
  ]
355
460
  }
356
461
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "obsidian-mcp-server",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Model Context Protocol server for Obsidian integration with token-aware response handling",
5
5
  "main": "build/index.js",
6
6
  "type": "module",
@@ -29,13 +29,19 @@ export class GetPropertiesToolHandler extends BaseToolHandler<GetPropertiesArgs>
29
29
  getToolDescription(): Tool {
30
30
  return {
31
31
  name: this.name,
32
- description: "Get properties from an Obsidian note's frontmatter.",
32
+ description: "Get properties (title, tags, status, etc.) from an Obsidian note's YAML frontmatter. Returns all available properties including custom fields.",
33
33
  examples: [
34
34
  {
35
35
  description: "Get properties from a note",
36
36
  args: {
37
37
  filepath: "path/to/note.md"
38
38
  }
39
+ },
40
+ {
41
+ description: "Get properties from a documentation file",
42
+ args: {
43
+ filepath: "docs/architecture.md"
44
+ }
39
45
  }
40
46
  ],
41
47
  inputSchema: {
@@ -73,16 +79,40 @@ export class UpdatePropertiesToolHandler extends BaseToolHandler<UpdatePropertie
73
79
  getToolDescription(): Tool {
74
80
  return {
75
81
  name: this.name,
76
- description: "Update properties in an Obsidian note's frontmatter.",
82
+ description: "Update properties in an Obsidian note's YAML frontmatter. Intelligently merges arrays (tags, type, status), handles custom fields, and automatically updates the modified timestamp. Existing properties not included in the update are preserved.",
77
83
  examples: [
78
84
  {
79
- description: "Update note properties",
85
+ description: "Update basic metadata",
80
86
  args: {
81
87
  filepath: "path/to/note.md",
82
88
  properties: {
83
- title: "New Title",
84
- tags: ["#tag1", "#tag2"],
85
- status: ["in-progress"]
89
+ title: "Architecture Overview",
90
+ author: "Development Team",
91
+ type: ["architecture", "specification"]
92
+ }
93
+ }
94
+ },
95
+ {
96
+ description: "Update tags and status",
97
+ args: {
98
+ filepath: "docs/feature.md",
99
+ properties: {
100
+ tags: ["#feature", "#in-development", "#high-priority"],
101
+ status: ["in-progress"],
102
+ version: "2.0.0"
103
+ }
104
+ }
105
+ },
106
+ {
107
+ description: "Add custom fields",
108
+ args: {
109
+ filepath: "projects/project-x.md",
110
+ properties: {
111
+ custom: {
112
+ priority: "high",
113
+ reviewedBy: ["Alice", "Bob"],
114
+ dueDate: "2025-03-01"
115
+ }
86
116
  }
87
117
  }
88
118
  }
package/src/tools.ts CHANGED
@@ -138,11 +138,31 @@ export class ListFilesInVaultToolHandler extends BaseToolHandler<Record<string,
138
138
  getToolDescription(): Tool {
139
139
  return {
140
140
  name: this.name,
141
- description: "Lists all files and directories in the root directory of your Obsidian vault.",
141
+ description: "Lists all files and directories in the root directory of your Obsidian vault. Returns a hierarchical structure of files and folders, including metadata like file type.",
142
142
  examples: [
143
143
  {
144
144
  description: "List all files in vault",
145
145
  args: {}
146
+ },
147
+ {
148
+ description: "Example response",
149
+ args: {},
150
+ response: [
151
+ {
152
+ "path": "Daily Notes",
153
+ "type": "folder",
154
+ "children": [
155
+ { "path": "Daily Notes/2025-01-24.md", "type": "file" }
156
+ ]
157
+ },
158
+ {
159
+ "path": "Projects",
160
+ "type": "folder",
161
+ "children": [
162
+ { "path": "Projects/MCP.md", "type": "file" }
163
+ ]
164
+ }
165
+ ]
146
166
  }
147
167
  ],
148
168
  inputSchema: {
@@ -171,13 +191,36 @@ export class ListFilesInDirToolHandler extends BaseToolHandler<ListFilesArgs> {
171
191
  getToolDescription(): Tool {
172
192
  return {
173
193
  name: this.name,
174
- description: "Lists all files and directories that exist in a specific Obsidian directory.",
194
+ description: "Lists all files and directories that exist in a specific Obsidian directory. Returns a hierarchical structure showing files, folders, and their relationships. Useful for exploring vault organization and finding specific files.",
175
195
  examples: [
176
196
  {
177
197
  description: "List files in Documents folder",
178
198
  args: {
179
199
  dirpath: "Documents"
180
200
  }
201
+ },
202
+ {
203
+ description: "Example response structure",
204
+ args: {
205
+ dirpath: "Projects"
206
+ },
207
+ response: [
208
+ {
209
+ "path": "Projects/Active",
210
+ "type": "folder",
211
+ "children": [
212
+ { "path": "Projects/Active/ProjectA.md", "type": "file" },
213
+ { "path": "Projects/Active/ProjectB.md", "type": "file" }
214
+ ]
215
+ },
216
+ {
217
+ "path": "Projects/Archive",
218
+ "type": "folder",
219
+ "children": [
220
+ { "path": "Projects/Archive/OldProject.md", "type": "file" }
221
+ ]
222
+ }
223
+ ]
181
224
  }
182
225
  ],
183
226
  inputSchema: {
@@ -212,7 +255,21 @@ export class GetFileContentsToolHandler extends BaseToolHandler<FileContentsArgs
212
255
  getToolDescription(): Tool {
213
256
  return {
214
257
  name: this.name,
215
- description: "Return the content of a single file in your vault.",
258
+ description: "Return the content of a single file in your vault. Supports markdown files, text files, and other readable formats. Returns the raw content including any YAML frontmatter.",
259
+ examples: [
260
+ {
261
+ description: "Get content of a markdown note",
262
+ args: {
263
+ filepath: "Projects/research.md"
264
+ }
265
+ },
266
+ {
267
+ description: "Get content of a configuration file",
268
+ args: {
269
+ filepath: "configs/settings.yml"
270
+ }
271
+ }
272
+ ],
216
273
  inputSchema: {
217
274
  type: "object",
218
275
  properties: {
@@ -245,17 +302,43 @@ export class FindInFileToolHandler extends BaseToolHandler<SearchArgs> {
245
302
  getToolDescription(): Tool {
246
303
  return {
247
304
  name: this.name,
248
- description: "Simple search that returns filenames of documents matching a specified text query across all files in the vault.",
305
+ description: "Full-text search across all files in the vault. Returns matching files with surrounding context for each match. Useful for finding specific content, references, or patterns across notes.",
306
+ examples: [
307
+ {
308
+ description: "Search for a specific term",
309
+ args: {
310
+ query: "neural networks",
311
+ contextLength: 20
312
+ }
313
+ },
314
+ {
315
+ description: "Search with default context",
316
+ args: {
317
+ query: "#todo"
318
+ },
319
+ response: [
320
+ {
321
+ "filename": "Projects/AI.md",
322
+ "matches": [
323
+ {
324
+ "context": "Research needed:\n#todo Implement transformer architecture\nDeadline: Next week",
325
+ "match": { "start": 15, "end": 45 }
326
+ }
327
+ ]
328
+ }
329
+ ]
330
+ }
331
+ ],
249
332
  inputSchema: {
250
333
  type: "object",
251
334
  properties: {
252
335
  query: {
253
336
  type: "string",
254
- description: "Text to search for in the vault."
337
+ description: "Text pattern to search for. Can include tags, keywords, or phrases."
255
338
  },
256
339
  contextLength: {
257
340
  type: "integer",
258
- description: "How much context to use for matching (default: 10)",
341
+ description: "Number of characters to include before and after each match for context (default: 10)",
259
342
  default: 10
260
343
  }
261
344
  },
@@ -383,23 +466,45 @@ export class ComplexSearchToolHandler extends BaseToolHandler<ComplexSearchArgs>
383
466
  getToolDescription(): Tool {
384
467
  return {
385
468
  name: this.name,
386
- description: "Complex search for documents using a JsonLogic query.",
469
+ description: "Advanced search functionality using JsonLogic queries. Enables complex file filtering based on paths, metadata, modification times, and content patterns. Supports logical operations, date comparisons, and pattern matching.",
387
470
  examples: [
388
471
  {
389
- description: "Find all markdown files",
472
+ description: "Find markdown files in a specific folder",
473
+ args: {
474
+ query: {
475
+ "and": [
476
+ {"glob": ["Projects/*.md", {"var": "path"}]},
477
+ {"contains": [{"var": "content"}, "#active"]}
478
+ ]
479
+ }
480
+ }
481
+ },
482
+ {
483
+ description: "Find recently modified documentation",
390
484
  args: {
391
485
  query: {
392
- "glob": ["*.md", {"var": "path"}]
486
+ "and": [
487
+ {"glob": ["docs/*.md", {"var": "path"}]},
488
+ {">=": [
489
+ {"var": "mtime"},
490
+ {"date": "-7 days"}
491
+ ]},
492
+ {"!=": [{"var": "size"}, 0]}
493
+ ]
393
494
  }
394
495
  }
395
496
  },
396
497
  {
397
- description: "Find files modified in last week",
498
+ description: "Find files by multiple criteria",
398
499
  args: {
399
500
  query: {
400
- ">=": [
401
- {"var": "mtime"},
402
- {"date": "-7 days"}
501
+ "and": [
502
+ {"or": [
503
+ {"glob": ["*.md", {"var": "path"}]},
504
+ {"glob": ["*.txt", {"var": "path"}]}
505
+ ]},
506
+ {"contains": [{"var": "content"}, "TODO"]},
507
+ {"<": [{"var": "size"}, 10000]}
403
508
  ]
404
509
  }
405
510
  }