triliumnext-mcp 0.3.8-beta.5 → 0.3.9-beta.1

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.
@@ -17,7 +17,8 @@ export async function handleCreateNoteRequest(args, axiosInstance, permissionChe
17
17
  title: args.title,
18
18
  type: args.type,
19
19
  content: args.content,
20
- mime: args.mime
20
+ mime: args.mime,
21
+ attributes: args.attributes // ✅ Add this line
21
22
  };
22
23
  const result = await handleCreateNote(noteOperation, axiosInstance);
23
24
  return {
@@ -3,6 +3,7 @@
3
3
  * Handles CRUD operations for TriliumNext notes
4
4
  */
5
5
  import { processContentArray } from '../utils/contentProcessor.js';
6
+ import { logVerbose, logVerboseError, logVerboseApi } from '../utils/verboseUtils.js';
6
7
  /**
7
8
  * Handle create note operation
8
9
  */
@@ -43,10 +44,14 @@ export async function handleCreateNote(args, axiosInstance) {
43
44
  // Handle attributes if provided
44
45
  if (attributes && attributes.length > 0) {
45
46
  try {
47
+ logVerbose("handleCreateNote", `Creating ${attributes.length} attributes for note ${noteId}`, attributes);
46
48
  await createNoteAttributes(noteId, attributes, axiosInstance);
49
+ logVerbose("handleCreateNote", `Successfully created all attributes for note ${noteId}`);
47
50
  }
48
51
  catch (attributeError) {
49
- console.warn(`Note created but attributes failed to apply: ${attributeError}`);
52
+ const errorMsg = `Note created but attributes failed to apply: ${attributeError instanceof Error ? attributeError.message : attributeError}`;
53
+ logVerboseError("handleCreateNote", attributeError);
54
+ console.warn(errorMsg);
50
55
  }
51
56
  }
52
57
  return {
@@ -60,15 +65,20 @@ export async function handleCreateNote(args, axiosInstance) {
60
65
  async function createNoteAttributes(noteId, attributes, axiosInstance) {
61
66
  const attributePromises = attributes.map(async (attr) => {
62
67
  const attributeData = {
68
+ noteId: noteId,
63
69
  type: attr.type,
64
70
  name: attr.name,
65
71
  value: attr.value || '',
66
72
  position: attr.position || 10,
67
73
  isInheritable: attr.isInheritable || false
68
74
  };
69
- return axiosInstance.post(`/notes/${noteId}/attributes`, attributeData);
75
+ logVerboseApi("POST", `/attributes`, attributeData);
76
+ const response = await axiosInstance.post(`/attributes`, attributeData);
77
+ logVerbose("createNoteAttributes", `Created ${attr.type} '${attr.name}' for note ${noteId}`, response.data);
78
+ return response;
70
79
  });
71
- await Promise.all(attributePromises);
80
+ const results = await Promise.all(attributePromises);
81
+ logVerbose("createNoteAttributes", `Successfully created ${results.length} attributes for note ${noteId}`);
72
82
  }
73
83
  /**
74
84
  * Handle update note operation
@@ -29,18 +29,18 @@ export function createWriteTools() {
29
29
  },
30
30
  content: {
31
31
  type: "array",
32
- description: "Content of the note as ContentItem array. Content requirements vary by note type: text/render/webView use smart format detection (HTML/Markdown/plain), code/mermaid require plain text, book/search/etc can be empty or optional.",
32
+ description: "Content of the note as ContentItem array. Content requirements by note type: TEXT NOTES - require HTML content (wrap plain text in <p> tags, e.g., '<p>hello world</p>'); CODE/MERMAID NOTES - require plain text (no HTML tags); BOOK/SEARCH NOTES - can be empty string. Use HTML formatting for text notes: <p> for paragraphs, <strong> for bold, <em> for italic, etc.",
33
33
  items: {
34
34
  type: "object",
35
35
  properties: {
36
36
  type: {
37
37
  type: "string",
38
38
  enum: ["text", "data-url"],
39
- description: "Content type: 'text' for smart format detection (HTML/Markdown/plain), 'data-url' for embedded data"
39
+ description: "Content type: 'text' for HTML content (text notes require HTML formatting), 'data-url' for embedded data"
40
40
  },
41
41
  content: {
42
42
  type: "string",
43
- description: "Content data - for text type: automatically detected as HTML/Markdown/plain; for data-url: URL string."
43
+ description: "HTML content for text notes (e.g., '<p>hello world</p>', '<strong>bold text</strong>'), plain text for code/mermaid notes"
44
44
  },
45
45
  mimeType: {
46
46
  type: "string",
@@ -43,7 +43,7 @@ export async function processContentItem(item, noteType) {
43
43
  }
44
44
  }
45
45
  /**
46
- * Process text content (Markdown conversion only for text notes)
46
+ * Process text content (HTML requirements for text notes)
47
47
  */
48
48
  async function processTextContent(item, noteType) {
49
49
  const content = item.content.trim();
@@ -52,6 +52,10 @@ async function processTextContent(item, noteType) {
52
52
  const html = await marked.parse(content);
53
53
  return { content: html };
54
54
  }
55
+ // For text notes: auto-wrap plain text in <p> tags if it's not already HTML
56
+ if (noteType === 'text' && !isLikelyHtml(content)) {
57
+ return { content: `<p>${content}</p>` };
58
+ }
55
59
  // For everything else: pass through exactly as provided
56
60
  return { content: content };
57
61
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "triliumnext-mcp",
3
- "version": "0.3.8-beta.5",
3
+ "version": "0.3.9-beta.1",
4
4
  "description": "A model context protocol server for TriliumNext Notes",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,7 +13,7 @@
13
13
  "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
14
14
  "prepare": "npm run build",
15
15
  "watch": "tsc --watch",
16
- "check": "npm run build && node --test tests/validation.test.js tests/attachment-integration.test.js",
16
+ "check": "npm run build && node --test tests/validation.test.js",
17
17
  "inspector": "npx @modelcontextprotocol/inspector build/index.js"
18
18
  },
19
19
  "dependencies": {