diff --git a/apps/server/src/core/ai-chat/tools/ai-chat-tools.service.ts b/apps/server/src/core/ai-chat/tools/ai-chat-tools.service.ts index 40a079c9..f4f8c926 100644 --- a/apps/server/src/core/ai-chat/tools/ai-chat-tools.service.ts +++ b/apps/server/src/core/ai-chat/tools/ai-chat-tools.service.ts @@ -729,6 +729,35 @@ export class AiChatToolsService { }), ), + // Schema + description live in @docmost/mcp's SHARED_TOOL_SPECS (#423). + // meta.hash in the result is the baseHash drawioUpdate requires. + drawioGet: sharedTool( + sharedToolSpecs.drawioGet, + async ({ pageId, node, format }) => + await client.drawioGet(pageId, node, format ?? 'xml'), + ), + + // Schema + description live in @docmost/mcp's SHARED_TOOL_SPECS (#423). + // The flat schema fields are regrouped into the client's `where` object. + drawioCreate: sharedTool( + sharedToolSpecs.drawioCreate, + async ({ pageId, xml, position, anchorNodeId, anchorText, title }) => + await client.drawioCreate( + pageId, + { position, anchorNodeId, anchorText }, + xml, + title, + ), + ), + + // Schema + description live in @docmost/mcp's SHARED_TOOL_SPECS (#423). + // baseHash is the optimistic lock: mismatch => structured conflict error. + drawioUpdate: sharedTool( + sharedToolSpecs.drawioUpdate, + async ({ pageId, node, xml, baseHash }) => + await client.drawioUpdate(pageId, node, xml, baseHash), + ), + // Schema + description now live in @docmost/mcp's SHARED_TOOL_SPECS (#294). // The table reference parameter was unified to `table` (was `tableRef`). tableInsertRow: sharedTool( diff --git a/apps/server/src/core/ai-chat/tools/docmost-client.loader.ts b/apps/server/src/core/ai-chat/tools/docmost-client.loader.ts index 8c8761fa..541abca3 100644 --- a/apps/server/src/core/ai-chat/tools/docmost-client.loader.ts +++ b/apps/server/src/core/ai-chat/tools/docmost-client.loader.ts @@ -168,6 +168,32 @@ export interface DocmostClientLike { url: string, opts?: { align?: 'left' | 'center' | 'right'; alt?: string }, ): Promise>; + // --- draw.io diagrams (#423, stage 1) --- + // Read a diagram as decoded mxGraph XML (default) or the raw .drawio.svg. + // meta.hash is the optimistic-lock key drawioUpdate expects as baseHash. + drawioGet( + pageId: string, + node: string, + format?: 'xml' | 'svg', + ): Promise>; + // Lint mxGraph XML, build the .drawio.svg attachment and insert a drawio node. + drawioCreate( + pageId: string, + where: { + position: 'before' | 'after' | 'append'; + anchorNodeId?: string; + anchorText?: string; + }, + xml: string, + title?: string, + ): Promise>; + // Optimistic-locked full replacement of a diagram (baseHash from drawioGet). + drawioUpdate( + pageId: string, + node: string, + xml: string, + baseHash: string, + ): Promise>; tableInsertRow( pageId: string, tableRef: string, diff --git a/packages/mcp/test/unit/client-host-contract.test.mjs b/packages/mcp/test/unit/client-host-contract.test.mjs index edbb2f74..8d7f17d5 100644 --- a/packages/mcp/test/unit/client-host-contract.test.mjs +++ b/packages/mcp/test/unit/client-host-contract.test.mjs @@ -81,6 +81,10 @@ const HOST_CONTRACT_METHODS = [ "insertImage", "replaceImage", "insertFootnote", + // draw.io diagrams (#423, stage 1) — read + create + optimistic-locked update + "drawioGet", + "drawioCreate", + "drawioUpdate", // write (comment) "createComment", "resolveComment",