@abraca/mcp 1.8.0 → 1.8.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.
package/src/tools/meta.ts CHANGED
@@ -17,17 +17,14 @@ export function registerMetaTools(mcp: McpServer, server: AbracadabraMCPServer)
17
17
  server.setActiveToolCall({ name: 'get_metadata', target: docId })
18
18
  const treeMap = server.getTreeMap()
19
19
  if (!treeMap) {
20
- server.setActiveToolCall(null)
21
20
  return { content: [{ type: 'text', text: 'Not connected' }] }
22
21
  }
23
22
 
24
23
  const entry = treeMap.get(docId)
25
24
  if (!entry) {
26
- server.setActiveToolCall(null)
27
25
  return { content: [{ type: 'text', text: `Document ${docId} not found` }] }
28
26
  }
29
27
 
30
- server.setActiveToolCall(null)
31
28
  return {
32
29
  content: [{
33
30
  type: 'text',
@@ -47,20 +44,18 @@ export function registerMetaTools(mcp: McpServer, server: AbracadabraMCPServer)
47
44
  'Update metadata fields on a document. Merges the provided fields into existing metadata.',
48
45
  {
49
46
  docId: z.string().describe('Document ID.'),
50
- meta: z.record(z.unknown()).describe('Metadata fields to update (merged with existing). Universal keys: color (hex), icon (Lucide kebab-case — NEVER emoji), dateStart/dateEnd, datetimeStart/datetimeEnd, allDay, timeStart/timeEnd, tags (string[]), checked (bool), priority (0=none,1=low,2=med,3=high,4=urgent), status, rating (0-5), url, email, phone, number, unit, subtitle, note, taskProgress (0-100), members ({id,label}[]), coverUploadId, coverDocId, dateTaken. Geo/Map (children): geoType ("marker"|"line"|"measure"), geoLat, geoLng, geoDescription. Spatial 3D (children, plugin: spatial): spShape ("box"|"sphere"|"cylinder"|"cone"|"plane"|"torus"|"glb"), spX/spY/spZ, spRX/spRY/spRZ (deg), spSX/spSY/spSZ (scale), spOpacity (0-100), spModelUploadId, spModelDocId — spatial uses the universal `color` key, NOT spColor. Dashboard (children): deskX, deskY, deskZ, deskMode ("icon"|"widget-sm"|"widget-lg"). Mindmap-layout (children): mmX, mmY. Graph-layout (children): graphX, graphY, graphPinned. Slides (children): slidesTransition ("none"|"fade"|"slide"). Coder (children, plugin: coder): fileType ("vue"|"ts"|"js"|"css"|"json"|"folder"), entry (bool). Cell formatting (sheets cells): bold, italic, textColor, bgColor, align ("left"|"center"|"right"), formula. Renderer config (on the PAGE doc itself, not children): kanbanColumnWidth ("narrow"|"default"|"wide"), galleryColumns (1-6), galleryAspect ("square"|"4:3"|"3:2"|"16:9"|"free"), galleryCardStyle ("default"|"compact"|"detailed"), galleryShowLabels, gallerySortBy ("manual"|"date"|"name"|"rating"), calendarView ("month"|"week"|"day"), calendarWeekStart ("sun"|"mon"), calendarShowWeekNumbers, tableMode ("hierarchy"|"flat"), tableSortKey, tableSortDir ("asc"|"desc"), timelineZoom ("week"|"month"|"quarter"), timelinePixelsPerDay, timelineCenterDate (ISO date), checklistFilter ("all"|"active"|"completed"), checklistSort ("manual"|"priority"|"due"), mapShowLabels, graphSpacing ("compact"|"default"|"spacious"), graphShowLabels, graphEdgeThickness ("thin"|"normal"|"thick"), showRefEdges, mmSpacing, spatialGridVisible, slidesTheme ("dark"|"light"), chartType ("bar"|"stacked bar"|"line"|"donut"|"treemap"), chartMetric ("value"|"type"|"tag"|"status"|"priority"|"activity"|"completion"), chartColorScheme ("default"|"warm"|"cool"|"mono"), chartLimit (3-30), chartShowLegend, chartShowValues, sheetsDefaultColWidth (40-500), sheetsDefaultRowHeight (20-100), sheetsShowGridlines, sheetsFreezeRows, sheetsFreezeCols, mediaRepeat ("off"|"all"|"one"), mediaShuffle. Set a key to null to clear it.'),
47
+ meta: z.record(z.string(), z.unknown()).describe('Metadata fields to update (merged with existing). Universal keys: color (hex), icon (Lucide kebab-case — NEVER emoji), dateStart/dateEnd, datetimeStart/datetimeEnd, allDay, timeStart/timeEnd, tags (string[]), checked (bool), priority (0=none,1=low,2=med,3=high,4=urgent), status, rating (0-5), url, email, phone, number, unit, subtitle, note, taskProgress (0-100), members ({id,label}[]), coverUploadId, coverDocId, dateTaken. Geo/Map (children): geoType ("marker"|"line"|"measure"), geoLat, geoLng, geoDescription. Spatial 3D (children, plugin: spatial): spShape ("box"|"sphere"|"cylinder"|"cone"|"plane"|"torus"|"glb"), spX/spY/spZ, spRX/spRY/spRZ (deg), spSX/spSY/spSZ (scale), spOpacity (0-100), spModelUploadId, spModelDocId — spatial uses the universal `color` key, NOT spColor. Dashboard (children): deskX, deskY, deskZ, deskMode ("icon"|"widget-sm"|"widget-lg"). Mindmap-layout (children): mmX, mmY. Graph-layout (children): graphX, graphY, graphPinned. Slides (children): slidesTransition ("none"|"fade"|"slide"). Coder (children, plugin: coder): fileType ("vue"|"ts"|"js"|"css"|"json"|"folder"), entry (bool). Cell formatting (sheets cells): bold, italic, textColor, bgColor, align ("left"|"center"|"right"), formula. Renderer config (on the PAGE doc itself, not children): kanbanColumnWidth ("narrow"|"default"|"wide"), galleryColumns (1-6), galleryAspect ("square"|"4:3"|"3:2"|"16:9"|"free"), galleryCardStyle ("default"|"compact"|"detailed"), galleryShowLabels, gallerySortBy ("manual"|"date"|"name"|"rating"), calendarView ("month"|"week"|"day"), calendarWeekStart ("sun"|"mon"), calendarShowWeekNumbers, tableMode ("hierarchy"|"flat"), tableSortKey, tableSortDir ("asc"|"desc"), timelineZoom ("week"|"month"|"quarter"), timelinePixelsPerDay, timelineCenterDate (ISO date), checklistFilter ("all"|"active"|"completed"), checklistSort ("manual"|"priority"|"due"), mapShowLabels, graphSpacing ("compact"|"default"|"spacious"), graphShowLabels, graphEdgeThickness ("thin"|"normal"|"thick"), showRefEdges, mmSpacing, spatialGridVisible, slidesTheme ("dark"|"light"), chartType ("bar"|"stacked bar"|"line"|"donut"|"treemap"), chartMetric ("value"|"type"|"tag"|"status"|"priority"|"activity"|"completion"), chartColorScheme ("default"|"warm"|"cool"|"mono"), chartLimit (3-30), chartShowLegend, chartShowValues, sheetsDefaultColWidth (40-500), sheetsDefaultRowHeight (20-100), sheetsShowGridlines, sheetsFreezeRows, sheetsFreezeCols, mediaRepeat ("off"|"all"|"one"), mediaShuffle. Set a key to null to clear it.'),
51
48
  },
52
49
  async ({ docId, meta }) => {
53
50
  server.setAutoStatus('writing', docId)
54
51
  server.setActiveToolCall({ name: 'update_metadata', target: docId })
55
52
  const treeMap = server.getTreeMap()
56
53
  if (!treeMap) {
57
- server.setActiveToolCall(null)
58
54
  return { content: [{ type: 'text', text: 'Not connected' }] }
59
55
  }
60
56
 
61
57
  const entry = treeMap.get(docId)
62
58
  if (!entry) {
63
- server.setActiveToolCall(null)
64
59
  return { content: [{ type: 'text', text: `Document ${docId} not found` }] }
65
60
  }
66
61
 
@@ -70,7 +65,6 @@ export function registerMetaTools(mcp: McpServer, server: AbracadabraMCPServer)
70
65
  updatedAt: Date.now(),
71
66
  })
72
67
 
73
- server.setActiveToolCall(null)
74
68
  return { content: [{ type: 'text', text: `Metadata updated for ${docId}` }] }
75
69
  }
76
70
  )
