obsidian-mcp-server 1.2.2 → 1.2.3
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 +1 -1
- package/build/properties.js +5 -4
- package/build/propertyTools.js +2 -3
- package/build/propertyTypes.js +25 -2
- package/package.json +1 -1
- package/src/properties.ts +10 -8
- package/src/propertyTools.ts +2 -3
- package/src/propertyTypes.ts +32 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.typescriptlang.org/)
|
|
4
4
|
[](https://modelcontextprotocol.io/)
|
|
5
|
-
[]()
|
|
6
6
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
7
7
|
[]()
|
|
8
8
|
[](https://github.com/cyanheads/obsidian-mcp-server)
|
package/build/properties.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parse, stringify } from 'yaml';
|
|
2
|
-
import { ObsidianPropertiesSchema } from './propertyTypes.js';
|
|
2
|
+
import { ObsidianPropertiesSchema, PropertyUpdateSchema } from './propertyTypes.js';
|
|
3
3
|
export class PropertyManager {
|
|
4
4
|
client;
|
|
5
5
|
constructor(client) {
|
|
@@ -51,7 +51,7 @@ export class PropertyManager {
|
|
|
51
51
|
* Validate property values
|
|
52
52
|
*/
|
|
53
53
|
validateProperties(properties) {
|
|
54
|
-
const result =
|
|
54
|
+
const result = PropertyUpdateSchema.safeParse(properties);
|
|
55
55
|
if (result.success) {
|
|
56
56
|
return { valid: true, errors: [] };
|
|
57
57
|
}
|
|
@@ -66,7 +66,8 @@ export class PropertyManager {
|
|
|
66
66
|
mergeProperties(existing, updates) {
|
|
67
67
|
const merged = { ...existing };
|
|
68
68
|
for (const [key, value] of Object.entries(updates)) {
|
|
69
|
-
|
|
69
|
+
// Skip undefined values and timestamp fields
|
|
70
|
+
if (value === undefined || key === 'created' || key === 'modified')
|
|
70
71
|
continue;
|
|
71
72
|
const currentValue = merged[key];
|
|
72
73
|
// Special handling for arrays - merge rather than replace
|
|
@@ -87,7 +88,7 @@ export class PropertyManager {
|
|
|
87
88
|
merged[key] = value;
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
|
-
// Always update modified date
|
|
91
|
+
// Always update modified date (this is the only place we set it)
|
|
91
92
|
merged.modified = new Date().toISOString();
|
|
92
93
|
return merged;
|
|
93
94
|
}
|
package/build/propertyTools.js
CHANGED
|
@@ -60,7 +60,7 @@ export class UpdatePropertiesToolHandler extends BaseToolHandler {
|
|
|
60
60
|
getToolDescription() {
|
|
61
61
|
return {
|
|
62
62
|
name: this.name,
|
|
63
|
-
description: "Update properties in an Obsidian note's YAML frontmatter. Intelligently merges arrays (tags, type, status), handles custom fields, and automatically
|
|
63
|
+
description: "Update properties in an Obsidian note's YAML frontmatter. Intelligently merges arrays (tags, type, status), handles custom fields, and automatically manages timestamps (created by Obsidian, modified by MCP server). Existing properties not included in the update are preserved.",
|
|
64
64
|
examples: [
|
|
65
65
|
{
|
|
66
66
|
description: "Update basic metadata",
|
|
@@ -111,9 +111,8 @@ export class UpdatePropertiesToolHandler extends BaseToolHandler {
|
|
|
111
111
|
description: "Properties to update",
|
|
112
112
|
properties: {
|
|
113
113
|
title: { type: "string" },
|
|
114
|
-
created: { type: "string", format: "date-time" },
|
|
115
|
-
modified: { type: "string", format: "date-time" },
|
|
116
114
|
author: { type: "string" },
|
|
115
|
+
// Note: created and modified timestamps are managed automatically
|
|
117
116
|
type: {
|
|
118
117
|
type: "array",
|
|
119
118
|
items: {
|
package/build/propertyTypes.js
CHANGED
|
@@ -17,11 +17,34 @@ export const StatusEnum = z.enum([
|
|
|
17
17
|
"review",
|
|
18
18
|
"complete"
|
|
19
19
|
]);
|
|
20
|
+
// Schema for reading properties (includes timestamps)
|
|
20
21
|
export const ObsidianPropertiesSchema = z.object({
|
|
22
|
+
// Basic Metadata
|
|
23
|
+
// Note: Timestamps are managed automatically
|
|
24
|
+
title: z.string().optional(),
|
|
25
|
+
modified: z.string().datetime().optional(), // Read-only, managed by MCP server
|
|
26
|
+
author: z.string().optional(),
|
|
27
|
+
// Classification
|
|
28
|
+
type: z.array(PropertyTypeEnum).optional(),
|
|
29
|
+
// Organization
|
|
30
|
+
tags: z.array(z.string().startsWith("#")).optional(),
|
|
31
|
+
// Technical Metadata
|
|
32
|
+
status: z.array(StatusEnum).optional(),
|
|
33
|
+
version: z.string().optional(),
|
|
34
|
+
platform: z.string().optional(),
|
|
35
|
+
repository: z.string().url().optional(),
|
|
36
|
+
dependencies: z.array(z.string()).optional(),
|
|
37
|
+
// References
|
|
38
|
+
sources: z.array(z.string()).optional(),
|
|
39
|
+
urls: z.array(z.string().url()).optional(),
|
|
40
|
+
papers: z.array(z.string()).optional(),
|
|
41
|
+
// Custom Fields
|
|
42
|
+
custom: z.record(z.unknown()).optional()
|
|
43
|
+
});
|
|
44
|
+
// Schema for validating property updates (excludes timestamps)
|
|
45
|
+
export const PropertyUpdateSchema = z.object({
|
|
21
46
|
// Basic Metadata
|
|
22
47
|
title: z.string().optional(),
|
|
23
|
-
created: z.string().datetime().optional(),
|
|
24
|
-
modified: z.string().datetime().optional(),
|
|
25
48
|
author: z.string().optional(),
|
|
26
49
|
// Classification
|
|
27
50
|
type: z.array(PropertyTypeEnum).optional(),
|
package/package.json
CHANGED
package/src/properties.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { parse, stringify } from 'yaml';
|
|
2
2
|
import { ObsidianClient } from './obsidian.js';
|
|
3
|
-
import {
|
|
4
|
-
ObsidianProperties,
|
|
5
|
-
ObsidianPropertiesSchema,
|
|
3
|
+
import {
|
|
4
|
+
ObsidianProperties,
|
|
5
|
+
ObsidianPropertiesSchema,
|
|
6
|
+
PropertyUpdateSchema,
|
|
6
7
|
PropertyManagerResult,
|
|
7
|
-
ValidationResult
|
|
8
|
+
ValidationResult
|
|
8
9
|
} from './propertyTypes.js';
|
|
9
10
|
|
|
10
11
|
export class PropertyManager {
|
|
@@ -62,7 +63,7 @@ export class PropertyManager {
|
|
|
62
63
|
* Validate property values
|
|
63
64
|
*/
|
|
64
65
|
validateProperties(properties: Partial<ObsidianProperties>): ValidationResult {
|
|
65
|
-
const result =
|
|
66
|
+
const result = PropertyUpdateSchema.safeParse(properties);
|
|
66
67
|
|
|
67
68
|
if (result.success) {
|
|
68
69
|
return { valid: true, errors: [] };
|
|
@@ -70,7 +71,7 @@ export class PropertyManager {
|
|
|
70
71
|
|
|
71
72
|
return {
|
|
72
73
|
valid: false,
|
|
73
|
-
errors: result.error.errors.map(err =>
|
|
74
|
+
errors: result.error.errors.map(err =>
|
|
74
75
|
`${err.path.join('.')}: ${err.message}`
|
|
75
76
|
)
|
|
76
77
|
};
|
|
@@ -86,7 +87,8 @@ export class PropertyManager {
|
|
|
86
87
|
const merged = { ...existing };
|
|
87
88
|
|
|
88
89
|
for (const [key, value] of Object.entries(updates)) {
|
|
89
|
-
|
|
90
|
+
// Skip undefined values and timestamp fields
|
|
91
|
+
if (value === undefined || key === 'created' || key === 'modified') continue;
|
|
90
92
|
|
|
91
93
|
const currentValue = merged[key as keyof ObsidianProperties];
|
|
92
94
|
|
|
@@ -109,7 +111,7 @@ export class PropertyManager {
|
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
113
|
|
|
112
|
-
// Always update modified date
|
|
114
|
+
// Always update modified date (this is the only place we set it)
|
|
113
115
|
merged.modified = new Date().toISOString();
|
|
114
116
|
|
|
115
117
|
return merged;
|
package/src/propertyTools.ts
CHANGED
|
@@ -79,7 +79,7 @@ export class UpdatePropertiesToolHandler extends BaseToolHandler<UpdatePropertie
|
|
|
79
79
|
getToolDescription(): Tool {
|
|
80
80
|
return {
|
|
81
81
|
name: this.name,
|
|
82
|
-
description: "Update properties in an Obsidian note's YAML frontmatter. Intelligently merges arrays (tags, type, status), handles custom fields, and automatically
|
|
82
|
+
description: "Update properties in an Obsidian note's YAML frontmatter. Intelligently merges arrays (tags, type, status), handles custom fields, and automatically manages timestamps (created by Obsidian, modified by MCP server). Existing properties not included in the update are preserved.",
|
|
83
83
|
examples: [
|
|
84
84
|
{
|
|
85
85
|
description: "Update basic metadata",
|
|
@@ -130,9 +130,8 @@ export class UpdatePropertiesToolHandler extends BaseToolHandler<UpdatePropertie
|
|
|
130
130
|
description: "Properties to update",
|
|
131
131
|
properties: {
|
|
132
132
|
title: { type: "string" },
|
|
133
|
-
created: { type: "string", format: "date-time" },
|
|
134
|
-
modified: { type: "string", format: "date-time" },
|
|
135
133
|
author: { type: "string" },
|
|
134
|
+
// Note: created and modified timestamps are managed automatically
|
|
136
135
|
type: {
|
|
137
136
|
type: "array",
|
|
138
137
|
items: {
|
package/src/propertyTypes.ts
CHANGED
|
@@ -20,11 +20,40 @@ export const StatusEnum = z.enum([
|
|
|
20
20
|
"complete"
|
|
21
21
|
]);
|
|
22
22
|
|
|
23
|
+
// Schema for reading properties (includes timestamps)
|
|
23
24
|
export const ObsidianPropertiesSchema = z.object({
|
|
25
|
+
// Basic Metadata
|
|
26
|
+
// Note: Timestamps are managed automatically
|
|
27
|
+
title: z.string().optional(),
|
|
28
|
+
modified: z.string().datetime().optional(), // Read-only, managed by MCP server
|
|
29
|
+
author: z.string().optional(),
|
|
30
|
+
|
|
31
|
+
// Classification
|
|
32
|
+
type: z.array(PropertyTypeEnum).optional(),
|
|
33
|
+
|
|
34
|
+
// Organization
|
|
35
|
+
tags: z.array(z.string().startsWith("#")).optional(),
|
|
36
|
+
|
|
37
|
+
// Technical Metadata
|
|
38
|
+
status: z.array(StatusEnum).optional(),
|
|
39
|
+
version: z.string().optional(),
|
|
40
|
+
platform: z.string().optional(),
|
|
41
|
+
repository: z.string().url().optional(),
|
|
42
|
+
dependencies: z.array(z.string()).optional(),
|
|
43
|
+
|
|
44
|
+
// References
|
|
45
|
+
sources: z.array(z.string()).optional(),
|
|
46
|
+
urls: z.array(z.string().url()).optional(),
|
|
47
|
+
papers: z.array(z.string()).optional(),
|
|
48
|
+
|
|
49
|
+
// Custom Fields
|
|
50
|
+
custom: z.record(z.unknown()).optional()
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Schema for validating property updates (excludes timestamps)
|
|
54
|
+
export const PropertyUpdateSchema = z.object({
|
|
24
55
|
// Basic Metadata
|
|
25
56
|
title: z.string().optional(),
|
|
26
|
-
created: z.string().datetime().optional(),
|
|
27
|
-
modified: z.string().datetime().optional(),
|
|
28
57
|
author: z.string().optional(),
|
|
29
58
|
|
|
30
59
|
// Classification
|
|
@@ -50,6 +79,7 @@ export const ObsidianPropertiesSchema = z.object({
|
|
|
50
79
|
});
|
|
51
80
|
|
|
52
81
|
export type ObsidianProperties = z.infer<typeof ObsidianPropertiesSchema>;
|
|
82
|
+
export type PropertyUpdate = z.infer<typeof PropertyUpdateSchema>;
|
|
53
83
|
|
|
54
84
|
export interface PropertyOperation {
|
|
55
85
|
operation: 'get' | 'update' | 'patch';
|