@naumu/mcp 0.4.1 → 0.6.0
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 +1 -1
- package/dist/tools/add-attribute.js +19 -4
- package/dist/tools/add-attribute.js.map +1 -1
- package/dist/tools/add-edge.js +1 -1
- package/dist/tools/add-edge.js.map +1 -1
- package/dist/tools/add-node-type.js +15 -2
- package/dist/tools/add-node-type.js.map +1 -1
- package/dist/tools/batch-reparent.d.ts +3 -0
- package/dist/tools/batch-reparent.js +31 -0
- package/dist/tools/batch-reparent.js.map +1 -0
- package/dist/tools/create-graph.d.ts +3 -0
- package/dist/tools/create-graph.js +19 -0
- package/dist/tools/create-graph.js.map +1 -0
- package/dist/tools/get-schema.js +17 -2
- package/dist/tools/get-schema.js.map +1 -1
- package/dist/tools/get-view.js +1 -1
- package/dist/tools/get-view.js.map +1 -1
- package/dist/tools/index.js +14 -4
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/list-dense-nodes.d.ts +3 -0
- package/dist/tools/list-dense-nodes.js +29 -0
- package/dist/tools/list-dense-nodes.js.map +1 -0
- package/dist/tools/list-node-connections.d.ts +3 -0
- package/dist/tools/list-node-connections.js +32 -0
- package/dist/tools/list-node-connections.js.map +1 -0
- package/dist/tools/remove-edge.js +13 -14
- package/dist/tools/remove-edge.js.map +1 -1
- package/dist/tools/remove-edges-bulk.d.ts +3 -0
- package/dist/tools/remove-edges-bulk.js +26 -0
- package/dist/tools/remove-edges-bulk.js.map +1 -0
- package/dist/tools/reparent.d.ts +3 -0
- package/dist/tools/reparent.js +21 -0
- package/dist/tools/reparent.js.map +1 -0
- package/dist/tools/search.js +21 -5
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/traverse.js +1 -1
- package/dist/tools/traverse.js.map +1 -1
- package/dist/tools/update-node.d.ts +27 -0
- package/dist/tools/update-node.js +77 -3
- package/dist/tools/update-node.js.map +1 -1
- package/dist/tools/update-schema.js +13 -1
- package/dist/tools/update-schema.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ URL → tool mapping (the value after /spaces/ is the slug — resolve it first)
|
|
|
27
27
|
|
|
28
28
|
Recommended workflow when a user pastes a view URL:
|
|
29
29
|
1. naumu_list_graphs — find the graph whose slug matches the URL. Note its 'id' (the UUID) as graphId.
|
|
30
|
-
2. naumu_get_view {graphId, viewId} — read the returned 'summary' and 'filters'
|
|
30
|
+
2. naumu_get_view {graphId, viewId} — read the returned 'summary' and 'filters' to understand what the view returns. This is cheap.
|
|
31
31
|
3. naumu_list_view_nodes {graphId, viewId} — page through results.
|
|
32
32
|
- fields:"summary" (default) for {id, label, type} per node — best for browsing.
|
|
33
33
|
- fields:"id" for {id} only — best when you just need to count or iterate.
|
|
@@ -2,15 +2,28 @@ import { z } from 'zod';
|
|
|
2
2
|
export function registerAddAttribute(server, client) {
|
|
3
3
|
server.registerTool('naumu_add_attribute', {
|
|
4
4
|
title: 'Add Attribute to Node Type',
|
|
5
|
-
description: 'Add or extend an attribute on an existing node type. If the attribute name doesn\'t exist, it is created. If it exists and is a select/multiselect, new values are merged in (existing values kept). Use type "select"/"multiselect" with values; "string"/"number"/"date" for free-form fields (pass values: []).',
|
|
5
|
+
description: 'Add or extend an attribute on an existing node type. If the attribute name doesn\'t exist, it is created. If it exists and is a select/multiselect, new values are merged in (existing values kept). Use type "select"/"multiselect" with values; "string"/"number"/"date" for free-form fields (pass values: [] — string/number/date have no enum values). Example date attribute: { name: "due_date", type: "date", values: [], description: "Target completion date (single day or range)" }. Date values on nodes are written via naumu_update_node as either an ISO date string "YYYY-MM-DD" (single day) or an object { start, end? } with ISO date strings (inclusive range). Strongly encouraged to provide `description` on the attribute and on each value — short, contrastive notes (e.g. attribute "stage — sales funnel position; distinct from status which captures health/blockers", value "closed-won — deal signed and revenue committed"). Descriptions are the single strongest signal future agents use when picking which attribute/value to set.',
|
|
6
6
|
inputSchema: z.object({
|
|
7
7
|
graphId: z.string(),
|
|
8
8
|
node_type: z.string().describe('Existing node type to add the attribute to.'),
|
|
9
9
|
name: z.string().describe('Attribute key (e.g. "stage", "status").'),
|
|
10
10
|
type: z.enum(['select', 'multiselect', 'string', 'number', 'date']).default('select'),
|
|
11
|
-
values: z
|
|
11
|
+
values: z
|
|
12
|
+
.array(z.object({
|
|
13
|
+
label: z.string(),
|
|
14
|
+
color: z.string().optional(),
|
|
15
|
+
description: z
|
|
16
|
+
.string()
|
|
17
|
+
.optional()
|
|
18
|
+
.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.'),
|
|
19
|
+
}))
|
|
20
|
+
.default([]),
|
|
21
|
+
description: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe('Short note explaining what this attribute captures and how it differs from similarly-named attributes elsewhere in the schema (e.g. "Sales funnel position; differs from `status` which captures health/blockers"). Strongly encouraged.'),
|
|
12
25
|
}),
|
|
13
|
-
}, async ({ graphId, node_type, name, type, values }) => {
|
|
26
|
+
}, async ({ graphId, node_type, name, type, values, description }) => {
|
|
14
27
|
const current = (await client.get(`/api/graphs/${graphId}/schema`));
|
|
15
28
|
const schema = current.definition ? JSON.parse(current.definition) : { nodes: [] };
|
|
16
29
|
const node = schema.nodes.find((n) => n.type === node_type);
|
|
@@ -23,13 +36,15 @@ export function registerAddAttribute(server, client) {
|
|
|
23
36
|
const existing = node.attributes.find((a) => a.name === name);
|
|
24
37
|
let action;
|
|
25
38
|
if (!existing) {
|
|
26
|
-
node.attributes.push({ name, type, values });
|
|
39
|
+
node.attributes.push({ name, type, values, ...(description ? { description } : {}) });
|
|
27
40
|
action = `Created attribute "${name}" (${type}) with ${values.length} value(s).`;
|
|
28
41
|
}
|
|
29
42
|
else {
|
|
30
43
|
const existingLabels = new Set((existing.values ?? []).map((v) => v.label));
|
|
31
44
|
const added = values.filter((v) => !existingLabels.has(v.label));
|
|
32
45
|
existing.values = [...(existing.values ?? []), ...added];
|
|
46
|
+
if (description && !existing.description)
|
|
47
|
+
existing.description = description;
|
|
33
48
|
action = added.length > 0
|
|
34
49
|
? `Extended attribute "${name}" with ${added.length} new value(s); kept ${existingLabels.size} existing.`
|
|
35
50
|
: `Attribute "${name}" already had all proposed values; no change.`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-attribute.js","sourceRoot":"","sources":["../../src/tools/add-attribute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"add-attribute.js","sourceRoot":"","sources":["../../src/tools/add-attribute.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/add-edge.js
CHANGED
|
@@ -8,7 +8,7 @@ const EdgeInput = z.object({
|
|
|
8
8
|
export function registerAddEdge(server, client) {
|
|
9
9
|
server.registerTool('naumu_add_edge', {
|
|
10
10
|
title: 'Add Edges (bulk)',
|
|
11
|
-
description: 'Create 1–25 relationships (edges) between existing nodes in a single call. Keep batches small and atomic (5–25 edges) so failures stay contained. Typical workflow after a bulk import: create nodes with `naumu_add_node`, then wire them up with batched `naumu_add_edge` calls. **Direction matters and must match the schema.** Each edge\'s `(source.type, label, target.type)` tuple should appear in the schema\'s `connections` or `parent` for the source type.
|
|
11
|
+
description: 'Create 1–25 relationships (edges) between existing nodes in a single call. Keep batches small and atomic (5–25 edges) so failures stay contained. Typical workflow after a bulk import: create nodes with `naumu_add_node`, then wire them up with batched `naumu_add_edge` calls. **Direction matters and must match the schema.** Each edge\'s `(source.type, label, target.type)` tuple should appear in the schema\'s `connections` or `parent` for the source type. When the backend runs with `STRICT_EDGE_VALIDATION=true`, invalid tuples are rejected immediately with `error: invalid_edge` (the response includes `details.allowed_targets_for_relation` and a `hint` for routing the call); otherwise the edge persists and surfaces later as an `invalid_connection_target` / `parent_mismatch` violation. Either way, check `naumu_get_schema` and flip / drop offending edges before calling. **Prefer `naumu_ask`** when you want the agent to discover the right connections itself.',
|
|
12
12
|
inputSchema: z.object({
|
|
13
13
|
graphId: z.string().describe('The graph ID'),
|
|
14
14
|
edges: z
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-edge.js","sourceRoot":"","sources":["../../src/tools/add-edge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAC7C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAC7C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;IACjF,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;CAClF,CAAC,CAAC;AAEH,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,MAAmB;IACrE,MAAM,CAAC,YAAY,CAClB,gBAAgB,EAChB;QACC,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACV,
|
|
1
|
+
{"version":3,"file":"add-edge.js","sourceRoot":"","sources":["../../src/tools/add-edge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAC7C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAC7C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;IACjF,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;CAClF,CAAC,CAAC;AAEH,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,MAAmB;IACrE,MAAM,CAAC,YAAY,CAClB,gBAAgB,EAChB;QACC,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACV,u8BAAu8B;QACx8B,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC5C,KAAK,EAAE,CAAC;iBACN,KAAK,CAAC,SAAS,CAAC;iBAChB,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,EAAE,CAAC;iBACP,QAAQ,CAAC,kEAAkE,CAAC;SAC9E,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;QAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,KAAK;SAC7B,CAAC,CAAC,CAAC;QAEJ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,eAAe,OAAO,QAAQ,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QACnF,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"}
|
|
@@ -7,26 +7,38 @@ const ConnectionSchema = z.object({
|
|
|
7
7
|
const AttributeValueSchema = z.object({
|
|
8
8
|
label: z.string(),
|
|
9
9
|
color: z.string().optional(),
|
|
10
|
+
description: z
|
|
11
|
+
.string()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe('Short note distinguishing this value from sibling values (e.g. for status="closed-won", "Deal signed and revenue committed"). Encouraged when the label alone is ambiguous.'),
|
|
10
14
|
});
|
|
11
15
|
const AttributeSchema = z.object({
|
|
12
16
|
name: z.string(),
|
|
13
17
|
type: z.enum(['select', 'multiselect', 'string', 'number', 'date']).optional(),
|
|
14
18
|
values: z.array(AttributeValueSchema).default([]),
|
|
19
|
+
description: z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe('Short note explaining what this attribute captures and how it differs from similarly-named attributes on other types (e.g. "stage on Feature" vs "stage on Deal"). Strongly encouraged.'),
|
|
15
23
|
});
|
|
16
24
|
export function registerAddNodeType(server, client) {
|
|
17
25
|
server.registerTool('naumu_add_node_type', {
|
|
18
26
|
title: 'Add Node Type to Schema',
|
|
19
|
-
description: 'Add one new node type to the schema. Cheaper than naumu_update_schema. STRUCTURAL RULES: (1) Schemas are hierarchical with a single root. If schema is empty, the first type IS the root — omit `parent`. Every subsequent type MUST set `parent`. (2) DEFAULT TO CONCRETE — pass {relation, target_node: <existing type>}. Polymorphic is the ESCAPE HATCH — use {relation, polymorphic: true} ONLY for genuinely cross-cutting concepts like Comment or Tag (types that validly attach to many distinct parents). If you can\'t pick a concrete parent, you may be missing a type — add the missing type first instead of falling back to polymorphic. (3) Required/suggested connections also each take ONE concrete target_node OR polymorphic — never a list. Default concrete there too. (4) Type name PascalCase (Company, Person, Feature). Relation names UPPER_SNAKE_CASE (BELONGS_TO, WORKS_AT). Returns an error if the type already exists — use naumu_add_attribute / naumu_add_connection to extend it.',
|
|
27
|
+
description: 'Add one new node type to the schema. Cheaper than naumu_update_schema. STRUCTURAL RULES: (1) Schemas are hierarchical with a single root. If schema is empty, the first type IS the root — omit `parent`. Every subsequent type MUST set `parent`. (2) DEFAULT TO CONCRETE — pass {relation, target_node: <existing type>}. Polymorphic is the ESCAPE HATCH — use {relation, polymorphic: true} ONLY for genuinely cross-cutting concepts like Comment or Tag (types that validly attach to many distinct parents). If you can\'t pick a concrete parent, you may be missing a type — add the missing type first instead of falling back to polymorphic. (3) Required/suggested connections also each take ONE concrete target_node OR polymorphic — never a list. Default concrete there too. (4) Type name PascalCase (Company, Person, Feature). Relation names UPPER_SNAKE_CASE (BELONGS_TO, WORKS_AT). (5) ALWAYS provide `description` — one short sentence that says what this type is AND what it is NOT relative to semantically close types (e.g. "External entity that delivers services on contract; distinct from Organization which is any legal entity"). This is the single strongest signal future agents have when classifying a node into one of several similar-sounding types. Returns an error if the type already exists — use naumu_add_attribute / naumu_add_connection to extend it.',
|
|
20
28
|
inputSchema: z.object({
|
|
21
29
|
graphId: z.string(),
|
|
22
30
|
type: z.string().describe('PascalCase type name'),
|
|
31
|
+
description: z
|
|
32
|
+
.string()
|
|
33
|
+
.optional()
|
|
34
|
+
.describe('Short one-sentence description of what this type represents and how it differs from sibling types. Contrastive (say what it IS and what it is NOT) is most useful. Strongly encouraged on every new type — agents reading the schema later rely on this to classify nodes.'),
|
|
23
35
|
parent: ConnectionSchema.optional().describe('Optional parent connection — sets this type as a child of another type.'),
|
|
24
36
|
required: z.array(ConnectionSchema).optional(),
|
|
25
37
|
suggested: z.array(ConnectionSchema).optional(),
|
|
26
38
|
attributes: z.array(AttributeSchema).optional(),
|
|
27
39
|
color: z.string().optional(),
|
|
28
40
|
}),
|
|
29
|
-
}, async ({ graphId, type, parent, required, suggested, attributes, color }) => {
|
|
41
|
+
}, async ({ graphId, type, description, parent, required, suggested, attributes, color }) => {
|
|
30
42
|
const current = (await client.get(`/api/graphs/${graphId}/schema`));
|
|
31
43
|
const schema = current.definition ? JSON.parse(current.definition) : { nodes: [] };
|
|
32
44
|
if (schema.nodes.some((n) => n.type === type)) {
|
|
@@ -43,6 +55,7 @@ export function registerAddNodeType(server, client) {
|
|
|
43
55
|
},
|
|
44
56
|
...(attributes && attributes.length > 0 ? { attributes } : {}),
|
|
45
57
|
...(color ? { color } : {}),
|
|
58
|
+
...(description ? { description } : {}),
|
|
46
59
|
};
|
|
47
60
|
schema.nodes.push(newNode);
|
|
48
61
|
await client.post(`/api/graphs/${graphId}/schema`, { definition: schema });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-node-type.js","sourceRoot":"","sources":["../../src/tools/add-node-type.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,wDAAwD,CAAC;IACvF,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,gDAAgD,CAAC;CAC9F,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"add-node-type.js","sourceRoot":"","sources":["../../src/tools/add-node-type.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerBatchReparent(server, client) {
|
|
3
|
+
server.registerTool('naumu_batch_reparent', {
|
|
4
|
+
title: 'Batch Reparent Nodes',
|
|
5
|
+
description: 'Reparent 1–25 nodes onto a shared `newParentId` with the same `newRelation`. Same semantics as `naumu_reparent` per-node: atomic swap of the isParent edge, preserves id/content/attributes/embedding, no re-embedding. Idempotent per node (already-parented nodes return `status: "skipped"`). Per-node response array: `[{nodeId, oldParentId, newParentId, status: "moved" | "skipped" | "error", error?}]`. Used to move a same-typed cluster under a freshly-created mini-hub in /restructure.',
|
|
6
|
+
inputSchema: z.object({
|
|
7
|
+
graphId: z.string().describe('The graph ID'),
|
|
8
|
+
newParentId: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe('Parent node id every nodeId in the batch will be parented to'),
|
|
11
|
+
newRelation: z
|
|
12
|
+
.string()
|
|
13
|
+
.describe('Parent edge relation label (must be valid per schema for child.type → parent.type)'),
|
|
14
|
+
nodeIds: z
|
|
15
|
+
.array(z.string())
|
|
16
|
+
.min(1)
|
|
17
|
+
.max(25)
|
|
18
|
+
.describe('1–25 child node ids to reparent under `newParentId`'),
|
|
19
|
+
}),
|
|
20
|
+
}, async ({ graphId, newParentId, newRelation, nodeIds }) => {
|
|
21
|
+
const data = await client.post(`/api/graphs/${graphId}/reparent/bulk`, {
|
|
22
|
+
newParentId,
|
|
23
|
+
newRelation,
|
|
24
|
+
nodeIds,
|
|
25
|
+
});
|
|
26
|
+
return {
|
|
27
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=batch-reparent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-reparent.js","sourceRoot":"","sources":["../../src/tools/batch-reparent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,MAAmB;IAC3E,MAAM,CAAC,YAAY,CAClB,sBAAsB,EACtB;QACC,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACV,seAAse;QACve,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC5C,WAAW,EAAE,CAAC;iBACZ,MAAM,EAAE;iBACR,QAAQ,CAAC,8DAA8D,CAAC;YAC1E,WAAW,EAAE,CAAC;iBACZ,MAAM,EAAE;iBACR,QAAQ,CAAC,oFAAoF,CAAC;YAChG,OAAO,EAAE,CAAC;iBACR,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,EAAE,CAAC;iBACP,QAAQ,CAAC,qDAAqD,CAAC;SACjE,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE;QACxD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,eAAe,OAAO,gBAAgB,EAAE;YACtE,WAAW;YACX,WAAW;YACX,OAAO;SACP,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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerCreateGraph(server, client) {
|
|
3
|
+
server.registerTool('naumu_create_graph', {
|
|
4
|
+
title: 'Create Graph',
|
|
5
|
+
description: 'Create a new knowledge graph (space) owned by the authenticated user. Returns `{id, name, slug, role, memberRole, createdAt, onboardingThreadId}` — use the returned `id` as `graphId` for subsequent tool calls. The space starts empty (no schema, no nodes); follow up with `naumu_update_schema` to register types before any `naumu_add_node` calls.',
|
|
6
|
+
inputSchema: z.object({
|
|
7
|
+
name: z
|
|
8
|
+
.string()
|
|
9
|
+
.min(1)
|
|
10
|
+
.describe('Display name for the new space. A URL slug is generated from this name.'),
|
|
11
|
+
}),
|
|
12
|
+
}, async ({ name }) => {
|
|
13
|
+
const data = await client.post('/api/graphs', { name });
|
|
14
|
+
return {
|
|
15
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=create-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-graph.js","sourceRoot":"","sources":["../../src/tools/create-graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,MAAmB;IACzE,MAAM,CAAC,YAAY,CAClB,oBAAoB,EACpB;QACC,KAAK,EAAE,cAAc;QACrB,WAAW,EACV,2VAA2V;QAC5V,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,IAAI,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,yEAAyE,CAAC;SACrF,CAAC;KACF,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAClB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,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/get-schema.js
CHANGED
|
@@ -5,6 +5,8 @@ function formatSchema(schema) {
|
|
|
5
5
|
description: schema.description ?? null,
|
|
6
6
|
types: schema.nodes.map((node) => {
|
|
7
7
|
const result = { type: node.type };
|
|
8
|
+
if (node.description)
|
|
9
|
+
result.description = node.description;
|
|
8
10
|
if (node.connections.parent) {
|
|
9
11
|
result.parent = `${node.connections.parent.relation} → ${node.connections.parent.target_node}`;
|
|
10
12
|
}
|
|
@@ -15,7 +17,20 @@ function formatSchema(schema) {
|
|
|
15
17
|
if (connections.length > 0)
|
|
16
18
|
result.connections = connections;
|
|
17
19
|
if (node.attributes && node.attributes.length > 0) {
|
|
18
|
-
result.attributes = Object.fromEntries(node.attributes.map((a) =>
|
|
20
|
+
result.attributes = Object.fromEntries(node.attributes.map((a) => {
|
|
21
|
+
const values = (a.values ?? []).map((v) => v.description ? { label: v.label, description: v.description } : v.label);
|
|
22
|
+
const attrDetail = { values };
|
|
23
|
+
if (a.description)
|
|
24
|
+
attrDetail.description = a.description;
|
|
25
|
+
// If no description AND values are bare strings, keep the legacy compact shape
|
|
26
|
+
// (attribute name -> string[]) for back-compat with prompt formatters and tests.
|
|
27
|
+
const hasDesc = !!a.description;
|
|
28
|
+
const hasValueDescs = values.some((v) => typeof v !== 'string');
|
|
29
|
+
if (!hasDesc && !hasValueDescs) {
|
|
30
|
+
return [a.name, (a.values ?? []).map((v) => v.label)];
|
|
31
|
+
}
|
|
32
|
+
return [a.name, attrDetail];
|
|
33
|
+
}));
|
|
19
34
|
}
|
|
20
35
|
return result;
|
|
21
36
|
}),
|
|
@@ -24,7 +39,7 @@ function formatSchema(schema) {
|
|
|
24
39
|
export function registerGetSchema(server, client) {
|
|
25
40
|
server.registerTool('naumu_get_schema', {
|
|
26
41
|
title: 'Get Graph Schema',
|
|
27
|
-
description: 'Get the schema definition for a knowledge graph. Returns node types, their allowed attributes (with valid values), and
|
|
42
|
+
description: 'Get the schema definition for a knowledge graph. Returns node types, their allowed attributes (with valid values), allowed relationships, and any descriptions authored on types/attributes/values. Call this before classifying a new node into a type, before picking an attribute value, or before extending the schema — descriptions are short, contrastive notes from the schema author explaining what each type/attribute/value is for and how it differs from similar-sounding ones.',
|
|
28
43
|
inputSchema: z.object({
|
|
29
44
|
graphId: z.string().describe('The graph ID'),
|
|
30
45
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-schema.js","sourceRoot":"","sources":["../../src/tools/get-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"get-schema.js","sourceRoot":"","sources":["../../src/tools/get-schema.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/get-view.js
CHANGED
|
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
export function registerGetView(server, client) {
|
|
3
3
|
server.registerTool('naumu_get_view', {
|
|
4
4
|
title: 'Get View',
|
|
5
|
-
description: 'Fetch a saved Naumu view\'s configuration plus a one-line natural-language summary of its filters. Call this BEFORE naumu_list_view_nodes whenever you encounter a view URL — the summary tells you what data the view returns so you can decide whether to page through it. Returns: id, name, description, summary, filters,
|
|
5
|
+
description: 'Fetch a saved Naumu view\'s configuration plus a one-line natural-language summary of its filters. Call this BEFORE naumu_list_view_nodes whenever you encounter a view URL — the summary tells you what data the view returns so you can decide whether to page through it. Returns: id, name, description, summary, filters, and table column config.',
|
|
6
6
|
inputSchema: z.object({
|
|
7
7
|
graphId: z.string().describe('The graph (space) ID. From naumu.ai URLs this is the value after /spaces/.'),
|
|
8
8
|
viewId: z.string().describe('The view ID (typically prefixed with "view_").'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-view.js","sourceRoot":"","sources":["../../src/tools/get-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,MAAmB;IACrE,MAAM,CAAC,YAAY,CAClB,gBAAgB,EAChB;QACC,KAAK,EAAE,UAAU;QACjB,WAAW,EACV,
|
|
1
|
+
{"version":3,"file":"get-view.js","sourceRoot":"","sources":["../../src/tools/get-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,MAAmB;IACrE,MAAM,CAAC,YAAY,CAClB,gBAAgB,EAChB;QACC,KAAK,EAAE,UAAU;QACjB,WAAW,EACV,yVAAyV;QAC1V,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4EAA4E,CAAC;YAC1G,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;SAC7E,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"}
|
package/dist/tools/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { registerListGraphs } from './list-graphs.js';
|
|
2
|
+
import { registerCreateGraph } from './create-graph.js';
|
|
2
3
|
import { registerGetSchema } from './get-schema.js';
|
|
3
4
|
import { registerUpdateSchema } from './update-schema.js';
|
|
4
5
|
import { registerAddNodeType } from './add-node-type.js';
|
|
5
6
|
import { registerAddConnection } from './add-connection.js';
|
|
6
7
|
import { registerAddAttribute } from './add-attribute.js';
|
|
7
|
-
import {
|
|
8
|
-
import { registerSemanticSearch } from './semantic-search.js';
|
|
8
|
+
import { registerSearch } from './search.js';
|
|
9
9
|
import { registerFilter } from './filter.js';
|
|
10
10
|
import { registerGetNode } from './get-node.js';
|
|
11
11
|
import { registerAddNode } from './add-node.js';
|
|
@@ -13,6 +13,7 @@ import { registerUpdateNode } from './update-node.js';
|
|
|
13
13
|
import { registerAddEdge } from './add-edge.js';
|
|
14
14
|
import { registerRemoveNode } from './remove-node.js';
|
|
15
15
|
import { registerRemoveEdge } from './remove-edge.js';
|
|
16
|
+
import { registerRemoveEdgesBulk } from './remove-edges-bulk.js';
|
|
16
17
|
import { registerAsk } from './ask.js';
|
|
17
18
|
import { registerGetAiThread } from './get-ai-thread.js';
|
|
18
19
|
import { registerTraverse } from './traverse.js';
|
|
@@ -45,6 +46,10 @@ import { registerCanvasRemoveElement } from './canvas-remove-element.js';
|
|
|
45
46
|
import { registerCreateNote } from './create-note.js';
|
|
46
47
|
import { registerCreateCanvas } from './create-canvas.js';
|
|
47
48
|
import { registerListSchemaViolations } from './list-schema-violations.js';
|
|
49
|
+
import { registerListDenseNodes } from './list-dense-nodes.js';
|
|
50
|
+
import { registerListNodeConnections } from './list-node-connections.js';
|
|
51
|
+
import { registerReparent } from './reparent.js';
|
|
52
|
+
import { registerBatchReparent } from './batch-reparent.js';
|
|
48
53
|
/**
|
|
49
54
|
* MCP tool name → registrar. Source of truth for which tool name a registrar
|
|
50
55
|
* binds to (the registrars themselves don't expose the name in a typed shape,
|
|
@@ -55,13 +60,13 @@ import { registerListSchemaViolations } from './list-schema-violations.js';
|
|
|
55
60
|
*/
|
|
56
61
|
const TOOL_REGISTRARS = {
|
|
57
62
|
naumu_list_graphs: registerListGraphs,
|
|
63
|
+
naumu_create_graph: registerCreateGraph,
|
|
58
64
|
naumu_get_schema: registerGetSchema,
|
|
59
65
|
naumu_update_schema: registerUpdateSchema,
|
|
60
66
|
naumu_add_node_type: registerAddNodeType,
|
|
61
67
|
naumu_add_connection: registerAddConnection,
|
|
62
68
|
naumu_add_attribute: registerAddAttribute,
|
|
63
|
-
|
|
64
|
-
naumu_semantic_search: registerSemanticSearch,
|
|
69
|
+
naumu_search: registerSearch,
|
|
65
70
|
naumu_filter: registerFilter,
|
|
66
71
|
naumu_get_node: registerGetNode,
|
|
67
72
|
naumu_get_view: registerGetView,
|
|
@@ -71,6 +76,7 @@ const TOOL_REGISTRARS = {
|
|
|
71
76
|
naumu_add_edge: registerAddEdge,
|
|
72
77
|
naumu_remove_node: registerRemoveNode,
|
|
73
78
|
naumu_remove_edge: registerRemoveEdge,
|
|
79
|
+
naumu_remove_edges_bulk: registerRemoveEdgesBulk,
|
|
74
80
|
naumu_ask: registerAsk,
|
|
75
81
|
naumu_get_ai_thread: registerGetAiThread,
|
|
76
82
|
naumu_traverse: registerTraverse,
|
|
@@ -101,6 +107,10 @@ const TOOL_REGISTRARS = {
|
|
|
101
107
|
naumu_create_note: registerCreateNote,
|
|
102
108
|
naumu_create_canvas: registerCreateCanvas,
|
|
103
109
|
naumu_list_schema_violations: registerListSchemaViolations,
|
|
110
|
+
naumu_list_dense_nodes: registerListDenseNodes,
|
|
111
|
+
naumu_list_node_connections: registerListNodeConnections,
|
|
112
|
+
naumu_reparent: registerReparent,
|
|
113
|
+
naumu_batch_reparent: registerBatchReparent,
|
|
104
114
|
};
|
|
105
115
|
/**
|
|
106
116
|
* Register every MCP tool. Used by user-key sessions, where no per-Identity
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerListDenseNodes(server, client) {
|
|
3
|
+
server.registerTool('naumu_list_dense_nodes', {
|
|
4
|
+
title: 'List Dense Nodes',
|
|
5
|
+
description: 'Return nodes whose total edge count (in+out, non-system) is ≥ minConnections, grouped by type. Built for /restructure hub detection: each row includes `same_typed_child_count` — the number of children of the SAME type as the node (the Naumu hub-pattern signal). Sort the response by `same_typed_child_count` descending and route any node with ≥10 same-typed children through a mini-hub split. Pass `nodeTypes` (comma-separated) to restrict to a subset (e.g. ["Feature","Company"]). Cheap to call — runs a single Cypher aggregation.',
|
|
6
|
+
inputSchema: z.object({
|
|
7
|
+
graphId: z.string().describe('The graph ID'),
|
|
8
|
+
minConnections: z
|
|
9
|
+
.number()
|
|
10
|
+
.int()
|
|
11
|
+
.min(1)
|
|
12
|
+
.describe('Minimum total edge count (in + out, excluding system relations). Typical: 10 for hub detection, 11 to count only hubs that exceed the round-4 ≤10 threshold.'),
|
|
13
|
+
nodeTypes: z
|
|
14
|
+
.array(z.string())
|
|
15
|
+
.optional()
|
|
16
|
+
.describe('Optional list of node types to restrict the scan to.'),
|
|
17
|
+
}),
|
|
18
|
+
}, async ({ graphId, minConnections, nodeTypes }) => {
|
|
19
|
+
const params = new URLSearchParams();
|
|
20
|
+
params.set('minConnections', String(minConnections));
|
|
21
|
+
if (nodeTypes?.length)
|
|
22
|
+
params.set('nodeTypes', nodeTypes.join(','));
|
|
23
|
+
const data = await client.get(`/api/graphs/${graphId}/dense-nodes?${params.toString()}`);
|
|
24
|
+
return {
|
|
25
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=list-dense-nodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-dense-nodes.js","sourceRoot":"","sources":["../../src/tools/list-dense-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,sBAAsB,CAAC,MAAiB,EAAE,MAAmB;IAC5E,MAAM,CAAC,YAAY,CAClB,wBAAwB,EACxB;QACC,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACV,qhBAAqhB;QACthB,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC5C,cAAc,EAAE,CAAC;iBACf,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,8JAA8J,CAAC;YAC1K,SAAS,EAAE,CAAC;iBACV,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,QAAQ,EAAE;iBACV,QAAQ,CAAC,sDAAsD,CAAC;SAClE,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE,EAAE;QAChD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;QACrD,IAAI,SAAS,EAAE,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACpE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAC5B,eAAe,OAAO,gBAAgB,MAAM,CAAC,QAAQ,EAAE,EAAE,CACzD,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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerListNodeConnections(server, client) {
|
|
3
|
+
server.registerTool('naumu_list_node_connections', {
|
|
4
|
+
title: 'List Node Connections',
|
|
5
|
+
description: 'Return a single node\'s edges (non-system) with the connected node on the other side. Used during /restructure to confirm mini-hub candidates and verify reparenting outcomes. Filter with `edgeType` (relation label) and `direction` ("in" | "out" | "both", default both). Response: `{ node: {id,label,type}, edges: [{relation, direction, isParent, other: {id,label,type}}] }`.',
|
|
6
|
+
inputSchema: z.object({
|
|
7
|
+
graphId: z.string().describe('The graph ID'),
|
|
8
|
+
nodeId: z.string().describe('The node ID to inspect'),
|
|
9
|
+
edgeType: z
|
|
10
|
+
.string()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe('Restrict to a specific relation label (e.g. "ASSOCIATED_WITH"). Case-insensitive; non-alphanum chars are normalized.'),
|
|
13
|
+
direction: z
|
|
14
|
+
.enum(['in', 'out', 'both'])
|
|
15
|
+
.optional()
|
|
16
|
+
.describe('Edge direction filter — "in" (incoming), "out" (outgoing), "both" (default).'),
|
|
17
|
+
}),
|
|
18
|
+
}, async ({ graphId, nodeId, edgeType, direction }) => {
|
|
19
|
+
const params = new URLSearchParams();
|
|
20
|
+
if (edgeType)
|
|
21
|
+
params.set('edgeType', edgeType);
|
|
22
|
+
if (direction)
|
|
23
|
+
params.set('direction', direction);
|
|
24
|
+
const qs = params.toString();
|
|
25
|
+
const path = `/api/graphs/${graphId}/nodes/${nodeId}/connections${qs ? `?${qs}` : ''}`;
|
|
26
|
+
const data = await client.get(path);
|
|
27
|
+
return {
|
|
28
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=list-node-connections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-node-connections.js","sourceRoot":"","sources":["../../src/tools/list-node-connections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,2BAA2B,CAAC,MAAiB,EAAE,MAAmB;IACjF,MAAM,CAAC,YAAY,CAClB,6BAA6B,EAC7B;QACC,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACV,wXAAwX;QACzX,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,wBAAwB,CAAC;YACrD,QAAQ,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,sHAAsH,CAAC;YAClI,SAAS,EAAE,CAAC;iBACV,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;iBAC3B,QAAQ,EAAE;iBACV,QAAQ,CAAC,8EAA8E,CAAC;SAC1F,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE;QAClD,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QACrC,IAAI,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC/C,IAAI,SAAS;YAAE,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAClD,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,eAAe,OAAO,UAAU,MAAM,eAAe,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACvF,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,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,23 +1,22 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
const EdgeRef = z.object({
|
|
3
|
-
source: z.string().describe('Source node ID'),
|
|
4
|
-
target: z.string().describe('Target node ID'),
|
|
5
|
-
label: z.string().describe('Relationship type to delete (e.g. RELATES_TO, SOLVES)'),
|
|
6
|
-
});
|
|
7
2
|
export function registerRemoveEdge(server, client) {
|
|
8
3
|
server.registerTool('naumu_remove_edge', {
|
|
9
|
-
title: 'Remove
|
|
10
|
-
description: 'Delete
|
|
4
|
+
title: 'Remove Edge',
|
|
5
|
+
description: 'Delete a single edge identified by `(source, target, label)` tuple. Does NOT delete the endpoint nodes — only the edge between them. System edges (HAS_NODE, HAS_THREAD, OWNS, etc.) are rejected with `error: system_edge_not_removable`. Parent edges (`isParent: true`) are removable but the response includes a warning that the child may now be orphaned — call `naumu_reparent` first if you want connectivity preserved. Response: `{deleted: 0 | 1, warnings: string[]}`. Use for correcting wrong-target edge mistakes; this is a recovery tool, not a routine one. **Prefer `naumu_ask`** when the structural intent is broader than removing one specific edge — `naumu_ask` can reason about the surrounding graph.',
|
|
11
6
|
inputSchema: z.object({
|
|
12
7
|
graphId: z.string().describe('The graph ID'),
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
.
|
|
17
|
-
.describe('
|
|
8
|
+
source: z.string().describe('Source node id of the edge to delete'),
|
|
9
|
+
target: z.string().describe('Target node id of the edge to delete'),
|
|
10
|
+
label: z
|
|
11
|
+
.string()
|
|
12
|
+
.describe('Relation label of the edge to delete (e.g. "AUTHORED"). Case-insensitive; non-alphanum chars are normalized.'),
|
|
18
13
|
}),
|
|
19
|
-
}, async ({ graphId,
|
|
20
|
-
const data = await client.
|
|
14
|
+
}, async ({ graphId, source, target, label }) => {
|
|
15
|
+
const data = await client.del(`/api/graphs/${graphId}/edges`, {
|
|
16
|
+
source,
|
|
17
|
+
target,
|
|
18
|
+
label,
|
|
19
|
+
});
|
|
21
20
|
return {
|
|
22
21
|
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
23
22
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove-edge.js","sourceRoot":"","sources":["../../src/tools/remove-edge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,
|
|
1
|
+
{"version":3,"file":"remove-edge.js","sourceRoot":"","sources":["../../src/tools/remove-edge.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,EACV,msBAAmsB;QACpsB,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,sCAAsC,CAAC;YACnE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;YACnE,KAAK,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,QAAQ,CAAC,8GAA8G,CAAC;SAC1H,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;QAC5C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,OAAO,QAAQ,EAAE;YAC7D,MAAM;YACN,MAAM;YACN,KAAK;SACL,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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const EdgeRef = z.object({
|
|
3
|
+
source: z.string().describe('Source node ID'),
|
|
4
|
+
target: z.string().describe('Target node ID'),
|
|
5
|
+
label: z.string().describe('Relation label of the edge to delete'),
|
|
6
|
+
});
|
|
7
|
+
export function registerRemoveEdgesBulk(server, client) {
|
|
8
|
+
server.registerTool('naumu_remove_edges_bulk', {
|
|
9
|
+
title: 'Remove Edges (bulk)',
|
|
10
|
+
description: 'Delete 1–100 edges in a single atomic call — all-or-none, same semantics as `naumu_add_node`. Does NOT delete endpoint nodes. **System edges** (HAS_NODE, HAS_THREAD, OWNS, etc.) are rejected — if any edge in the batch targets a system relation, the WHOLE batch is rejected with `error: system_edge_not_removable`. **Parent edges** (`isParent: true`) are removable but each parent removal contributes a warning to the response (`{deleted, warnings: string[]}`) — call `naumu_reparent` first if you want connectivity preserved. Use to fix multiple wrong-target edge mistakes in one shot. **Prefer `naumu_ask`** for broader structural cleanup that needs graph-wide reasoning.',
|
|
11
|
+
inputSchema: z.object({
|
|
12
|
+
graphId: z.string().describe('The graph ID'),
|
|
13
|
+
edges: z
|
|
14
|
+
.array(EdgeRef)
|
|
15
|
+
.min(1)
|
|
16
|
+
.max(100)
|
|
17
|
+
.describe('1–100 edges to delete. Atomic per call — all succeed or none do.'),
|
|
18
|
+
}),
|
|
19
|
+
}, async ({ graphId, edges }) => {
|
|
20
|
+
const data = await client.del(`/api/graphs/${graphId}/edges/bulk`, { edges });
|
|
21
|
+
return {
|
|
22
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=remove-edges-bulk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove-edges-bulk.js","sourceRoot":"","sources":["../../src/tools/remove-edges-bulk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC;IACxB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAC7C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAC7C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;CAClE,CAAC,CAAC;AAEH,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,MAAmB;IAC7E,MAAM,CAAC,YAAY,CAClB,yBAAyB,EACzB;QACC,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACV,kqBAAkqB;QACnqB,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC5C,KAAK,EAAE,CAAC;iBACN,KAAK,CAAC,OAAO,CAAC;iBACd,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,GAAG,CAAC;iBACR,QAAQ,CAAC,kEAAkE,CAAC;SAC9E,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;QAC5B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,OAAO,aAAa,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9E,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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
package/dist/tools/search.js
CHANGED
|
@@ -2,14 +2,30 @@ import { z } from 'zod';
|
|
|
2
2
|
export function registerSearch(server, client) {
|
|
3
3
|
server.registerTool('naumu_search', {
|
|
4
4
|
title: 'Search Graph',
|
|
5
|
-
description: '
|
|
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
6
|
inputSchema: z.object({
|
|
7
7
|
graphId: z.string().describe('The graph ID'),
|
|
8
|
-
query: z
|
|
9
|
-
|
|
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"])'),
|
|
10
20
|
}),
|
|
11
|
-
}, async ({ graphId, query, limit }) => {
|
|
12
|
-
const
|
|
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()}`);
|
|
13
29
|
return {
|
|
14
30
|
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
15
31
|
};
|
package/dist/tools/search.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,
|
|
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"}
|
package/dist/tools/traverse.js
CHANGED
|
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
export function registerTraverse(server, client) {
|
|
3
3
|
server.registerTool('naumu_traverse', {
|
|
4
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 `
|
|
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
6
|
inputSchema: z.object({
|
|
7
7
|
graphId: z.string().describe('The graph ID'),
|
|
8
8
|
query: z
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,3 +1,30 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
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
|
+
};
|
|
3
29
|
export declare function registerUpdateNode(server: McpServer, client: NaumuClient): void;
|
|
30
|
+
export {};
|
|
@@ -1,4 +1,38 @@
|
|
|
1
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
|
+
}
|
|
2
36
|
/** Build a map of lowercase attribute name → valid values for a given node type. */
|
|
3
37
|
function getAttributeMap(schema, nodeType) {
|
|
4
38
|
const map = new Map();
|
|
@@ -10,10 +44,40 @@ function getAttributeMap(schema, nodeType) {
|
|
|
10
44
|
}
|
|
11
45
|
return map;
|
|
12
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
|
+
}
|
|
13
77
|
export function registerUpdateNode(server, client) {
|
|
14
78
|
server.registerTool('naumu_update_node', {
|
|
15
79
|
title: 'Update Node',
|
|
16
|
-
description: 'Update properties of an existing node. Only the provided fields will be changed. Good for simple attribute changes like setting a status or
|
|
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.',
|
|
17
81
|
inputSchema: z.object({
|
|
18
82
|
graphId: z.string().describe('The graph ID'),
|
|
19
83
|
nodeId: z.string().describe('The node ID to update'),
|
|
@@ -23,7 +87,7 @@ export function registerUpdateNode(server, client) {
|
|
|
23
87
|
attributes: z
|
|
24
88
|
.record(z.string(), z.unknown())
|
|
25
89
|
.optional()
|
|
26
|
-
.describe('Schema-defined attributes to set
|
|
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}.'),
|
|
27
91
|
}),
|
|
28
92
|
}, async ({ graphId, nodeId, label, type, content, attributes }) => {
|
|
29
93
|
const body = {};
|
|
@@ -49,7 +113,17 @@ export function registerUpdateNode(server, client) {
|
|
|
49
113
|
errors.push(`Unknown attribute "${key}" for type "${nodeType}". Valid attributes: ${validNames.length > 0 ? validNames.join(', ') : 'none'}.`);
|
|
50
114
|
continue;
|
|
51
115
|
}
|
|
52
|
-
//
|
|
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.
|
|
53
127
|
const validValues = schemaDef.values.map((v) => v.label);
|
|
54
128
|
if (typeof val === 'string' && validValues.length > 0 && !validValues.includes(val)) {
|
|
55
129
|
errors.push(`Invalid value "${val}" for attribute "${schemaDef.name}" on type "${nodeType}". Valid values: ${validValues.join(', ')}.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-node.js","sourceRoot":"","sources":["../../src/tools/update-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"update-node.js","sourceRoot":"","sources":["../../src/tools/update-node.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,11 +7,19 @@ const ConnectionSchema = z.object({
|
|
|
7
7
|
const AttributeValueSchema = z.object({
|
|
8
8
|
label: z.string().describe('Display label for this enum value'),
|
|
9
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.'),
|
|
10
14
|
});
|
|
11
15
|
const AttributeSchema = z.object({
|
|
12
16
|
name: z.string().describe('Attribute key (e.g. "stage", "status", "category")'),
|
|
13
17
|
type: z.enum(['select', 'multiselect', 'string', 'number', 'date']).optional().describe('Attribute type. Defaults to select if omitted.'),
|
|
14
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.'),
|
|
15
23
|
});
|
|
16
24
|
const NodeTypeSchema = z.object({
|
|
17
25
|
type: z.string().describe('Type name in PascalCase (e.g. Company, Person, Feature, Document)'),
|
|
@@ -23,6 +31,10 @@ const NodeTypeSchema = z.object({
|
|
|
23
31
|
attributes: z.array(AttributeSchema).optional().describe('Type-level attributes for instances of this type.'),
|
|
24
32
|
defaultVisibility: z.enum(['restricted', 'internal', 'open']).optional(),
|
|
25
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.'),
|
|
26
38
|
});
|
|
27
39
|
const SchemaDefinitionSchema = z.object({
|
|
28
40
|
description: z.string().optional().describe('Schema-level description / domain summary.'),
|
|
@@ -31,7 +43,7 @@ const SchemaDefinitionSchema = z.object({
|
|
|
31
43
|
export function registerUpdateSchema(server, client) {
|
|
32
44
|
server.registerTool('naumu_update_schema', {
|
|
33
45
|
title: 'Update Graph Schema',
|
|
34
|
-
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. 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.',
|
|
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.',
|
|
35
47
|
inputSchema: z.object({
|
|
36
48
|
graphId: z.string().describe('The graph ID'),
|
|
37
49
|
schema: SchemaDefinitionSchema,
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
1
|
+
{"version":3,"file":"update-schema.js","sourceRoot":"","sources":["../../src/tools/update-schema.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED