@naumu/mcp 0.6.0 → 0.6.2
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/index.js +2314 -49
- package/package.json +6 -4
- package/dist/client.d.ts +0 -15
- package/dist/client.js +0 -82
- package/dist/client.js.map +0 -1
- package/dist/errors.d.ts +0 -35
- package/dist/errors.js +0 -52
- package/dist/errors.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js.map +0 -1
- package/dist/tools/add-attribute.d.ts +0 -3
- package/dist/tools/add-attribute.js +0 -58
- package/dist/tools/add-attribute.js.map +0 -1
- package/dist/tools/add-connection.d.ts +0 -3
- package/dist/tools/add-connection.js +0 -46
- package/dist/tools/add-connection.js.map +0 -1
- package/dist/tools/add-edge.d.ts +0 -3
- package/dist/tools/add-edge.js +0 -33
- package/dist/tools/add-edge.js.map +0 -1
- package/dist/tools/add-node-type.d.ts +0 -3
- package/dist/tools/add-node-type.js +0 -67
- package/dist/tools/add-node-type.js.map +0 -1
- package/dist/tools/add-node.d.ts +0 -3
- package/dist/tools/add-node.js +0 -36
- package/dist/tools/add-node.js.map +0 -1
- package/dist/tools/add-reaction.d.ts +0 -3
- package/dist/tools/add-reaction.js +0 -34
- package/dist/tools/add-reaction.js.map +0 -1
- package/dist/tools/ask-naumu.d.ts +0 -3
- package/dist/tools/ask-naumu.js +0 -44
- package/dist/tools/ask-naumu.js.map +0 -1
- package/dist/tools/ask.d.ts +0 -3
- package/dist/tools/ask.js +0 -37
- package/dist/tools/ask.js.map +0 -1
- package/dist/tools/batch-reparent.d.ts +0 -3
- package/dist/tools/batch-reparent.js +0 -31
- package/dist/tools/batch-reparent.js.map +0 -1
- package/dist/tools/canvas-add-element.d.ts +0 -3
- package/dist/tools/canvas-add-element.js +0 -46
- package/dist/tools/canvas-add-element.js.map +0 -1
- package/dist/tools/canvas-remove-element.d.ts +0 -3
- package/dist/tools/canvas-remove-element.js +0 -17
- package/dist/tools/canvas-remove-element.js.map +0 -1
- package/dist/tools/canvas-update-element.d.ts +0 -3
- package/dist/tools/canvas-update-element.js +0 -20
- package/dist/tools/canvas-update-element.js.map +0 -1
- package/dist/tools/create-canvas.d.ts +0 -3
- package/dist/tools/create-canvas.js +0 -17
- package/dist/tools/create-canvas.js.map +0 -1
- package/dist/tools/create-graph.d.ts +0 -3
- package/dist/tools/create-graph.js +0 -19
- package/dist/tools/create-graph.js.map +0 -1
- package/dist/tools/create-note.d.ts +0 -3
- package/dist/tools/create-note.js +0 -17
- package/dist/tools/create-note.js.map +0 -1
- package/dist/tools/create-thread.d.ts +0 -3
- package/dist/tools/create-thread.js +0 -63
- package/dist/tools/create-thread.js.map +0 -1
- package/dist/tools/filter.d.ts +0 -3
- package/dist/tools/filter.js +0 -54
- package/dist/tools/filter.js.map +0 -1
- package/dist/tools/get-ai-thread.d.ts +0 -3
- package/dist/tools/get-ai-thread.js +0 -18
- package/dist/tools/get-ai-thread.js.map +0 -1
- package/dist/tools/get-canvas-elements.d.ts +0 -3
- package/dist/tools/get-canvas-elements.js +0 -16
- package/dist/tools/get-canvas-elements.js.map +0 -1
- package/dist/tools/get-canvas-image.d.ts +0 -3
- package/dist/tools/get-canvas-image.js +0 -77
- package/dist/tools/get-canvas-image.js.map +0 -1
- package/dist/tools/get-node.d.ts +0 -3
- package/dist/tools/get-node.js +0 -17
- package/dist/tools/get-node.js.map +0 -1
- package/dist/tools/get-schema.d.ts +0 -3
- package/dist/tools/get-schema.js +0 -55
- package/dist/tools/get-schema.js.map +0 -1
- package/dist/tools/get-thread.d.ts +0 -3
- package/dist/tools/get-thread.js +0 -25
- package/dist/tools/get-thread.js.map +0 -1
- package/dist/tools/get-view.d.ts +0 -3
- package/dist/tools/get-view.js +0 -17
- package/dist/tools/get-view.js.map +0 -1
- package/dist/tools/index.d.ts +0 -13
- package/dist/tools/index.js +0 -147
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/list-canvases.d.ts +0 -3
- package/dist/tools/list-canvases.js +0 -16
- package/dist/tools/list-canvases.js.map +0 -1
- package/dist/tools/list-dense-nodes.d.ts +0 -3
- package/dist/tools/list-dense-nodes.js +0 -29
- package/dist/tools/list-dense-nodes.js.map +0 -1
- package/dist/tools/list-graphs.d.ts +0 -3
- package/dist/tools/list-graphs.js +0 -14
- package/dist/tools/list-graphs.js.map +0 -1
- package/dist/tools/list-node-connections.d.ts +0 -3
- package/dist/tools/list-node-connections.js +0 -32
- package/dist/tools/list-node-connections.js.map +0 -1
- package/dist/tools/list-schema-violations.d.ts +0 -3
- package/dist/tools/list-schema-violations.js +0 -16
- package/dist/tools/list-schema-violations.js.map +0 -1
- package/dist/tools/list-threads.d.ts +0 -3
- package/dist/tools/list-threads.js +0 -43
- package/dist/tools/list-threads.js.map +0 -1
- package/dist/tools/list-view-nodes.d.ts +0 -3
- package/dist/tools/list-view-nodes.js +0 -29
- package/dist/tools/list-view-nodes.js.map +0 -1
- package/dist/tools/naumu-typing.d.ts +0 -3
- package/dist/tools/naumu-typing.js +0 -30
- package/dist/tools/naumu-typing.js.map +0 -1
- package/dist/tools/note-append.d.ts +0 -3
- package/dist/tools/note-append.js +0 -17
- package/dist/tools/note-append.js.map +0 -1
- package/dist/tools/note-delete-section.d.ts +0 -3
- package/dist/tools/note-delete-section.js +0 -22
- package/dist/tools/note-delete-section.js.map +0 -1
- package/dist/tools/note-find-replace.d.ts +0 -3
- package/dist/tools/note-find-replace.js +0 -26
- package/dist/tools/note-find-replace.js.map +0 -1
- package/dist/tools/note-insert.d.ts +0 -3
- package/dist/tools/note-insert.js +0 -24
- package/dist/tools/note-insert.js.map +0 -1
- package/dist/tools/note-read.d.ts +0 -3
- package/dist/tools/note-read.js +0 -16
- package/dist/tools/note-read.js.map +0 -1
- package/dist/tools/note-replace-section.d.ts +0 -3
- package/dist/tools/note-replace-section.js +0 -26
- package/dist/tools/note-replace-section.js.map +0 -1
- package/dist/tools/note-replace.d.ts +0 -3
- package/dist/tools/note-replace.js +0 -17
- package/dist/tools/note-replace.js.map +0 -1
- package/dist/tools/post-message.d.ts +0 -3
- package/dist/tools/post-message.js +0 -45
- package/dist/tools/post-message.js.map +0 -1
- package/dist/tools/react-to-message.d.ts +0 -3
- package/dist/tools/react-to-message.js +0 -34
- package/dist/tools/react-to-message.js.map +0 -1
- package/dist/tools/read-thread.d.ts +0 -3
- package/dist/tools/read-thread.js +0 -43
- package/dist/tools/read-thread.js.map +0 -1
- package/dist/tools/remove-edge.d.ts +0 -3
- package/dist/tools/remove-edge.js +0 -25
- package/dist/tools/remove-edge.js.map +0 -1
- package/dist/tools/remove-edges-bulk.d.ts +0 -3
- package/dist/tools/remove-edges-bulk.js +0 -26
- package/dist/tools/remove-edges-bulk.js.map +0 -1
- package/dist/tools/remove-node.d.ts +0 -3
- package/dist/tools/remove-node.js +0 -17
- package/dist/tools/remove-node.js.map +0 -1
- package/dist/tools/remove-reaction.d.ts +0 -3
- package/dist/tools/remove-reaction.js +0 -34
- package/dist/tools/remove-reaction.js.map +0 -1
- package/dist/tools/reparent.d.ts +0 -3
- package/dist/tools/reparent.js +0 -21
- package/dist/tools/reparent.js.map +0 -1
- package/dist/tools/request-attachment-upload.d.ts +0 -3
- package/dist/tools/request-attachment-upload.js +0 -59
- package/dist/tools/request-attachment-upload.js.map +0 -1
- package/dist/tools/search.d.ts +0 -3
- package/dist/tools/search.js +0 -34
- package/dist/tools/search.js.map +0 -1
- package/dist/tools/semantic-search.d.ts +0 -3
- package/dist/tools/semantic-search.js +0 -34
- package/dist/tools/semantic-search.js.map +0 -1
- package/dist/tools/text-search.d.ts +0 -3
- package/dist/tools/text-search.js +0 -18
- package/dist/tools/text-search.js.map +0 -1
- package/dist/tools/traverse.d.ts +0 -3
- package/dist/tools/traverse.js +0 -19
- package/dist/tools/traverse.js.map +0 -1
- package/dist/tools/update-node.d.ts +0 -30
- package/dist/tools/update-node.js +0 -152
- package/dist/tools/update-node.js.map +0 -1
- package/dist/tools/update-schema.d.ts +0 -3
- package/dist/tools/update-schema.js +0 -60
- package/dist/tools/update-schema.js.map +0 -1
- package/dist/tools/whoami.d.ts +0 -3
- package/dist/tools/whoami.js +0 -23
- package/dist/tools/whoami.js.map +0 -1
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export function registerRemoveNode(server, client) {
|
|
3
|
-
server.registerTool('naumu_remove_node', {
|
|
4
|
-
title: 'Remove Node',
|
|
5
|
-
description: 'Low-level tool: delete a node and all its connections from the knowledge graph. This is a destructive operation. **Prefer `naumu_ask`** for removing knowledge — it understands the impact on the broader graph and can handle cascading changes. Use this only when you need precise, surgical deletion.',
|
|
6
|
-
inputSchema: z.object({
|
|
7
|
-
graphId: z.string().describe('The graph ID'),
|
|
8
|
-
nodeId: z.string().describe('The node ID to delete'),
|
|
9
|
-
}),
|
|
10
|
-
}, async ({ graphId, nodeId }) => {
|
|
11
|
-
const data = await client.del(`/api/graphs/${graphId}/nodes/${nodeId}`);
|
|
12
|
-
return {
|
|
13
|
-
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
14
|
-
};
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=remove-node.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"remove-node.js","sourceRoot":"","sources":["../../src/tools/remove-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,MAAmB;IACxE,MAAM,CAAC,YAAY,CAClB,mBAAmB,EACnB;QACC,KAAK,EAAE,aAAa;QACpB,WAAW,EAAE,2SAA2S;QACxT,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC5C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;SACpD,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,OAAO,UAAU,MAAM,EAAE,CAAC,CAAC;QACxE,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACzE,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export function registerRemoveReaction(server, client) {
|
|
3
|
-
server.registerTool('naumu_remove_reaction', {
|
|
4
|
-
title: 'Remove Reaction',
|
|
5
|
-
description: 'Remove your own emoji reaction from a message. Idempotent — calling on a reaction you never added is a no-op. Pair with `naumu_add_reaction` when you need to walk back an acknowledgement (e.g. you reacted 👀 to start a task and want to clear it after a final result message lands). Returns `{ ok, messageId, emoji, alreadyExisted, reactionCount, reactions }` — `alreadyExisted: false` means there was nothing to remove and the call was a no-op.',
|
|
6
|
-
inputSchema: z.object({
|
|
7
|
-
threadId: z
|
|
8
|
-
.string()
|
|
9
|
-
.describe('Thread containing the message. You must be a participant.'),
|
|
10
|
-
messageId: z
|
|
11
|
-
.string()
|
|
12
|
-
.describe('The message to remove your reaction from.'),
|
|
13
|
-
emoji: z
|
|
14
|
-
.string()
|
|
15
|
-
.min(1)
|
|
16
|
-
.describe('Emoji character to remove (must match what you originally reacted with).'),
|
|
17
|
-
}),
|
|
18
|
-
}, async ({ threadId, messageId, emoji }) => {
|
|
19
|
-
try {
|
|
20
|
-
const data = await client.post(`/api/threads/${threadId}/messages/${messageId}/reactions`, { emoji, action: 'remove' });
|
|
21
|
-
return {
|
|
22
|
-
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
catch (err) {
|
|
26
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
27
|
-
return {
|
|
28
|
-
content: [{ type: 'text', text: `Error: ${message}` }],
|
|
29
|
-
isError: true,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=remove-reaction.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"remove-reaction.js","sourceRoot":"","sources":["../../src/tools/remove-reaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,sBAAsB,CAAC,MAAiB,EAAE,MAAmB;IAC5E,MAAM,CAAC,YAAY,CAClB,uBAAuB,EACvB;QACC,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACV,8bAA8b;QAC/b,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,QAAQ,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,CAAC,2DAA2D,CAAC;YACvE,SAAS,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,CAAC,2CAA2C,CAAC;YACvD,KAAK,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,0EAA0E,CAAC;SACtF,CAAC;KACF,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE;QACxC,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAC7B,gBAAgB,QAAQ,aAAa,SAAS,YAAY,EAC1D,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAC3B,CAAC;YACF,OAAO;gBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aACzE,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO;gBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;gBAC/D,OAAO,EAAE,IAAI;aACb,CAAC;QACH,CAAC;IACF,CAAC,CACD,CAAC;AACH,CAAC"}
|
package/dist/tools/reparent.d.ts
DELETED
package/dist/tools/reparent.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export function registerReparent(server, client) {
|
|
3
|
-
server.registerTool('naumu_reparent', {
|
|
4
|
-
title: 'Reparent Node',
|
|
5
|
-
description: 'Atomically swap a node\'s parent edge. Deletes any existing `isParent: true` edges on the node and creates a new one to `newParentId` with relation `newRelation`. **Preserves the node\'s id, content, attributes, and embedding** — does NOT trigger embedding regeneration because only the parent edge changes. Idempotent: if the node already has the requested parent edge, response is `status: "skipped"`. Response shape: `{nodeId, oldParentId, newParentId, newRelation, status: "moved" | "skipped"}`. Use during /restructure to reparent children under newly-created mini-hubs.',
|
|
6
|
-
inputSchema: z.object({
|
|
7
|
-
graphId: z.string().describe('The graph ID'),
|
|
8
|
-
nodeId: z.string().describe('The child node to reparent'),
|
|
9
|
-
newParentId: z.string().describe('The new parent node id'),
|
|
10
|
-
newRelation: z
|
|
11
|
-
.string()
|
|
12
|
-
.describe('The new parent edge relation label (e.g. "PART_OF"). Must be valid per the schema for (child.type, relation, parent.type).'),
|
|
13
|
-
}),
|
|
14
|
-
}, async ({ graphId, nodeId, newParentId, newRelation }) => {
|
|
15
|
-
const data = await client.post(`/api/graphs/${graphId}/nodes/${nodeId}/reparent`, { newParentId, newRelation });
|
|
16
|
-
return {
|
|
17
|
-
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
18
|
-
};
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
//# sourceMappingURL=reparent.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"reparent.js","sourceRoot":"","sources":["../../src/tools/reparent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAmB;IACtE,MAAM,CAAC,YAAY,CAClB,gBAAgB,EAChB;QACC,KAAK,EAAE,eAAe;QACtB,WAAW,EACV,ikBAAikB;QAClkB,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC5C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YACzD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YAC1D,WAAW,EAAE,CAAC;iBACZ,MAAM,EAAE;iBACR,QAAQ,CAAC,4HAA4H,CAAC;SACxI,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,EAAE;QACvD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAC7B,eAAe,OAAO,UAAU,MAAM,WAAW,EACjD,EAAE,WAAW,EAAE,WAAW,EAAE,CAC5B,CAAC;QACF,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACzE,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export function registerRequestAttachmentUpload(server, client) {
|
|
3
|
-
server.registerTool('naumu_request_attachment_upload', {
|
|
4
|
-
title: 'Request Attachment Upload',
|
|
5
|
-
description: 'Request a presigned S3 upload URL to attach a file to a message. Same flow Naumu users use for file uploads: get a signed URL, PUT the bytes to it directly, then call `naumu_post_message` with the returned `attachmentId` in `attachmentIds`. Use this when you want to deliver generated content as a file (a markdown report, a PDF, an image, an audio recording, a video). Per-MIME size caps apply (typically 50MB umbrella, 10MB for agent-readable types).\n\nReturns `{ attachmentId, uploadUrl, method, requiredHeaders, expiresAt }`. Use these EXACTLY:\n• `method` is "PUT".\n• Send every header in `requiredHeaders` (Content-Type matters for S3 signature validation).\n• Do NOT add an Authorization header — the URL itself is the auth.\n• Do NOT log `uploadUrl` — it is a bearer capability for the duration of the TTL.\n• `expiresAt` is a Unix-ms timestamp; the pending attachment vanishes at that moment whether or not you uploaded. Call `naumu_post_message` with the attachmentId before then or the upload orphans.\n\nServer-side checks at post time enforce that the attachment was uploaded by you, in this graph, for this thread — you cannot reuse an upload across threads.',
|
|
6
|
-
inputSchema: z.object({
|
|
7
|
-
threadId: z
|
|
8
|
-
.string()
|
|
9
|
-
.describe('Thread the attachment will land in. You must be a participant. The pending attachment is keyed to this thread — you cannot reuse it for a different one.'),
|
|
10
|
-
fileName: z
|
|
11
|
-
.string()
|
|
12
|
-
.min(1)
|
|
13
|
-
.describe('Original filename (with extension). Used as the display name in the message and for the S3 object suffix. Special characters are sanitized server-side.'),
|
|
14
|
-
fileType: z
|
|
15
|
-
.string()
|
|
16
|
-
.min(1)
|
|
17
|
-
.describe('MIME type, e.g. `application/pdf`, `image/png`, `text/markdown`, `audio/mpeg`, `video/mp4`. The S3 PUT will enforce this Content-Type.'),
|
|
18
|
-
fileSize: z
|
|
19
|
-
.number()
|
|
20
|
-
.int()
|
|
21
|
-
.positive()
|
|
22
|
-
.describe('File size in bytes. Validated against per-MIME caps before the URL is issued — exceeding the cap returns a 400.'),
|
|
23
|
-
audioDurationSec: z
|
|
24
|
-
.number()
|
|
25
|
-
.positive()
|
|
26
|
-
.optional()
|
|
27
|
-
.describe('For audio attachments, duration in seconds. Validated against the audio recording cap (currently 8 hours).'),
|
|
28
|
-
}),
|
|
29
|
-
}, async ({ threadId, fileName, fileType, fileSize, audioDurationSec }) => {
|
|
30
|
-
try {
|
|
31
|
-
// graphId is required by the presign endpoint, but a bot is
|
|
32
|
-
// pinned to one graph — fetch it via whoami to keep the bot
|
|
33
|
-
// from having to thread it through manually. (One-time per
|
|
34
|
-
// session if the caller caches; cheap regardless.)
|
|
35
|
-
const me = (await client.get('/api/identities/me/whoami'));
|
|
36
|
-
const body = {
|
|
37
|
-
graphId: me.graphId,
|
|
38
|
-
threadId,
|
|
39
|
-
fileName,
|
|
40
|
-
fileType,
|
|
41
|
-
fileSize,
|
|
42
|
-
};
|
|
43
|
-
if (audioDurationSec !== undefined)
|
|
44
|
-
body.audioDurationSec = audioDurationSec;
|
|
45
|
-
const data = await client.post('/api/attachments/presign', body);
|
|
46
|
-
return {
|
|
47
|
-
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
catch (err) {
|
|
51
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
52
|
-
return {
|
|
53
|
-
content: [{ type: 'text', text: `Error: ${message}` }],
|
|
54
|
-
isError: true,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
//# sourceMappingURL=request-attachment-upload.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"request-attachment-upload.js","sourceRoot":"","sources":["../../src/tools/request-attachment-upload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,+BAA+B,CAC9C,MAAiB,EACjB,MAAmB;IAEnB,MAAM,CAAC,YAAY,CAClB,iCAAiC,EACjC;QACC,KAAK,EAAE,2BAA2B;QAClC,WAAW,EACV,wpCAAwpC;QACzpC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,QAAQ,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,CAAC,0JAA0J,CAAC;YACtK,QAAQ,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,yJAAyJ,CAAC;YACrK,QAAQ,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,wIAAwI,CAAC;YACpJ,QAAQ,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,QAAQ,EAAE;iBACV,QAAQ,CAAC,iHAAiH,CAAC;YAC7H,gBAAgB,EAAE,CAAC;iBACjB,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,EAAE;iBACV,QAAQ,CAAC,4GAA4G,CAAC;SACxH,CAAC;KACF,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,EAAE,EAAE;QACtE,IAAI,CAAC;YACJ,4DAA4D;YAC5D,4DAA4D;YAC5D,2DAA2D;YAC3D,mDAAmD;YACnD,MAAM,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAwB,CAAC;YAClF,MAAM,IAAI,GAA4B;gBACrC,OAAO,EAAE,EAAE,CAAC,OAAO;gBACnB,QAAQ;gBACR,QAAQ;gBACR,QAAQ;gBACR,QAAQ;aACR,CAAC;YACF,IAAI,gBAAgB,KAAK,SAAS;gBAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;YAE7E,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,IAAI,CAAC,CAAC;YACjE,OAAO;gBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aACzE,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO;gBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;gBAC/D,OAAO,EAAE,IAAI;aACb,CAAC;QACH,CAAC;IACF,CAAC,CACD,CAAC;AACH,CAAC"}
|
package/dist/tools/search.d.ts
DELETED
package/dist/tools/search.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export function registerSearch(server, client) {
|
|
3
|
-
server.registerTool('naumu_search', {
|
|
4
|
-
title: 'Search Graph',
|
|
5
|
-
description: 'Hybrid search over graph nodes. Combines exact-token text matching (good for UUIDs, proper nouns, specific labels) with semantic similarity (good for paraphrase and meaning), then fuses both rankings with Reciprocal Rank Fusion. Returns the top matches with a `matchedVia` tag — `both` is the highest-confidence signal, then `semantic`, then `text`. Use `naumu_filter` for structured queries by type and attributes (e.g. "all in-progress Tasks"). Tip: include both synonyms ("authentication login SSO") and exact tokens you remember in the same query — the fusion handles both.',
|
|
6
|
-
inputSchema: z.object({
|
|
7
|
-
graphId: z.string().describe('The graph ID'),
|
|
8
|
-
query: z
|
|
9
|
-
.string()
|
|
10
|
-
.describe('Search query text. Mix synonyms and exact tokens freely (e.g. "auth login SSO 2fa Twitter handle").'),
|
|
11
|
-
limit: z
|
|
12
|
-
.number()
|
|
13
|
-
.optional()
|
|
14
|
-
.default(20)
|
|
15
|
-
.describe('Max results to return (default 20, max 200). Adaptive cutoff may return fewer when the top match is weak.'),
|
|
16
|
-
nodeTypes: z
|
|
17
|
-
.array(z.string())
|
|
18
|
-
.optional()
|
|
19
|
-
.describe('Filter to specific node types (e.g. ["Feature", "Pain"])'),
|
|
20
|
-
}),
|
|
21
|
-
}, async ({ graphId, query, limit, nodeTypes }) => {
|
|
22
|
-
const params = new URLSearchParams();
|
|
23
|
-
params.set('q', query);
|
|
24
|
-
if (limit)
|
|
25
|
-
params.set('limit', String(limit));
|
|
26
|
-
if (nodeTypes?.length)
|
|
27
|
-
params.set('nodeTypes', nodeTypes.join(','));
|
|
28
|
-
const data = await client.get(`/api/graphs/${graphId}/search/hybrid?${params.toString()}`);
|
|
29
|
-
return {
|
|
30
|
-
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
31
|
-
};
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=search.js.map
|
package/dist/tools/search.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,cAAc,CAAC,MAAiB,EAAE,MAAmB;IACpE,MAAM,CAAC,YAAY,CAClB,cAAc,EACd;QACC,KAAK,EAAE,cAAc;QACrB,WAAW,EACV,mkBAAmkB;QACpkB,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC5C,KAAK,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,CACR,qGAAqG,CACrG;YACF,KAAK,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,OAAO,CAAC,EAAE,CAAC;iBACX,QAAQ,CAAC,2GAA2G,CAAC;YACvH,SAAS,EAAE,CAAC;iBACV,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,QAAQ,EAAE;iBACV,QAAQ,CAAC,0DAA0D,CAAC;SACtE,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACvB,IAAI,KAAK;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9C,IAAI,SAAS,EAAE,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAEpE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,OAAO,kBAAkB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC3F,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACzE,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export function registerSemanticSearch(server, client) {
|
|
3
|
-
server.registerTool('naumu_semantic_search', {
|
|
4
|
-
title: 'Semantic Search Graph',
|
|
5
|
-
description: 'Semantic search over a knowledge graph using AI embeddings. Understands meaning and context, not just exact text matches. Use `naumu_text_search` for literal/exact string matching. Use `naumu_filter` for structured queries by type and attributes (e.g. "all in-progress Tasks"). Returns nodes ranked by semantic similarity. Tip: expand your query with synonyms and related terms for best results.',
|
|
6
|
-
inputSchema: z.object({
|
|
7
|
-
graphId: z.string().describe('The graph ID'),
|
|
8
|
-
query: z
|
|
9
|
-
.string()
|
|
10
|
-
.describe('Search query text. For best results, expand with synonyms and related terms (e.g. "authentication login sign-in auth" instead of just "auth")'),
|
|
11
|
-
limit: z
|
|
12
|
-
.number()
|
|
13
|
-
.optional()
|
|
14
|
-
.default(100)
|
|
15
|
-
.describe('Max results to return (default 100, max 200)'),
|
|
16
|
-
nodeTypes: z
|
|
17
|
-
.array(z.string())
|
|
18
|
-
.optional()
|
|
19
|
-
.describe('Filter to specific node types (e.g. ["Feature", "Pain"])'),
|
|
20
|
-
}),
|
|
21
|
-
}, async ({ graphId, query, limit, nodeTypes }) => {
|
|
22
|
-
const params = new URLSearchParams();
|
|
23
|
-
params.set('q', query);
|
|
24
|
-
if (limit)
|
|
25
|
-
params.set('limit', String(limit));
|
|
26
|
-
if (nodeTypes?.length)
|
|
27
|
-
params.set('nodeTypes', nodeTypes.join(','));
|
|
28
|
-
const data = await client.get(`/api/graphs/${graphId}/search/semantic?${params.toString()}`);
|
|
29
|
-
return {
|
|
30
|
-
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
31
|
-
};
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=semantic-search.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-search.js","sourceRoot":"","sources":["../../src/tools/semantic-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,sBAAsB,CAAC,MAAiB,EAAE,MAAmB;IAC5E,MAAM,CAAC,YAAY,CAClB,uBAAuB,EACvB;QACC,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACV,6YAA6Y;QAC9Y,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC5C,KAAK,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,CACR,+IAA+I,CAC/I;YACF,KAAK,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,OAAO,CAAC,GAAG,CAAC;iBACZ,QAAQ,CAAC,8CAA8C,CAAC;YAC1D,SAAS,EAAE,CAAC;iBACV,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,QAAQ,EAAE;iBACV,QAAQ,CAAC,0DAA0D,CAAC;SACtE,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACvB,IAAI,KAAK;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9C,IAAI,SAAS,EAAE,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAEpE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,OAAO,oBAAoB,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC7F,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACzE,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export function registerTextSearch(server, client) {
|
|
3
|
-
server.registerTool('naumu_text_search', {
|
|
4
|
-
title: 'Text Search Graph',
|
|
5
|
-
description: "Case-insensitive substring search over node labels, content, and types. Use this when you know a keyword or phrase to find. For meaning-based discovery, use `naumu_semantic_search`. For structured filtering by type/attributes, use `naumu_filter`.",
|
|
6
|
-
inputSchema: z.object({
|
|
7
|
-
graphId: z.string().describe('The graph ID'),
|
|
8
|
-
query: z.string().describe('Search query text'),
|
|
9
|
-
limit: z.number().optional().default(20).describe('Max results to return (default 20, max 200)'),
|
|
10
|
-
}),
|
|
11
|
-
}, async ({ graphId, query, limit }) => {
|
|
12
|
-
const data = await client.get(`/api/graphs/${graphId}/search?q=${encodeURIComponent(query)}&limit=${limit}`);
|
|
13
|
-
return {
|
|
14
|
-
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
15
|
-
};
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=text-search.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"text-search.js","sourceRoot":"","sources":["../../src/tools/text-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,MAAmB;IACxE,MAAM,CAAC,YAAY,CAClB,mBAAmB,EACnB;QACC,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACV,wPAAwP;QACzP,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC5C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YAC/C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;SAChG,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,OAAO,aAAa,kBAAkB,CAAC,KAAK,CAAC,UAAU,KAAK,EAAE,CAAC,CAAC;QAC7G,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACzE,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
package/dist/tools/traverse.d.ts
DELETED
package/dist/tools/traverse.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export function registerTraverse(server, client) {
|
|
3
|
-
server.registerTool('naumu_traverse', {
|
|
4
|
-
title: 'Traverse Knowledge Graph',
|
|
5
|
-
description: 'Query the graph structurally using natural language. A sub-LLM generates and executes Cypher queries. Use for structural questions like "tasks without a parent", "features with most tasks", "orphan nodes", "everything within 2 hops of X", or temporal filters like "nodes updated this week". For meaning-based search, use `naumu_search` instead.',
|
|
6
|
-
inputSchema: z.object({
|
|
7
|
-
graphId: z.string().describe('The graph ID'),
|
|
8
|
-
query: z
|
|
9
|
-
.string()
|
|
10
|
-
.describe('Natural language description of the structural pattern to find (e.g. "tasks without a parent", "features that don\'t resolve any pain")'),
|
|
11
|
-
}),
|
|
12
|
-
}, async ({ graphId, query }) => {
|
|
13
|
-
const data = await client.post(`/api/graphs/${graphId}/traverse`, { query });
|
|
14
|
-
return {
|
|
15
|
-
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
16
|
-
};
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=traverse.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"traverse.js","sourceRoot":"","sources":["../../src/tools/traverse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAmB;IACtE,MAAM,CAAC,YAAY,CAClB,gBAAgB,EAChB;QACC,KAAK,EAAE,0BAA0B;QACjC,WAAW,EACV,0VAA0V;QAC3V,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC5C,KAAK,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,CACR,yIAAyI,CACzI;SACF,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;QAC5B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,eAAe,OAAO,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7E,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACzE,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import type { NaumuClient } from '../client.js';
|
|
3
|
-
/**
|
|
4
|
-
* Date attribute payload. Single day = ISO string "YYYY-MM-DD" OR
|
|
5
|
-
* { start: "YYYY-MM-DD" }; range = { start, end? } where end >= start.
|
|
6
|
-
* Mirrors `DateRangeValue` in `@naumu/shared/attributes/date-value` —
|
|
7
|
-
* inlined here because @naumu/mcp ships standalone to npm and can't
|
|
8
|
-
* depend on the private workspace package.
|
|
9
|
-
*/
|
|
10
|
-
interface DateRangeValue {
|
|
11
|
-
start: string;
|
|
12
|
-
end?: string;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Validate an incoming date-attribute payload. Returns either the value to send
|
|
16
|
-
* to the backend (null, ISO string, or { start, end? } object) OR an error
|
|
17
|
-
* message string. The backend's update-node-attribute endpoint accepts these
|
|
18
|
-
* shapes and handles JSON serialization to Neo4j.
|
|
19
|
-
*
|
|
20
|
-
* Exported for testing.
|
|
21
|
-
*/
|
|
22
|
-
export declare function validateDateAttribute(name: string, val: unknown): {
|
|
23
|
-
ok: true;
|
|
24
|
-
value: null | string | DateRangeValue;
|
|
25
|
-
} | {
|
|
26
|
-
ok: false;
|
|
27
|
-
error: string;
|
|
28
|
-
};
|
|
29
|
-
export declare function registerUpdateNode(server: McpServer, client: NaumuClient): void;
|
|
30
|
-
export {};
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
3
|
-
/** True iff `s` is `YYYY-MM-DD` AND represents a real calendar day. */
|
|
4
|
-
function isValidIsoDate(s) {
|
|
5
|
-
if (typeof s !== 'string')
|
|
6
|
-
return false;
|
|
7
|
-
if (!ISO_DATE_REGEX.test(s))
|
|
8
|
-
return false;
|
|
9
|
-
const [yearStr, monthStr, dayStr] = s.split('-');
|
|
10
|
-
const year = Number(yearStr);
|
|
11
|
-
const month = Number(monthStr);
|
|
12
|
-
const day = Number(dayStr);
|
|
13
|
-
const date = new Date(Date.UTC(year, month - 1, day));
|
|
14
|
-
if (Number.isNaN(date.getTime()))
|
|
15
|
-
return false;
|
|
16
|
-
return (date.getUTCFullYear() === year &&
|
|
17
|
-
date.getUTCMonth() === month - 1 &&
|
|
18
|
-
date.getUTCDate() === day);
|
|
19
|
-
}
|
|
20
|
-
/** True iff `value` is `{ start }` with optional `end >= start`, all valid ISO dates. */
|
|
21
|
-
function isValidDateRange(value) {
|
|
22
|
-
if (value === null || typeof value !== 'object')
|
|
23
|
-
return false;
|
|
24
|
-
const candidate = value;
|
|
25
|
-
if (!isValidIsoDate(candidate.start))
|
|
26
|
-
return false;
|
|
27
|
-
if (candidate.end !== undefined) {
|
|
28
|
-
if (!isValidIsoDate(candidate.end))
|
|
29
|
-
return false;
|
|
30
|
-
// Lexicographic comparison works for YYYY-MM-DD.
|
|
31
|
-
if (candidate.end < candidate.start)
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
/** Build a map of lowercase attribute name → valid values for a given node type. */
|
|
37
|
-
function getAttributeMap(schema, nodeType) {
|
|
38
|
-
const map = new Map();
|
|
39
|
-
const nodeDef = schema.nodes.find((n) => n.type === nodeType);
|
|
40
|
-
if (nodeDef?.attributes) {
|
|
41
|
-
for (const attr of nodeDef.attributes) {
|
|
42
|
-
map.set(attr.name.toLowerCase(), attr);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return map;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Validate an incoming date-attribute payload. Returns either the value to send
|
|
49
|
-
* to the backend (null, ISO string, or { start, end? } object) OR an error
|
|
50
|
-
* message string. The backend's update-node-attribute endpoint accepts these
|
|
51
|
-
* shapes and handles JSON serialization to Neo4j.
|
|
52
|
-
*
|
|
53
|
-
* Exported for testing.
|
|
54
|
-
*/
|
|
55
|
-
export function validateDateAttribute(name, val) {
|
|
56
|
-
const rejectionMessage = `Date attribute "${name}" expects null, an ISO date string (YYYY-MM-DD), or { start, end? } with ISO dates.`;
|
|
57
|
-
if (val === null)
|
|
58
|
-
return { ok: true, value: null };
|
|
59
|
-
if (typeof val === 'string') {
|
|
60
|
-
if (isValidIsoDate(val))
|
|
61
|
-
return { ok: true, value: val };
|
|
62
|
-
return { ok: false, error: rejectionMessage };
|
|
63
|
-
}
|
|
64
|
-
if (typeof val === 'object' && val !== null) {
|
|
65
|
-
if (isValidDateRange(val)) {
|
|
66
|
-
const range = val;
|
|
67
|
-
// Normalize: drop end when it equals start (single-day).
|
|
68
|
-
const normalized = range.end === undefined || range.end === range.start
|
|
69
|
-
? { start: range.start }
|
|
70
|
-
: { start: range.start, end: range.end };
|
|
71
|
-
return { ok: true, value: normalized };
|
|
72
|
-
}
|
|
73
|
-
return { ok: false, error: rejectionMessage };
|
|
74
|
-
}
|
|
75
|
-
return { ok: false, error: rejectionMessage };
|
|
76
|
-
}
|
|
77
|
-
export function registerUpdateNode(server, client) {
|
|
78
|
-
server.registerTool('naumu_update_node', {
|
|
79
|
-
title: 'Update Node',
|
|
80
|
-
description: 'Update properties of an existing node. Only the provided fields will be changed. Good for simple attribute changes like setting a status, priority, or due date. For content or structural changes, consider `naumu_ask` instead — it understands the full graph context and can propagate updates to related nodes. Attribute keys AND values must match the schema for the node type. Use naumu_get_schema to check valid attribute names, types, and values before updating. Date attributes accept either null (to clear), an ISO date string "YYYY-MM-DD" (single day), or { start: "YYYY-MM-DD", end?: "YYYY-MM-DD" } (inclusive range). Example: { "due_date": { "start": "2026-05-21", "end": "2026-05-23" } } or { "due_date": "2026-05-21" } or { "due_date": null }. Select attributes accept the value label as a string.',
|
|
81
|
-
inputSchema: z.object({
|
|
82
|
-
graphId: z.string().describe('The graph ID'),
|
|
83
|
-
nodeId: z.string().describe('The node ID to update'),
|
|
84
|
-
label: z.string().optional().describe('New display name'),
|
|
85
|
-
type: z.string().optional().describe('New node type'),
|
|
86
|
-
content: z.string().optional().describe('New content / description'),
|
|
87
|
-
attributes: z
|
|
88
|
-
.record(z.string(), z.unknown())
|
|
89
|
-
.optional()
|
|
90
|
-
.describe('Schema-defined attributes to set. Examples: {"Status": "In Progress"}, {"due_date": {"start": "2026-05-21", "end": "2026-05-23"}}, {"due_date": "2026-05-21"}, {"due_date": null}.'),
|
|
91
|
-
}),
|
|
92
|
-
}, async ({ graphId, nodeId, label, type, content, attributes }) => {
|
|
93
|
-
const body = {};
|
|
94
|
-
if (label !== undefined)
|
|
95
|
-
body.label = label;
|
|
96
|
-
if (type !== undefined)
|
|
97
|
-
body.type = type;
|
|
98
|
-
if (content !== undefined)
|
|
99
|
-
body.content = content;
|
|
100
|
-
if (attributes && Object.keys(attributes).length > 0) {
|
|
101
|
-
// Fetch the node to get its type, then validate attributes against schema
|
|
102
|
-
const node = (await client.get(`/api/graphs/${graphId}/nodes/${nodeId}`));
|
|
103
|
-
const nodeType = (type ?? node.type);
|
|
104
|
-
const schemaRes = (await client.get(`/api/graphs/${graphId}/schema`));
|
|
105
|
-
const schema = JSON.parse(schemaRes.definition);
|
|
106
|
-
const attrMap = getAttributeMap(schema, nodeType);
|
|
107
|
-
const errors = [];
|
|
108
|
-
for (const [key, val] of Object.entries(attributes)) {
|
|
109
|
-
const normalized = key.toLowerCase();
|
|
110
|
-
const schemaDef = attrMap.get(normalized);
|
|
111
|
-
if (!schemaDef) {
|
|
112
|
-
const validNames = [...attrMap.values()].map((a) => a.name);
|
|
113
|
-
errors.push(`Unknown attribute "${key}" for type "${nodeType}". Valid attributes: ${validNames.length > 0 ? validNames.join(', ') : 'none'}.`);
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
// Date type — validate shape, pass through raw to backend (it serializes).
|
|
117
|
-
if (schemaDef.type === 'date') {
|
|
118
|
-
const result = validateDateAttribute(schemaDef.name, val);
|
|
119
|
-
if (!result.ok) {
|
|
120
|
-
errors.push(result.error);
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
body[normalized] = result.value;
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
// Enum types — validate value against allowed labels.
|
|
127
|
-
const validValues = schemaDef.values.map((v) => v.label);
|
|
128
|
-
if (typeof val === 'string' && validValues.length > 0 && !validValues.includes(val)) {
|
|
129
|
-
errors.push(`Invalid value "${val}" for attribute "${schemaDef.name}" on type "${nodeType}". Valid values: ${validValues.join(', ')}.`);
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
body[normalized] = val;
|
|
133
|
-
}
|
|
134
|
-
if (errors.length > 0) {
|
|
135
|
-
return {
|
|
136
|
-
content: [
|
|
137
|
-
{
|
|
138
|
-
type: 'text',
|
|
139
|
-
text: `Attribute validation failed:\n${errors.join('\n')}\n\nUse naumu_get_schema to check valid attributes and values for this node type.`,
|
|
140
|
-
},
|
|
141
|
-
],
|
|
142
|
-
isError: true,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
const data = await client.patch(`/api/graphs/${graphId}/nodes/${nodeId}`, body);
|
|
147
|
-
return {
|
|
148
|
-
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
149
|
-
};
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
//# sourceMappingURL=update-node.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"update-node.js","sourceRoot":"","sources":["../../src/tools/update-node.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
const ConnectionSchema = z.object({
|
|
3
|
-
relation: z.string().describe('UPPER_SNAKE_CASE relation name (e.g. WORKS_AT, BUILT_BY, BELONGS_TO)'),
|
|
4
|
-
target_node: z.string().optional().describe('Target type name. Omit when polymorphic=true.'),
|
|
5
|
-
polymorphic: z.boolean().optional().describe('Set true when this relation can target multiple types.'),
|
|
6
|
-
});
|
|
7
|
-
const AttributeValueSchema = z.object({
|
|
8
|
-
label: z.string().describe('Display label for this enum value'),
|
|
9
|
-
color: z.string().optional().describe('Optional hex color (e.g. "#ff5722")'),
|
|
10
|
-
description: z
|
|
11
|
-
.string()
|
|
12
|
-
.optional()
|
|
13
|
-
.describe('Short note distinguishing this value from sibling values (e.g. "closed-won — deal signed and revenue committed"). Encouraged when the label alone is ambiguous.'),
|
|
14
|
-
});
|
|
15
|
-
const AttributeSchema = z.object({
|
|
16
|
-
name: z.string().describe('Attribute key (e.g. "stage", "status", "category")'),
|
|
17
|
-
type: z.enum(['select', 'multiselect', 'string', 'number', 'date']).optional().describe('Attribute type. Defaults to select if omitted.'),
|
|
18
|
-
values: z.array(AttributeValueSchema).describe('Allowed enum values for select/multiselect; pass [] for string/number/date.'),
|
|
19
|
-
description: z
|
|
20
|
-
.string()
|
|
21
|
-
.optional()
|
|
22
|
-
.describe('Short note explaining what this attribute captures and how it differs from similarly-named attributes elsewhere in the schema. Strongly encouraged.'),
|
|
23
|
-
});
|
|
24
|
-
const NodeTypeSchema = z.object({
|
|
25
|
-
type: z.string().describe('Type name in PascalCase (e.g. Company, Person, Feature, Document)'),
|
|
26
|
-
connections: z.object({
|
|
27
|
-
parent: ConnectionSchema.optional().describe('Optional parent relation (this type nests under another via this connection).'),
|
|
28
|
-
required: z.array(ConnectionSchema).default([]).describe('Required outgoing connections to other types.'),
|
|
29
|
-
suggested: z.array(ConnectionSchema).default([]).describe('Suggested-but-optional outgoing connections.'),
|
|
30
|
-
}),
|
|
31
|
-
attributes: z.array(AttributeSchema).optional().describe('Type-level attributes for instances of this type.'),
|
|
32
|
-
defaultVisibility: z.enum(['restricted', 'internal', 'open']).optional(),
|
|
33
|
-
color: z.string().optional().describe('Optional hex color for instances of this type.'),
|
|
34
|
-
description: z
|
|
35
|
-
.string()
|
|
36
|
-
.optional()
|
|
37
|
-
.describe('Short one-sentence description of what this type represents AND how it differs from semantically similar types (e.g. "External entity delivering services on contract — distinct from Organization which is any legal entity"). Strongly encouraged on every type. Future agents rely on this when classifying a new node into one of several similar-sounding types.'),
|
|
38
|
-
});
|
|
39
|
-
const SchemaDefinitionSchema = z.object({
|
|
40
|
-
description: z.string().optional().describe('Schema-level description / domain summary.'),
|
|
41
|
-
nodes: z.array(NodeTypeSchema).describe('All node types in the schema.'),
|
|
42
|
-
});
|
|
43
|
-
export function registerUpdateSchema(server, client) {
|
|
44
|
-
server.registerTool('naumu_update_schema', {
|
|
45
|
-
title: 'Update Graph Schema',
|
|
46
|
-
description: 'Replace the graph schema with a new full definition. STRUCTURAL RULES (load-bearing): (1) HIERARCHICAL with a single root — exactly ONE type has no parent; every other type MUST declare a parent. (2) Each parent / required / suggested connection is XOR: ONE concrete target_node OR polymorphic=true — never both, never a list of multiple targets. (3) DEFAULT TO CONCRETE target_node. Polymorphic is the ESCAPE HATCH — reserve for genuinely cross-cutting concepts like Comment or Tag (entities that validly attach to many distinct types). If you find yourself making most parents polymorphic, you are avoiding the design work — pick concrete relationships instead. If you can\'t pick a concrete parent, you may be missing a type — add the missing type first. (4) Same-type nesting is implicit: a node can be placed under another of its same type using the existing parent relation — never add a self-relation just to enable nesting. (5) Always provide `description` on every node type, attribute, and select value — one short, contrastive sentence (what it IS and what it is NOT vs sibling types/attrs/values). This is the single strongest disambiguation signal for future agents classifying nodes. Use to bootstrap an empty graph (cold-start) or fully replace mid-build (call naumu_get_schema first, send the FULL new schema — anything you omit is removed). Conventions: type names PascalCase (Company, Person, Feature), relation names UPPER_SNAKE_CASE (WORKS_AT, BELONGS_TO). Bias toward general types — refine via attributes or nested children, not type proliferation.',
|
|
47
|
-
inputSchema: z.object({
|
|
48
|
-
graphId: z.string().describe('The graph ID'),
|
|
49
|
-
schema: SchemaDefinitionSchema,
|
|
50
|
-
}),
|
|
51
|
-
}, async ({ graphId, schema }) => {
|
|
52
|
-
const data = await client.post(`/api/graphs/${graphId}/schema`, {
|
|
53
|
-
definition: schema,
|
|
54
|
-
});
|
|
55
|
-
return {
|
|
56
|
-
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
57
|
-
};
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
//# sourceMappingURL=update-schema.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"update-schema.js","sourceRoot":"","sources":["../../src/tools/update-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sEAAsE,CAAC;IACrG,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;IAC5F,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;CACtG,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;IAC/D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;IAC5E,WAAW,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,iKAAiK,CAAC;CAC7K,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;IAC/E,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;IACzI,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,QAAQ,CAAC,6EAA6E,CAAC;IAC7H,WAAW,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,qJAAqJ,CAAC;CACjK,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mEAAmE,CAAC;IAC9F,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACrB,MAAM,EAAE,gBAAgB,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+EAA+E,CAAC;QAC7H,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,+CAA+C,CAAC;QACzG,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;KACzG,CAAC;IACF,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;IAC7G,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;IACxE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;IACvF,WAAW,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,uWAAuW,CAAC;CACnX,CAAC,CAAC;AAEH,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;IACzF,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,+BAA+B,CAAC;CACxE,CAAC,CAAC;AAEH,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,MAAmB;IAC1E,MAAM,CAAC,YAAY,CAClB,qBAAqB,EACrB;QACC,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACV,oiDAAoiD;QACriD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC5C,MAAM,EAAE,sBAAsB;SAC9B,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,eAAe,OAAO,SAAS,EAAE;YAC/D,UAAU,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACzE,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
package/dist/tools/whoami.d.ts
DELETED