@naumu/mcp 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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-node-type.js +20 -2
- package/dist/tools/add-node-type.js.map +1 -1
- package/dist/tools/get-schema.js +30 -3
- 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.d.ts +4 -1
- package/dist/tools/index.js +11 -3
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/list-threads.js +17 -4
- package/dist/tools/list-threads.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 +17 -2
- package/dist/tools/update-schema.js.map +1 -1
- package/dist/tools/whoami.d.ts +1 -1
- package/dist/tools/whoami.js +10 -2
- package/dist/tools/whoami.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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"}
|
|
@@ -7,26 +7,42 @@ 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(),
|
|
40
|
+
defaultVisibility: z
|
|
41
|
+
.enum(['restricted', 'internal', 'open'])
|
|
42
|
+
.optional()
|
|
43
|
+
.describe('Default visibility for NEW nodes of this type when no explicit visibility is passed on creation. Does NOT retroactively change existing nodes. "open" = visible to anyone with the space link, "internal" = visible to all space members, "restricted" = only members explicitly granted access. Omit to fall back to the space-level defaultVisibility.'),
|
|
28
44
|
}),
|
|
29
|
-
}, async ({ graphId, type, parent, required, suggested, attributes, color }) => {
|
|
45
|
+
}, async ({ graphId, type, description, parent, required, suggested, attributes, color, defaultVisibility }) => {
|
|
30
46
|
const current = (await client.get(`/api/graphs/${graphId}/schema`));
|
|
31
47
|
const schema = current.definition ? JSON.parse(current.definition) : { nodes: [] };
|
|
32
48
|
if (schema.nodes.some((n) => n.type === type)) {
|
|
@@ -43,6 +59,8 @@ export function registerAddNodeType(server, client) {
|
|
|
43
59
|
},
|
|
44
60
|
...(attributes && attributes.length > 0 ? { attributes } : {}),
|
|
45
61
|
...(color ? { color } : {}),
|
|
62
|
+
...(description ? { description } : {}),
|
|
63
|
+
...(defaultVisibility ? { defaultVisibility } : {}),
|
|
46
64
|
};
|
|
47
65
|
schema.nodes.push(newNode);
|
|
48
66
|
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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"}
|
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
|
}),
|
|
@@ -32,8 +47,20 @@ export function registerGetSchema(server, client) {
|
|
|
32
47
|
const data = (await client.get(`/api/graphs/${graphId}/schema`));
|
|
33
48
|
const schema = JSON.parse(data.definition);
|
|
34
49
|
const formatted = formatSchema(schema);
|
|
50
|
+
// Fold in the canonical space-description (the same string the main
|
|
51
|
+
// agent reads off Graph.description) so MCP consumers calling this
|
|
52
|
+
// tool also see "what this space is about" alongside the schema.
|
|
53
|
+
let spaceDescription = null;
|
|
54
|
+
try {
|
|
55
|
+
const summary = (await client.get(`/api/graphs/${graphId}/summary`));
|
|
56
|
+
spaceDescription = summary.description ?? summary.summary ?? null;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Best-effort — schema is still useful without the description.
|
|
60
|
+
}
|
|
61
|
+
const out = { ...formatted, space_description: spaceDescription };
|
|
35
62
|
return {
|
|
36
|
-
content: [{ type: 'text', text: JSON.stringify(
|
|
63
|
+
content: [{ type: 'text', text: JSON.stringify(out, null, 2) }],
|
|
37
64
|
};
|
|
38
65
|
});
|
|
39
66
|
}
|
|
@@ -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":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAqCxB,wEAAwE;AACxE,SAAS,YAAY,CAAC,MAAwB;IAC7C,OAAO;QACN,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,IAAI;QACvC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAChC,MAAM,MAAM,GAA4B,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5D,IAAI,IAAI,CAAC,WAAW;gBAAE,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;YAE5D,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;gBAC7B,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAChG,CAAC;YAED,MAAM,WAAW,GAAG;gBACnB,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,WAAW,aAAa,CAAC;gBACtF,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;aAC5E,CAAC;YACF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;YAE7D,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnD,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,WAAW,CACrC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBACzB,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACzC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CACxE,CAAC;oBACF,MAAM,UAAU,GAA4B,EAAE,MAAM,EAAE,CAAC;oBACvD,IAAI,CAAC,CAAC,WAAW;wBAAE,UAAU,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC;oBAC1D,+EAA+E;oBAC/E,iFAAiF;oBACjF,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;oBAChC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;oBAChE,IAAI,CAAC,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC;wBAChC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;oBACvD,CAAC;oBACD,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBAC7B,CAAC,CAAC,CACF,CAAC;YACH,CAAC;YAED,OAAO,MAAM,CAAC;QACf,CAAC,CAAC;KACF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,MAAmB;IACvE,MAAM,CAAC,YAAY,CAClB,kBAAkB,EAClB;QACC,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACV,+dAA+d;QAChe,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;SAC5C,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACrB,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,OAAO,SAAS,CAAC,CAA2B,CAAC;QAC3F,MAAM,MAAM,GAAqB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAEvC,oEAAoE;QACpE,mEAAmE;QACnE,iEAAiE;QACjE,IAAI,gBAAgB,GAAkB,IAAI,CAAC;QAC3C,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,OAAO,UAAU,CAAC,CAGlE,CAAC;YACF,gBAAgB,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;QACnE,CAAC;QAAC,MAAM,CAAC;YACR,gEAAgE;QACjE,CAAC;QAED,MAAM,GAAG,GAAG,EAAE,GAAG,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;QAClE,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACxE,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
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.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import type { NaumuClient } from '../client.js';
|
|
3
|
+
/** Every MCP tool name this build registers — the full user-key surface. */
|
|
4
|
+
export declare const ALL_TOOL_NAMES: readonly string[];
|
|
3
5
|
/**
|
|
4
6
|
* Register every MCP tool. Used by user-key sessions, where no per-Identity
|
|
5
|
-
* filtering applies.
|
|
7
|
+
* filtering applies. `whoami` is handed the full tool-name list so its
|
|
8
|
+
* user-mode response can report the surface (the backend can't know it).
|
|
6
9
|
*/
|
|
7
10
|
export declare function registerAllTools(server: McpServer, client: NaumuClient): void;
|
|
8
11
|
/**
|
package/dist/tools/index.js
CHANGED
|
@@ -112,13 +112,21 @@ const TOOL_REGISTRARS = {
|
|
|
112
112
|
naumu_reparent: registerReparent,
|
|
113
113
|
naumu_batch_reparent: registerBatchReparent,
|
|
114
114
|
};
|
|
115
|
+
/** Every MCP tool name this build registers — the full user-key surface. */
|
|
116
|
+
export const ALL_TOOL_NAMES = Object.keys(TOOL_REGISTRARS);
|
|
115
117
|
/**
|
|
116
118
|
* Register every MCP tool. Used by user-key sessions, where no per-Identity
|
|
117
|
-
* filtering applies.
|
|
119
|
+
* filtering applies. `whoami` is handed the full tool-name list so its
|
|
120
|
+
* user-mode response can report the surface (the backend can't know it).
|
|
118
121
|
*/
|
|
119
122
|
export function registerAllTools(server, client) {
|
|
120
|
-
for (const registrar of Object.
|
|
121
|
-
|
|
123
|
+
for (const [name, registrar] of Object.entries(TOOL_REGISTRARS)) {
|
|
124
|
+
if (name === 'naumu_whoami') {
|
|
125
|
+
registerWhoami(server, client, ALL_TOOL_NAMES);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
registrar(server, client);
|
|
129
|
+
}
|
|
122
130
|
}
|
|
123
131
|
}
|
|
124
132
|
/**
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,8 +2,12 @@ import { z } from 'zod';
|
|
|
2
2
|
export function registerListThreads(server, client) {
|
|
3
3
|
server.registerTool('naumu_list_threads', {
|
|
4
4
|
title: 'List Threads',
|
|
5
|
-
description: 'List threads
|
|
5
|
+
description: 'List threads sorted by last activity (newest first), for self-discovery before deciding which to engage. With a user API key, pass `graphId` to list threads you can see in that space (resolve it via naumu_list_graphs). With a bot identity key, omit `graphId` to list threads in your own graph — each row carries an `isParticipant` flag (TRUE means you were explicitly invited and your replies fan out via webhook). Page back with `cursor` set to the oldest `lastActivityAt` from the previous page.',
|
|
6
6
|
inputSchema: z.object({
|
|
7
|
+
graphId: z
|
|
8
|
+
.string()
|
|
9
|
+
.optional()
|
|
10
|
+
.describe('Graph (space) ID. Required for user API keys; omit for bot identity keys (defaults to your own graph).'),
|
|
7
11
|
cursor: z
|
|
8
12
|
.number()
|
|
9
13
|
.int()
|
|
@@ -17,15 +21,24 @@ export function registerListThreads(server, client) {
|
|
|
17
21
|
.optional()
|
|
18
22
|
.describe('Page size, default 50, max 200.'),
|
|
19
23
|
}),
|
|
20
|
-
}, async ({ cursor, limit }) => {
|
|
24
|
+
}, async ({ graphId, cursor, limit }) => {
|
|
21
25
|
try {
|
|
22
26
|
const params = new URLSearchParams();
|
|
23
27
|
if (cursor !== undefined)
|
|
24
28
|
params.set('cursor', String(cursor));
|
|
25
29
|
if (limit !== undefined)
|
|
26
30
|
params.set('limit', String(limit));
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
// User keys are graph-scoped: route to the user-facing paginated
|
|
32
|
+
// listing. Bot keys self-discover their own graph via me/threads.
|
|
33
|
+
let path;
|
|
34
|
+
if (graphId) {
|
|
35
|
+
params.set('graphId', graphId);
|
|
36
|
+
path = `/api/threads/paginated?${params.toString()}`;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const qs = params.toString();
|
|
40
|
+
path = `/api/identities/me/threads${qs ? `?${qs}` : ''}`;
|
|
41
|
+
}
|
|
29
42
|
const data = await client.get(path);
|
|
30
43
|
return {
|
|
31
44
|
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-threads.js","sourceRoot":"","sources":["../../src/tools/list-threads.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,
|
|
1
|
+
{"version":3,"file":"list-threads.js","sourceRoot":"","sources":["../../src/tools/list-threads.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,mfAAmf;QACpf,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,OAAO,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,wGAAwG,CAAC;YACpH,MAAM,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,QAAQ,EAAE;iBACV,QAAQ,CAAC,+GAA+G,CAAC;YAC3H,KAAK,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,GAAG,CAAC;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,iCAAiC,CAAC;SAC7C,CAAC;KACF,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;QACpC,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YACrC,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YAC/D,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5D,iEAAiE;YACjE,kEAAkE;YAClE,IAAI,IAAY,CAAC;YACjB,IAAI,OAAO,EAAE,CAAC;gBACb,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBAC/B,IAAI,GAAG,0BAA0B,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACP,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAC7B,IAAI,GAAG,6BAA6B,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC1D,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpC,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"}
|
|
@@ -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)'),
|
|
@@ -21,8 +29,15 @@ const NodeTypeSchema = z.object({
|
|
|
21
29
|
suggested: z.array(ConnectionSchema).default([]).describe('Suggested-but-optional outgoing connections.'),
|
|
22
30
|
}),
|
|
23
31
|
attributes: z.array(AttributeSchema).optional().describe('Type-level attributes for instances of this type.'),
|
|
24
|
-
defaultVisibility: z
|
|
32
|
+
defaultVisibility: z
|
|
33
|
+
.enum(['restricted', 'internal', 'open'])
|
|
34
|
+
.optional()
|
|
35
|
+
.describe('Default visibility for NEW nodes of this type when no explicit visibility is passed on creation. Does NOT retroactively change visibility on existing nodes. "open" = visible to anyone with the space link (including non-members), "internal" = visible to all space members, "restricted" = only members explicitly granted access. Omit to leave the type unset — it then falls back to the space-level defaultVisibility.'),
|
|
25
36
|
color: z.string().optional().describe('Optional hex color for instances of this type.'),
|
|
37
|
+
description: z
|
|
38
|
+
.string()
|
|
39
|
+
.optional()
|
|
40
|
+
.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
41
|
});
|
|
27
42
|
const SchemaDefinitionSchema = z.object({
|
|
28
43
|
description: z.string().optional().describe('Schema-level description / domain summary.'),
|
|
@@ -31,7 +46,7 @@ const SchemaDefinitionSchema = z.object({
|
|
|
31
46
|
export function registerUpdateSchema(server, client) {
|
|
32
47
|
server.registerTool('naumu_update_schema', {
|
|
33
48
|
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.',
|
|
49
|
+
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
50
|
inputSchema: z.object({
|
|
36
51
|
graphId: z.string().describe('The graph ID'),
|
|
37
52
|
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/dist/tools/whoami.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import type { NaumuClient } from '../client.js';
|
|
3
|
-
export declare function registerWhoami(server: McpServer, client: NaumuClient): void;
|
|
3
|
+
export declare function registerWhoami(server: McpServer, client: NaumuClient, allToolNames?: string[]): void;
|
package/dist/tools/whoami.js
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
export function registerWhoami(server, client) {
|
|
2
|
+
export function registerWhoami(server, client, allToolNames) {
|
|
3
3
|
server.registerTool('naumu_whoami', {
|
|
4
4
|
title: 'Who Am I',
|
|
5
|
-
description: 'Return the calling Identity
|
|
5
|
+
description: 'Return who the calling key is plus the live MCP tool manifest, so you can bootstrap before the first real operation. A bot identity key returns its Identity row (id, graphId, name, instructions, allowedTools). A user API key returns `kind: "user"` with userId, name, and email — a person spans many graphs, so resolve a specific graph via naumu_list_graphs. No arguments. Always available regardless of the permission grid.',
|
|
6
6
|
inputSchema: z.object({}),
|
|
7
7
|
}, async () => {
|
|
8
8
|
try {
|
|
9
9
|
const data = await client.get('/api/identities/me/whoami');
|
|
10
|
+
// User keys get the full local tool surface — the backend can't
|
|
11
|
+
// know which MCP build is installed, so fill it in here.
|
|
12
|
+
if (allToolNames &&
|
|
13
|
+
data &&
|
|
14
|
+
typeof data === 'object' &&
|
|
15
|
+
data.kind === 'user') {
|
|
16
|
+
data.mcpTools = allToolNames;
|
|
17
|
+
}
|
|
10
18
|
return {
|
|
11
19
|
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
12
20
|
};
|
package/dist/tools/whoami.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/tools/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,cAAc,
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/tools/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,cAAc,CAC7B,MAAiB,EACjB,MAAmB,EACnB,YAAuB;IAEvB,MAAM,CAAC,YAAY,CAClB,cAAc,EACd;QACC,KAAK,EAAE,UAAU;QACjB,WAAW,EACV,yaAAya;QAC1a,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;KACzB,EACD,KAAK,IAAI,EAAE;QACV,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YAC3D,gEAAgE;YAChE,yDAAyD;YACzD,IACC,YAAY;gBACZ,IAAI;gBACJ,OAAO,IAAI,KAAK,QAAQ;gBACvB,IAA2B,CAAC,IAAI,KAAK,MAAM,EAC3C,CAAC;gBACD,IAAgC,CAAC,QAAQ,GAAG,YAAY,CAAC;YAC3D,CAAC;YACD,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/package.json
CHANGED