@abraca/mcp 1.8.0 → 1.9.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/dist/abracadabra-mcp.cjs +316 -190
- package/dist/abracadabra-mcp.cjs.map +1 -1
- package/dist/abracadabra-mcp.esm.js +316 -190
- package/dist/abracadabra-mcp.esm.js.map +1 -1
- package/dist/index.d.ts +30 -1
- package/package.json +1 -1
- package/src/converters/markdownToYjs.ts +30 -13
- package/src/converters/yjsToMarkdown.ts +10 -1
- package/src/hook-bridge.ts +18 -8
- package/src/index.ts +29 -2
- package/src/mentions.ts +42 -0
- package/src/server.ts +126 -14
- package/src/tools/awareness.ts +3 -0
- package/src/tools/channel.ts +18 -8
- package/src/tools/content.ts +0 -5
- package/src/tools/files.ts +8 -0
- package/src/tools/meta.ts +1 -7
- package/src/tools/svg.ts +0 -3
- package/src/tools/tree.ts +1 -20
package/src/tools/channel.ts
CHANGED
|
@@ -23,7 +23,6 @@ export function registerChannelTools(mcp: McpServer, server: AbracadabraMCPServe
|
|
|
23
23
|
const treeMap = server.getTreeMap()
|
|
24
24
|
const rootDoc = server.rootDocument
|
|
25
25
|
if (!treeMap || !rootDoc) {
|
|
26
|
-
server.setActiveToolCall(null)
|
|
27
26
|
return { content: [{ type: 'text' as const, text: 'Not connected' }], isError: true }
|
|
28
27
|
}
|
|
29
28
|
|
|
@@ -51,13 +50,11 @@ export function registerChannelTools(mcp: McpServer, server: AbracadabraMCPServe
|
|
|
51
50
|
server.clearAiTask(task_id)
|
|
52
51
|
}
|
|
53
52
|
|
|
54
|
-
server.setActiveToolCall(null)
|
|
55
53
|
|
|
56
54
|
return {
|
|
57
55
|
content: [{ type: 'text' as const, text: JSON.stringify({ replyDocId: replyId, parentId: doc_id }) }],
|
|
58
56
|
}
|
|
59
57
|
} catch (error: any) {
|
|
60
|
-
server.setActiveToolCall(null)
|
|
61
58
|
return {
|
|
62
59
|
content: [{ type: 'text' as const, text: `Error: ${error.message}` }],
|
|
63
60
|
isError: true,
|
|
@@ -80,17 +77,30 @@ export function registerChannelTools(mcp: McpServer, server: AbracadabraMCPServe
|
|
|
80
77
|
return { content: [{ type: 'text' as const, text: 'Not connected' }], isError: true }
|
|
81
78
|
}
|
|
82
79
|
|
|
80
|
+
// Normalize literal escape sequences. Some LLM outputs emit the
|
|
81
|
+
// 2-char `\n` / `\t` / `\r` instead of the real control chars, which
|
|
82
|
+
// then render literally in the chat (markdown renderer can't see a
|
|
83
|
+
// newline where there is just "\n"). Convert them back to real chars.
|
|
84
|
+
const normalized = text
|
|
85
|
+
.replace(/\\r\\n/g, '\n')
|
|
86
|
+
.replace(/\\n/g, '\n')
|
|
87
|
+
.replace(/\\t/g, '\t')
|
|
88
|
+
.replace(/\\r/g, '\n')
|
|
89
|
+
|
|
90
|
+
// Order matters: clear status + tool pill FIRST so the dashboard's
|
|
91
|
+
// typing-indicator filter (which hides typing while an activeToolCall
|
|
92
|
+
// exists) doesn't swallow the burst. Then emit the typing frame, then
|
|
93
|
+
// the actual chat:send. The clear also flushes toolHistory + turnId.
|
|
94
|
+
server.setAutoStatus(null)
|
|
95
|
+
server.sendTypingIndicator(channel)
|
|
96
|
+
|
|
83
97
|
rootProvider.sendStateless(JSON.stringify({
|
|
84
98
|
type: 'chat:send',
|
|
85
99
|
channel,
|
|
86
|
-
content:
|
|
100
|
+
content: normalized,
|
|
87
101
|
sender_name: server.agentName,
|
|
88
102
|
}))
|
|
89
103
|
|
|
90
|
-
// Clear thinking/typing status after sending the reply
|
|
91
|
-
server.setAutoStatus(null)
|
|
92
|
-
server.setActiveToolCall(null)
|
|
93
|
-
|
|
94
104
|
return { content: [{ type: 'text' as const, text: `Sent to ${channel}` }] }
|
|
95
105
|
} catch (error: any) {
|
|
96
106
|
return {
|
package/src/tools/content.ts
CHANGED
|
@@ -51,8 +51,6 @@ export function registerContentTools(mcp: McpServer, server: AbracadabraMCPServe
|
|
|
51
51
|
children.sort((a: any, b: any) => ((treeMap.get(a.id)?.order ?? 0) - (treeMap.get(b.id)?.order ?? 0)))
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
server.setActiveToolCall(null)
|
|
55
|
-
|
|
56
54
|
const result: Record<string, unknown> = { label, type, meta, markdown, children }
|
|
57
55
|
return {
|
|
58
56
|
content: [{
|
|
@@ -61,7 +59,6 @@ export function registerContentTools(mcp: McpServer, server: AbracadabraMCPServe
|
|
|
61
59
|
}],
|
|
62
60
|
}
|
|
63
61
|
} catch (error: any) {
|
|
64
|
-
server.setActiveToolCall(null)
|
|
65
62
|
return {
|
|
66
63
|
content: [{ type: 'text', text: `Error reading document: ${error.message}` }],
|
|
67
64
|
isError: true,
|
|
@@ -128,13 +125,11 @@ export function registerContentTools(mcp: McpServer, server: AbracadabraMCPServe
|
|
|
128
125
|
server.setFocusedDoc(docId)
|
|
129
126
|
server.setDocCursor(docId, fragment.length)
|
|
130
127
|
|
|
131
|
-
server.setActiveToolCall(null)
|
|
132
128
|
|
|
133
129
|
return {
|
|
134
130
|
content: [{ type: 'text', text: `Document ${docId} updated (${writeMode} mode)` }],
|
|
135
131
|
}
|
|
136
132
|
} catch (error: any) {
|
|
137
|
-
server.setActiveToolCall(null)
|
|
138
133
|
return {
|
|
139
134
|
content: [{ type: 'text', text: `Error writing document: ${error.message}` }],
|
|
140
135
|
isError: true,
|
package/src/tools/files.ts
CHANGED
|
@@ -15,6 +15,8 @@ export function registerFileTools(mcp: McpServer, server: AbracadabraMCPServer)
|
|
|
15
15
|
docId: z.string().describe('Document ID.'),
|
|
16
16
|
},
|
|
17
17
|
async ({ docId }) => {
|
|
18
|
+
server.setAutoStatus('reading', docId)
|
|
19
|
+
server.setActiveToolCall({ name: 'list_uploads', target: docId })
|
|
18
20
|
try {
|
|
19
21
|
const uploads = await server.client.listUploads(docId)
|
|
20
22
|
return {
|
|
@@ -41,6 +43,8 @@ export function registerFileTools(mcp: McpServer, server: AbracadabraMCPServer)
|
|
|
41
43
|
filename: z.string().optional().describe('Override filename (defaults to basename of filePath).'),
|
|
42
44
|
},
|
|
43
45
|
async ({ docId, filePath, filename }) => {
|
|
46
|
+
server.setAutoStatus('uploading', docId)
|
|
47
|
+
server.setActiveToolCall({ name: 'upload_file', target: path.basename(filePath) })
|
|
44
48
|
try {
|
|
45
49
|
const resolvedPath = path.resolve(filePath)
|
|
46
50
|
const data = fs.readFileSync(resolvedPath)
|
|
@@ -71,6 +75,8 @@ export function registerFileTools(mcp: McpServer, server: AbracadabraMCPServer)
|
|
|
71
75
|
saveTo: z.string().describe('Absolute local file path to save the download.'),
|
|
72
76
|
},
|
|
73
77
|
async ({ docId, uploadId, saveTo }) => {
|
|
78
|
+
server.setAutoStatus('reading', docId)
|
|
79
|
+
server.setActiveToolCall({ name: 'download_file', target: path.basename(saveTo) })
|
|
74
80
|
try {
|
|
75
81
|
const blob = await server.client.getUpload(docId, uploadId)
|
|
76
82
|
const buffer = Buffer.from(await blob.arrayBuffer())
|
|
@@ -96,6 +102,8 @@ export function registerFileTools(mcp: McpServer, server: AbracadabraMCPServer)
|
|
|
96
102
|
uploadId: z.string().describe('Upload ID to delete.'),
|
|
97
103
|
},
|
|
98
104
|
async ({ docId, uploadId }) => {
|
|
105
|
+
server.setAutoStatus('writing', docId)
|
|
106
|
+
server.setActiveToolCall({ name: 'delete_file', target: uploadId })
|
|
99
107
|
try {
|
|
100
108
|
await server.client.deleteUpload(docId, uploadId)
|
|
101
109
|
return { content: [{ type: 'text', text: `Deleted upload ${uploadId}` }] }
|
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
|
)
|