package/src/tools/svg.ts CHANGED
@@ -43,7 +43,6 @@ export function registerSvgTools(mcp: McpServer, server: AbracadabraMCPServer) {
43
43
 
44
44
  const cleanSvg = sanitizeSvg(svg)
45
45
  if (!cleanSvg) {
46
- server.setActiveToolCall(null)
47
46
  return {
48
47
  content: [{ type: 'text', text: 'Error: SVG markup was empty or entirely stripped by sanitizer.' }],
49
48
  isError: true,
@@ -66,13 +65,11 @@ export function registerSvgTools(mcp: McpServer, server: AbracadabraMCPServer) {
66
65
  })
67
66
 
68
67
  server.setFocusedDoc(docId)
69
- server.setActiveToolCall(null)
70
68
 
71
69
  return {
72
70
  content: [{ type: 'text', text: `SVG inserted into document ${docId}${title ? ` ("${title}")` : ''}` }],
73
71
  }
74
72
  } catch (error: any) {
75
- server.setActiveToolCall(null)
76
73
  return {
77
74
  content: [{ type: 'text', text: `Error writing SVG: ${error.message}` }],
78
75
  isError: true,
package/src/tools/tree.ts CHANGED
@@ -90,7 +90,6 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
90
90
  server.setActiveToolCall({ name: 'list_documents' })
91
91
  const treeMap = server.getTreeMap()
92
92
  if (!treeMap) {
93
- server.setActiveToolCall(null)
94
93
  return { content: [{ type: 'text', text: 'Not connected' }] }
95
94
  }
96
95
 
@@ -98,7 +97,6 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
98
97
  const entries = readEntries(treeMap)
99
98
  const children = childrenOf(entries, targetId)
100
99
 
101
- server.setActiveToolCall(null)
102
100
  return {
103
101
  content: [{
104
102
  type: 'text',
@@ -120,7 +118,6 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
120
118
  server.setActiveToolCall({ name: 'get_document_tree' })
121
119
  const treeMap = server.getTreeMap()
122
120
  if (!treeMap) {
123
- server.setActiveToolCall(null)
124
121
  return { content: [{ type: 'text', text: 'Not connected' }] }
125
122
  }
126
123
 
@@ -129,7 +126,6 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
129
126
  const entries = readEntries(treeMap)
130
127
  const tree = buildTree(entries, targetId, maxDepth)
131
128
 
132
- server.setActiveToolCall(null)
133
129
  return {
134
130
  content: [{
135
131
  type: 'text',
@@ -151,7 +147,6 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
151
147
  server.setActiveToolCall({ name: 'find_document', target: query })
152
148
  const treeMap = server.getTreeMap()
153
149
  if (!treeMap) {
154
- server.setActiveToolCall(null)
155
150
  return { content: [{ type: 'text', text: 'Not connected' }] }
156
151
  }
157
152
 
@@ -189,7 +184,6 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
189
184
  }
190
185
  })
191
186
 
192
- server.setActiveToolCall(null)
193
187
  if (results.length === 0) {
194
188
  return {
195
189
  content: [{ type: 'text', text: `No documents found matching "${query}". Try get_document_tree to see the full hierarchy.` }],
@@ -209,7 +203,7 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
209
203
  parentId: z.string().optional().describe('Parent document ID. Omit for top-level pages. Use a document ID for nested/child pages.'),
210
204
  label: z.string().describe('Display name / title for the document.'),
211
205
  type: z.string().optional().describe('Page type — sets how this document renders. Core types (always available): "doc" (rich text), "kanban" (columns → cards), "table" (columns → rows, positional), "calendar" (events with datetimeStart/End), "timeline" (epics → tasks with dateStart/End + taskProgress), "checklist" (tasks with checked/priority, unlimited nesting), "outline" (nested items, unlimited depth), "gallery" (visual grid with covers/ratings), "map" (markers/lines with geoLat/geoLng), "graph" (force-directed knowledge graph), "dashboard" (positioned widgets with deskX/deskY/deskMode), "slides" (slides → sub-slides with transitions), "chart" (bar/stacked bar/line/donut/treemap from data points or aggregation), "sheets" (spreadsheet with formulas and formatting), "overview" (space home — activity and stats), "call" (video call room, no children). Plugin types (require plugin enabled on the server): "spatial" (3D scene with spShape/spX/spY/spZ + universal color, plugin: spatial), "media" (audio/video player with playlists, plugin: media), "coder" (collaborative multi-file coding env with fileType/entry, plugin: coder). Alias: "desktop" → "dashboard". Omit to inherit parent view. Only set on the parent page, NEVER on child items.'),
212
- meta: z.record(z.unknown()).optional().describe('Initial metadata (PageMeta fields: color as hex string, icon as Lucide kebab-case name like "star"/"code-2"/"users" — never emoji, dateStart, dateEnd, priority 0-4, tags array, etc). Omit icon entirely to use page type default.'),
206
+ meta: z.record(z.string(), z.unknown()).optional().describe('Initial metadata (PageMeta fields: color as hex string, icon as Lucide kebab-case name like "star"/"code-2"/"users" — never emoji, dateStart, dateEnd, priority 0-4, tags array, etc). Omit icon entirely to use page type default.'),
213
207
  },
214
208
  async ({ parentId, label, type, meta }) => {
215
209
  server.setAutoStatus('creating')
@@ -218,7 +212,6 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
218
212
  const treeMap = server.getTreeMap()
219
213
  const rootDoc = server.rootDocument
220
214
  if (!treeMap || !rootDoc) {
221
- server.setActiveToolCall(null)
222
215
  return { content: [{ type: 'text', text: 'Not connected' }] }
223
216
  }
224
217
 
@@ -238,7 +231,6 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
238
231
  })
239
232
 
240
233
  server.setFocusedDoc(id)
241
- server.setActiveToolCall(null)
242
234
 
243
235
  return {
244
236
  content: [{
@@ -261,19 +253,16 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
261
253
  server.setActiveToolCall({ name: 'rename_document', target: id })
262
254
  const treeMap = server.getTreeMap()
263
255
  if (!treeMap) {
264
- server.setActiveToolCall(null)
265
256
  return { content: [{ type: 'text', text: 'Not connected' }] }
266
257
  }
267
258
 
268
259
  const raw = treeMap.get(id)
269
260
  if (!raw) {
270
- server.setActiveToolCall(null)
271
261
  return { content: [{ type: 'text', text: `Document ${id} not found` }] }
272
262
  }
273
263
 
274
264
  const entry = toPlain(raw)
275
265
  treeMap.set(id, { ...entry, label, updatedAt: Date.now() })
276
- server.setActiveToolCall(null)
277
266
  return { content: [{ type: 'text', text: `Renamed to "${label}"` }] }
278
267
  }
279
268
  )
@@ -291,13 +280,11 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
291
280
  server.setActiveToolCall({ name: 'move_document', target: id })
292
281
  const treeMap = server.getTreeMap()
293
282
  if (!treeMap) {
294
- server.setActiveToolCall(null)
295
283
  return { content: [{ type: 'text', text: 'Not connected' }] }
296
284
  }
297
285
 
298
286
  const raw = treeMap.get(id)
299
287
  if (!raw) {
300
- server.setActiveToolCall(null)
301
288
  return { content: [{ type: 'text', text: `Document ${id} not found` }] }
302
289
  }
303
290
 
@@ -308,7 +295,6 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
308
295
  order: order ?? Date.now(),
309
296
  updatedAt: Date.now(),
310
297
  })
311
- server.setActiveToolCall(null)
312
298
  return { content: [{ type: 'text', text: `Moved ${id} to parent ${newParentId}` }] }
313
299
  }
314
300
  )
@@ -326,7 +312,6 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
326
312
  const trashMap = server.getTrashMap()
327
313
  const rootDoc = server.rootDocument
328
314
  if (!treeMap || !trashMap || !rootDoc) {
329
- server.setActiveToolCall(null)
330
315
  return { content: [{ type: 'text', text: 'Not connected' }] }
331
316
  }
332
317
 
@@ -351,7 +336,6 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
351
336
  }
352
337
  })
353
338
 
354
- server.setActiveToolCall(null)
355
339
  return { content: [{ type: 'text', text: `Deleted ${toDelete.length} document(s)` }] }
356
340
  }
357
341
  )
@@ -368,19 +352,16 @@ export function registerTreeTools(mcp: McpServer, server: AbracadabraMCPServer)
368
352
  server.setActiveToolCall({ name: 'change_document_type', target: id })
369
353
  const treeMap = server.getTreeMap()
370
354
  if (!treeMap) {
371
- server.setActiveToolCall(null)
372
355
  return { content: [{ type: 'text', text: 'Not connected' }] }
373
356
  }
374
357
 
375
358
  const raw = treeMap.get(id)
376
359
  if (!raw) {
377
- server.setActiveToolCall(null)
378
360
  return { content: [{ type: 'text', text: `Document ${id} not found` }] }
379
361
  }
380
362
 
381
363
  const entry = toPlain(raw)
382
364
  treeMap.set(id, { ...entry, type, updatedAt: Date.now() })
383
- server.setActiveToolCall(null)
384
365
  return { content: [{ type: 'text', text: `Changed type to "${type}"` }] }
385
366
  }
386
367
  )