@naumu/mcp 0.6.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/dist/index.js +2314 -49
  2. package/package.json +6 -4
  3. package/dist/client.d.ts +0 -15
  4. package/dist/client.js +0 -82
  5. package/dist/client.js.map +0 -1
  6. package/dist/errors.d.ts +0 -35
  7. package/dist/errors.js +0 -52
  8. package/dist/errors.js.map +0 -1
  9. package/dist/index.d.ts +0 -2
  10. package/dist/index.js.map +0 -1
  11. package/dist/tools/add-attribute.d.ts +0 -3
  12. package/dist/tools/add-attribute.js +0 -58
  13. package/dist/tools/add-attribute.js.map +0 -1
  14. package/dist/tools/add-connection.d.ts +0 -3
  15. package/dist/tools/add-connection.js +0 -46
  16. package/dist/tools/add-connection.js.map +0 -1
  17. package/dist/tools/add-edge.d.ts +0 -3
  18. package/dist/tools/add-edge.js +0 -33
  19. package/dist/tools/add-edge.js.map +0 -1
  20. package/dist/tools/add-node-type.d.ts +0 -3
  21. package/dist/tools/add-node-type.js +0 -72
  22. package/dist/tools/add-node-type.js.map +0 -1
  23. package/dist/tools/add-node.d.ts +0 -3
  24. package/dist/tools/add-node.js +0 -36
  25. package/dist/tools/add-node.js.map +0 -1
  26. package/dist/tools/add-reaction.d.ts +0 -3
  27. package/dist/tools/add-reaction.js +0 -34
  28. package/dist/tools/add-reaction.js.map +0 -1
  29. package/dist/tools/ask-naumu.d.ts +0 -3
  30. package/dist/tools/ask-naumu.js +0 -44
  31. package/dist/tools/ask-naumu.js.map +0 -1
  32. package/dist/tools/ask.d.ts +0 -3
  33. package/dist/tools/ask.js +0 -37
  34. package/dist/tools/ask.js.map +0 -1
  35. package/dist/tools/batch-reparent.d.ts +0 -3
  36. package/dist/tools/batch-reparent.js +0 -31
  37. package/dist/tools/batch-reparent.js.map +0 -1
  38. package/dist/tools/canvas-add-element.d.ts +0 -3
  39. package/dist/tools/canvas-add-element.js +0 -46
  40. package/dist/tools/canvas-add-element.js.map +0 -1
  41. package/dist/tools/canvas-remove-element.d.ts +0 -3
  42. package/dist/tools/canvas-remove-element.js +0 -17
  43. package/dist/tools/canvas-remove-element.js.map +0 -1
  44. package/dist/tools/canvas-update-element.d.ts +0 -3
  45. package/dist/tools/canvas-update-element.js +0 -20
  46. package/dist/tools/canvas-update-element.js.map +0 -1
  47. package/dist/tools/create-canvas.d.ts +0 -3
  48. package/dist/tools/create-canvas.js +0 -17
  49. package/dist/tools/create-canvas.js.map +0 -1
  50. package/dist/tools/create-graph.d.ts +0 -3
  51. package/dist/tools/create-graph.js +0 -19
  52. package/dist/tools/create-graph.js.map +0 -1
  53. package/dist/tools/create-note.d.ts +0 -3
  54. package/dist/tools/create-note.js +0 -17
  55. package/dist/tools/create-note.js.map +0 -1
  56. package/dist/tools/create-thread.d.ts +0 -3
  57. package/dist/tools/create-thread.js +0 -63
  58. package/dist/tools/create-thread.js.map +0 -1
  59. package/dist/tools/filter.d.ts +0 -3
  60. package/dist/tools/filter.js +0 -54
  61. package/dist/tools/filter.js.map +0 -1
  62. package/dist/tools/get-ai-thread.d.ts +0 -3
  63. package/dist/tools/get-ai-thread.js +0 -18
  64. package/dist/tools/get-ai-thread.js.map +0 -1
  65. package/dist/tools/get-canvas-elements.d.ts +0 -3
  66. package/dist/tools/get-canvas-elements.js +0 -16
  67. package/dist/tools/get-canvas-elements.js.map +0 -1
  68. package/dist/tools/get-canvas-image.d.ts +0 -3
  69. package/dist/tools/get-canvas-image.js +0 -77
  70. package/dist/tools/get-canvas-image.js.map +0 -1
  71. package/dist/tools/get-node.d.ts +0 -3
  72. package/dist/tools/get-node.js +0 -17
  73. package/dist/tools/get-node.js.map +0 -1
  74. package/dist/tools/get-schema.d.ts +0 -3
  75. package/dist/tools/get-schema.js +0 -67
  76. package/dist/tools/get-schema.js.map +0 -1
  77. package/dist/tools/get-thread.d.ts +0 -3
  78. package/dist/tools/get-thread.js +0 -25
  79. package/dist/tools/get-thread.js.map +0 -1
  80. package/dist/tools/get-view.d.ts +0 -3
  81. package/dist/tools/get-view.js +0 -17
  82. package/dist/tools/get-view.js.map +0 -1
  83. package/dist/tools/index.d.ts +0 -16
  84. package/dist/tools/index.js +0 -155
  85. package/dist/tools/index.js.map +0 -1
  86. package/dist/tools/list-canvases.d.ts +0 -3
  87. package/dist/tools/list-canvases.js +0 -16
  88. package/dist/tools/list-canvases.js.map +0 -1
  89. package/dist/tools/list-dense-nodes.d.ts +0 -3
  90. package/dist/tools/list-dense-nodes.js +0 -29
  91. package/dist/tools/list-dense-nodes.js.map +0 -1
  92. package/dist/tools/list-graphs.d.ts +0 -3
  93. package/dist/tools/list-graphs.js +0 -14
  94. package/dist/tools/list-graphs.js.map +0 -1
  95. package/dist/tools/list-node-connections.d.ts +0 -3
  96. package/dist/tools/list-node-connections.js +0 -32
  97. package/dist/tools/list-node-connections.js.map +0 -1
  98. package/dist/tools/list-schema-violations.d.ts +0 -3
  99. package/dist/tools/list-schema-violations.js +0 -16
  100. package/dist/tools/list-schema-violations.js.map +0 -1
  101. package/dist/tools/list-threads.d.ts +0 -3
  102. package/dist/tools/list-threads.js +0 -56
  103. package/dist/tools/list-threads.js.map +0 -1
  104. package/dist/tools/list-view-nodes.d.ts +0 -3
  105. package/dist/tools/list-view-nodes.js +0 -29
  106. package/dist/tools/list-view-nodes.js.map +0 -1
  107. package/dist/tools/naumu-typing.d.ts +0 -3
  108. package/dist/tools/naumu-typing.js +0 -30
  109. package/dist/tools/naumu-typing.js.map +0 -1
  110. package/dist/tools/note-append.d.ts +0 -3
  111. package/dist/tools/note-append.js +0 -17
  112. package/dist/tools/note-append.js.map +0 -1
  113. package/dist/tools/note-delete-section.d.ts +0 -3
  114. package/dist/tools/note-delete-section.js +0 -22
  115. package/dist/tools/note-delete-section.js.map +0 -1
  116. package/dist/tools/note-find-replace.d.ts +0 -3
  117. package/dist/tools/note-find-replace.js +0 -26
  118. package/dist/tools/note-find-replace.js.map +0 -1
  119. package/dist/tools/note-insert.d.ts +0 -3
  120. package/dist/tools/note-insert.js +0 -24
  121. package/dist/tools/note-insert.js.map +0 -1
  122. package/dist/tools/note-read.d.ts +0 -3
  123. package/dist/tools/note-read.js +0 -16
  124. package/dist/tools/note-read.js.map +0 -1
  125. package/dist/tools/note-replace-section.d.ts +0 -3
  126. package/dist/tools/note-replace-section.js +0 -26
  127. package/dist/tools/note-replace-section.js.map +0 -1
  128. package/dist/tools/note-replace.d.ts +0 -3
  129. package/dist/tools/note-replace.js +0 -17
  130. package/dist/tools/note-replace.js.map +0 -1
  131. package/dist/tools/post-message.d.ts +0 -3
  132. package/dist/tools/post-message.js +0 -45
  133. package/dist/tools/post-message.js.map +0 -1
  134. package/dist/tools/react-to-message.d.ts +0 -3
  135. package/dist/tools/react-to-message.js +0 -34
  136. package/dist/tools/react-to-message.js.map +0 -1
  137. package/dist/tools/read-thread.d.ts +0 -3
  138. package/dist/tools/read-thread.js +0 -43
  139. package/dist/tools/read-thread.js.map +0 -1
  140. package/dist/tools/remove-edge.d.ts +0 -3
  141. package/dist/tools/remove-edge.js +0 -25
  142. package/dist/tools/remove-edge.js.map +0 -1
  143. package/dist/tools/remove-edges-bulk.d.ts +0 -3
  144. package/dist/tools/remove-edges-bulk.js +0 -26
  145. package/dist/tools/remove-edges-bulk.js.map +0 -1
  146. package/dist/tools/remove-node.d.ts +0 -3
  147. package/dist/tools/remove-node.js +0 -17
  148. package/dist/tools/remove-node.js.map +0 -1
  149. package/dist/tools/remove-reaction.d.ts +0 -3
  150. package/dist/tools/remove-reaction.js +0 -34
  151. package/dist/tools/remove-reaction.js.map +0 -1
  152. package/dist/tools/reparent.d.ts +0 -3
  153. package/dist/tools/reparent.js +0 -21
  154. package/dist/tools/reparent.js.map +0 -1
  155. package/dist/tools/request-attachment-upload.d.ts +0 -3
  156. package/dist/tools/request-attachment-upload.js +0 -59
  157. package/dist/tools/request-attachment-upload.js.map +0 -1
  158. package/dist/tools/search.d.ts +0 -3
  159. package/dist/tools/search.js +0 -34
  160. package/dist/tools/search.js.map +0 -1
  161. package/dist/tools/semantic-search.d.ts +0 -3
  162. package/dist/tools/semantic-search.js +0 -34
  163. package/dist/tools/semantic-search.js.map +0 -1
  164. package/dist/tools/text-search.d.ts +0 -3
  165. package/dist/tools/text-search.js +0 -18
  166. package/dist/tools/text-search.js.map +0 -1
  167. package/dist/tools/traverse.d.ts +0 -3
  168. package/dist/tools/traverse.js +0 -19
  169. package/dist/tools/traverse.js.map +0 -1
  170. package/dist/tools/update-node.d.ts +0 -30
  171. package/dist/tools/update-node.js +0 -152
  172. package/dist/tools/update-node.js.map +0 -1
  173. package/dist/tools/update-schema.d.ts +0 -3
  174. package/dist/tools/update-schema.js +0 -63
  175. package/dist/tools/update-schema.js.map +0 -1
  176. package/dist/tools/whoami.d.ts +0 -3
  177. package/dist/tools/whoami.js +0 -31
  178. package/dist/tools/whoami.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naumu/mcp",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "MCP server for Naumu – access your knowledge graph from Claude Code, Cursor, and other AI coding agents",
5
5
  "license": "MIT",
6
6
  "author": "Naumu <hello@naumu.ai>",
@@ -34,14 +34,15 @@
34
34
  "node": ">=18"
35
35
  },
36
36
  "scripts": {
37
- "build": "tsc",
38
- "dev": "tsc --watch",
37
+ "build": "tsup",
38
+ "dev": "tsup --watch",
39
39
  "start": "node dist/index.js",
40
40
  "test": "NODE_OPTIONS=--experimental-vm-modules jest",
41
- "prepublishOnly": "tsc"
41
+ "prepublishOnly": "tsup"
42
42
  },
43
43
  "dependencies": {
44
44
  "@modelcontextprotocol/sdk": "^1.12.1",
45
+ "@naumu/mcp-core": "workspace:*",
45
46
  "zod": "^3.25.23"
46
47
  },
47
48
  "devDependencies": {
@@ -49,6 +50,7 @@
49
50
  "@types/node": "*",
50
51
  "jest": "^30.3.0",
51
52
  "ts-jest": "^29.4.6",
53
+ "tsup": "^8.5.1",
52
54
  "typescript": "^5.9.3"
53
55
  }
54
56
  }
package/dist/client.d.ts DELETED
@@ -1,15 +0,0 @@
1
- export declare class NaumuClient {
2
- private baseUrl;
3
- private apiKey;
4
- constructor(baseUrl: string, apiKey: string);
5
- private headers;
6
- private handleResponse;
7
- get(path: string): Promise<unknown>;
8
- getBinary(path: string): Promise<{
9
- buffer: Uint8Array;
10
- contentType: string;
11
- }>;
12
- post(path: string, body?: unknown): Promise<unknown>;
13
- patch(path: string, body: unknown): Promise<unknown>;
14
- del(path: string, body?: unknown): Promise<unknown>;
15
- }
package/dist/client.js DELETED
@@ -1,82 +0,0 @@
1
- import { NaumuApiError, safeErrorMessage } from './errors.js';
2
- export class NaumuClient {
3
- baseUrl;
4
- apiKey;
5
- constructor(baseUrl, apiKey) {
6
- this.baseUrl = baseUrl.replace(/\/+$/, '');
7
- this.apiKey = apiKey;
8
- }
9
- headers() {
10
- return {
11
- 'Authorization': `Bearer ${this.apiKey}`,
12
- 'Content-Type': 'application/json',
13
- };
14
- }
15
- async handleResponse(res) {
16
- if (!res.ok) {
17
- const text = await res.text().catch(() => 'Unknown error');
18
- let upstream;
19
- try {
20
- const json = JSON.parse(text);
21
- upstream = json.message || text;
22
- }
23
- catch {
24
- upstream = text;
25
- }
26
- // Log the raw upstream message server-side for debugging, but throw
27
- // a safe-mapped one so 403/404 differentials don't leak through to
28
- // the model.
29
- console.error(`[mcp] upstream ${res.status}: ${upstream.slice(0, 500)}`);
30
- throw new NaumuApiError(res.status, safeErrorMessage(res.status, upstream), upstream);
31
- }
32
- return res.json();
33
- }
34
- async get(path) {
35
- const res = await fetch(`${this.baseUrl}${path}`, {
36
- method: 'GET',
37
- headers: this.headers(),
38
- });
39
- return this.handleResponse(res);
40
- }
41
- async getBinary(path) {
42
- const res = await fetch(`${this.baseUrl}${path}`, {
43
- method: 'GET',
44
- headers: { Authorization: `Bearer ${this.apiKey}` },
45
- });
46
- if (!res.ok) {
47
- const upstream = await res.text().catch(() => 'Unknown error');
48
- console.error(`[mcp] upstream binary ${res.status}: ${upstream.slice(0, 500)}`);
49
- throw new NaumuApiError(res.status, safeErrorMessage(res.status, upstream), upstream);
50
- }
51
- const arrayBuffer = await res.arrayBuffer();
52
- return {
53
- buffer: new Uint8Array(arrayBuffer),
54
- contentType: res.headers.get('content-type') ?? 'application/octet-stream',
55
- };
56
- }
57
- async post(path, body) {
58
- const res = await fetch(`${this.baseUrl}${path}`, {
59
- method: 'POST',
60
- headers: this.headers(),
61
- body: body !== undefined ? JSON.stringify(body) : undefined,
62
- });
63
- return this.handleResponse(res);
64
- }
65
- async patch(path, body) {
66
- const res = await fetch(`${this.baseUrl}${path}`, {
67
- method: 'PATCH',
68
- headers: this.headers(),
69
- body: JSON.stringify(body),
70
- });
71
- return this.handleResponse(res);
72
- }
73
- async del(path, body) {
74
- const res = await fetch(`${this.baseUrl}${path}`, {
75
- method: 'DELETE',
76
- headers: this.headers(),
77
- body: body !== undefined ? JSON.stringify(body) : undefined,
78
- });
79
- return this.handleResponse(res);
80
- }
81
- }
82
- //# sourceMappingURL=client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/errors.d.ts DELETED
@@ -1,35 +0,0 @@
1
- export declare class NaumuApiError extends Error {
2
- readonly status: number;
3
- /**
4
- * Raw upstream message — captured for server-side logging only. Never
5
- * pipe this to model output: it can carry 403/404 differential signal
6
- * (e.g. "Thread not found" vs "Role 'X' cannot perform 'thread:post'")
7
- * which lets a malicious caller enumerate resources they don't have
8
- * access to. Tools should surface `error.message` (the safe-mapped
9
- * version) instead.
10
- */
11
- readonly upstreamMessage?: string | undefined;
12
- constructor(status: number, message: string,
13
- /**
14
- * Raw upstream message — captured for server-side logging only. Never
15
- * pipe this to model output: it can carry 403/404 differential signal
16
- * (e.g. "Thread not found" vs "Role 'X' cannot perform 'thread:post'")
17
- * which lets a malicious caller enumerate resources they don't have
18
- * access to. Tools should surface `error.message` (the safe-mapped
19
- * version) instead.
20
- */
21
- upstreamMessage?: string | undefined);
22
- }
23
- /**
24
- * Map an HTTP status + raw upstream message to a model-safe error string.
25
- *
26
- * The 403/404 collapse is the security mitigation: bots can otherwise
27
- * enumerate threads / attachments / nodes they don't own by reading the
28
- * differential between "not found" and "forbidden" responses.
29
- *
30
- * 400/422 messages pass through verbatim because they describe what the
31
- * caller did wrong (malformed input, validation failure) — the bot needs
32
- * that detail to fix its own request, and the messages are derived from
33
- * its own input rather than server-side state.
34
- */
35
- export declare function safeErrorMessage(status: number, upstream: string): string;
package/dist/errors.js DELETED
@@ -1,52 +0,0 @@
1
- export class NaumuApiError extends Error {
2
- status;
3
- upstreamMessage;
4
- constructor(status, message,
5
- /**
6
- * Raw upstream message — captured for server-side logging only. Never
7
- * pipe this to model output: it can carry 403/404 differential signal
8
- * (e.g. "Thread not found" vs "Role 'X' cannot perform 'thread:post'")
9
- * which lets a malicious caller enumerate resources they don't have
10
- * access to. Tools should surface `error.message` (the safe-mapped
11
- * version) instead.
12
- */
13
- upstreamMessage) {
14
- super(message);
15
- this.status = status;
16
- this.upstreamMessage = upstreamMessage;
17
- this.name = 'NaumuApiError';
18
- }
19
- }
20
- /**
21
- * Map an HTTP status + raw upstream message to a model-safe error string.
22
- *
23
- * The 403/404 collapse is the security mitigation: bots can otherwise
24
- * enumerate threads / attachments / nodes they don't own by reading the
25
- * differential between "not found" and "forbidden" responses.
26
- *
27
- * 400/422 messages pass through verbatim because they describe what the
28
- * caller did wrong (malformed input, validation failure) — the bot needs
29
- * that detail to fix its own request, and the messages are derived from
30
- * its own input rather than server-side state.
31
- */
32
- export function safeErrorMessage(status, upstream) {
33
- if (status === 400 || status === 422)
34
- return upstream;
35
- if (status === 401)
36
- return 'Unauthorized — check your API key.';
37
- if (status === 403 || status === 404) {
38
- return 'Resource not found, or you do not have access to it.';
39
- }
40
- if (status === 409)
41
- return 'Conflict with current state.';
42
- if (status === 410)
43
- return 'Resource is no longer available.';
44
- if (status === 413)
45
- return 'Payload too large.';
46
- if (status === 429)
47
- return 'Rate limit exceeded — slow down and retry.';
48
- if (status >= 500)
49
- return 'Server error — try again shortly.';
50
- return `Request failed with status ${status}.`;
51
- }
52
- //# sourceMappingURL=errors.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,aAAc,SAAQ,KAAK;IAEtB;IAUA;IAXjB,YACiB,MAAc,EAC9B,OAAe;IACf;;;;;;;OAOG;IACa,eAAwB;QAExC,KAAK,CAAC,OAAO,CAAC,CAAC;QAZC,WAAM,GAAN,MAAM,CAAQ;QAUd,oBAAe,GAAf,eAAe,CAAS;QAGxC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC7B,CAAC;CACD;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,QAAgB;IAChE,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,QAAQ,CAAC;IACtD,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,oCAAoC,CAAC;IAChE,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACtC,OAAO,sDAAsD,CAAC;IAC/D,CAAC;IACD,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,8BAA8B,CAAC;IAC1D,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,kCAAkC,CAAC;IAC9D,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,oBAAoB,CAAC;IAChD,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,4CAA4C,CAAC;IACxE,IAAI,MAAM,IAAI,GAAG;QAAE,OAAO,mCAAmC,CAAC;IAC9D,OAAO,8BAA8B,MAAM,GAAG,CAAC;AAChD,CAAC"}
package/dist/index.d.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAExE,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAC3C,MAAM,cAAc,GAAG,UAAU,CAAC;AAElC,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,eAAe,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AACvF,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;AAEzC,IAAI,CAAC,MAAM,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;wOAwB6M,CAAC;AAEzO,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE/C,MAAM,MAAM,GAAG,IAAI,SAAS,CAC3B;IACC,IAAI,EAAE,OAAO;IACb,OAAO,EAAE,OAAO;CAChB,EACD;IACC,YAAY,EAAE,kBAAkB;CAChC,CACD,CAAC;AAEF,4EAA4E;AAC5E,8EAA8E;AAC9E,6CAA6C;AAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AAEnD,IAAI,QAAQ,EAAE,CAAC;IACd,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAKzE,CAAC;QACF,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACtD,OAAO,CAAC,KAAK,CACZ,sBAAsB,MAAM,oBAAoB,QAAQ,CAAC,UAAU,KAAK,QAAQ,CAAC,gBAAgB,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,qBAAqB,CACpJ,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,wCAAwC,OAAO,EAAE,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;AACF,CAAC;KAAM,CAAC;IACP,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,KAAK,CACZ,sBAAsB,MAAM,iBAAiB,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,oBAAoB,GAAG,CACrG,CAAC;AACH,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import type { NaumuClient } from '../client.js';
3
- export declare function registerAddAttribute(server: McpServer, client: NaumuClient): void;
@@ -1,58 +0,0 @@
1
- import { z } from 'zod';
2
- export function registerAddAttribute(server, client) {
3
- server.registerTool('naumu_add_attribute', {
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: [] — 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
- inputSchema: z.object({
7
- graphId: z.string(),
8
- node_type: z.string().describe('Existing node type to add the attribute to.'),
9
- name: z.string().describe('Attribute key (e.g. "stage", "status").'),
10
- type: z.enum(['select', 'multiselect', 'string', 'number', 'date']).default('select'),
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.'),
25
- }),
26
- }, async ({ graphId, node_type, name, type, values, description }) => {
27
- const current = (await client.get(`/api/graphs/${graphId}/schema`));
28
- const schema = current.definition ? JSON.parse(current.definition) : { nodes: [] };
29
- const node = schema.nodes.find((n) => n.type === node_type);
30
- if (!node) {
31
- return {
32
- content: [{ type: 'text', text: JSON.stringify({ error: `Node type "${node_type}" not found. Add it first via naumu_add_node_type.` }, null, 2) }],
33
- };
34
- }
35
- node.attributes = node.attributes ?? [];
36
- const existing = node.attributes.find((a) => a.name === name);
37
- let action;
38
- if (!existing) {
39
- node.attributes.push({ name, type, values, ...(description ? { description } : {}) });
40
- action = `Created attribute "${name}" (${type}) with ${values.length} value(s).`;
41
- }
42
- else {
43
- const existingLabels = new Set((existing.values ?? []).map((v) => v.label));
44
- const added = values.filter((v) => !existingLabels.has(v.label));
45
- existing.values = [...(existing.values ?? []), ...added];
46
- if (description && !existing.description)
47
- existing.description = description;
48
- action = added.length > 0
49
- ? `Extended attribute "${name}" with ${added.length} new value(s); kept ${existingLabels.size} existing.`
50
- : `Attribute "${name}" already had all proposed values; no change.`;
51
- }
52
- await client.post(`/api/graphs/${graphId}/schema`, { definition: schema });
53
- return {
54
- content: [{ type: 'text', text: JSON.stringify({ message: action, node_type }, null, 2) }],
55
- };
56
- });
57
- }
58
- //# sourceMappingURL=add-attribute.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-attribute.js","sourceRoot":"","sources":["../../src/tools/add-attribute.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import type { NaumuClient } from '../client.js';
3
- export declare function registerAddConnection(server: McpServer, client: NaumuClient): void;
@@ -1,46 +0,0 @@
1
- import { z } from 'zod';
2
- export function registerAddConnection(server, client) {
3
- server.registerTool('naumu_add_connection', {
4
- title: 'Add Connection to Node Type',
5
- description: 'Add one connection from an existing node type to another. `kind`: "parent" (sets/replaces — every non-root type needs exactly one parent; only ONE type in the whole schema has no parent), "required" (must exist on instances), "suggested" (optional). Each connection is XOR: ONE concrete target_node OR polymorphic=true — never both. DEFAULT TO CONCRETE target_node. Polymorphic is the ESCAPE HATCH — reserve for genuinely cross-cutting relations (e.g. a Tag-style relation that validly applies to many distinct types). If you can\'t pick a concrete target, you may be missing a type — add it first instead of falling back to polymorphic. Same-type nesting (e.g. Topic under Topic) does NOT need a new connection — use the existing parent relation. Relation name UPPER_SNAKE_CASE.',
6
- inputSchema: z.object({
7
- graphId: z.string(),
8
- source_type: z.string().describe('Existing node type to add the connection to.'),
9
- relation: z.string().describe('UPPER_SNAKE_CASE relation name.'),
10
- target_node: z.string().optional().describe('Target type. Omit when polymorphic=true.'),
11
- polymorphic: z.boolean().optional(),
12
- kind: z.enum(['required', 'suggested', 'parent']).default('suggested'),
13
- }),
14
- }, async ({ graphId, source_type, relation, target_node, polymorphic, kind }) => {
15
- const current = (await client.get(`/api/graphs/${graphId}/schema`));
16
- const schema = current.definition ? JSON.parse(current.definition) : { nodes: [] };
17
- const node = schema.nodes.find((n) => n.type === source_type);
18
- if (!node) {
19
- return {
20
- content: [{ type: 'text', text: JSON.stringify({ error: `Node type "${source_type}" not found. Add it first via naumu_add_node_type.` }, null, 2) }],
21
- };
22
- }
23
- const conn = { relation, ...(polymorphic ? { polymorphic: true } : {}), ...(target_node ? { target_node } : {}) };
24
- if (!node.connections)
25
- node.connections = { required: [], suggested: [] };
26
- if (kind === 'parent') {
27
- node.connections.parent = conn;
28
- }
29
- else {
30
- const list = node.connections[kind] ?? [];
31
- const exists = list.some((c) => c.relation === relation && c.target_node === target_node && Boolean(c.polymorphic) === Boolean(polymorphic));
32
- if (exists) {
33
- return {
34
- content: [{ type: 'text', text: JSON.stringify({ message: `Connection already exists on "${source_type}", no change.` }, null, 2) }],
35
- };
36
- }
37
- list.push(conn);
38
- node.connections[kind] = list;
39
- }
40
- await client.post(`/api/graphs/${graphId}/schema`, { definition: schema });
41
- return {
42
- content: [{ type: 'text', text: JSON.stringify({ message: `Added ${kind} connection ${relation}${target_node ? ` → ${target_node}` : ' (polymorphic)'} on "${source_type}".` }, null, 2) }],
43
- };
44
- });
45
- }
46
- //# sourceMappingURL=add-connection.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-connection.js","sourceRoot":"","sources":["../../src/tools/add-connection.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import type { NaumuClient } from '../client.js';
3
- export declare function registerAddEdge(server: McpServer, client: NaumuClient): void;
@@ -1,33 +0,0 @@
1
- import { z } from 'zod';
2
- const EdgeInput = 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 (e.g. RELATES_TO, SOLVES, TRACKS)'),
6
- isParent: z.boolean().optional().describe('Whether this is a parent relationship'),
7
- });
8
- export function registerAddEdge(server, client) {
9
- server.registerTool('naumu_add_edge', {
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. 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
- inputSchema: z.object({
13
- graphId: z.string().describe('The graph ID'),
14
- edges: z
15
- .array(EdgeInput)
16
- .min(1)
17
- .max(25)
18
- .describe('Batch of 1–25 edges to create. Keep batches small for atomicity.'),
19
- }),
20
- }, async ({ graphId, edges }) => {
21
- const payload = edges.map((e) => ({
22
- source: e.source,
23
- target: e.target,
24
- label: e.label,
25
- isParent: e.isParent || false,
26
- }));
27
- const data = await client.post(`/api/graphs/${graphId}/edges`, { edges: payload });
28
- return {
29
- content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
30
- };
31
- });
32
- }
33
- //# sourceMappingURL=add-edge.js.map
@@ -1 +0,0 @@
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"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import type { NaumuClient } from '../client.js';
3
- export declare function registerAddNodeType(server: McpServer, client: NaumuClient): void;
@@ -1,72 +0,0 @@
1
- import { z } from 'zod';
2
- const ConnectionSchema = z.object({
3
- relation: z.string().describe('UPPER_SNAKE_CASE relation name (WORKS_AT, BELONGS_TO).'),
4
- target_node: z.string().optional().describe('Target type name. Omit when polymorphic=true.'),
5
- polymorphic: z.boolean().optional().describe('True when this relation can target many types.'),
6
- });
7
- const AttributeValueSchema = z.object({
8
- label: z.string(),
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.'),
14
- });
15
- const AttributeSchema = z.object({
16
- name: z.string(),
17
- type: z.enum(['select', 'multiselect', 'string', 'number', 'date']).optional(),
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.'),
23
- });
24
- export function registerAddNodeType(server, client) {
25
- server.registerTool('naumu_add_node_type', {
26
- title: 'Add Node Type to Schema',
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.',
28
- inputSchema: z.object({
29
- graphId: z.string(),
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.'),
35
- parent: ConnectionSchema.optional().describe('Optional parent connection — sets this type as a child of another type.'),
36
- required: z.array(ConnectionSchema).optional(),
37
- suggested: z.array(ConnectionSchema).optional(),
38
- attributes: z.array(AttributeSchema).optional(),
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.'),
44
- }),
45
- }, async ({ graphId, type, description, parent, required, suggested, attributes, color, defaultVisibility }) => {
46
- const current = (await client.get(`/api/graphs/${graphId}/schema`));
47
- const schema = current.definition ? JSON.parse(current.definition) : { nodes: [] };
48
- if (schema.nodes.some((n) => n.type === type)) {
49
- return {
50
- content: [{ type: 'text', text: JSON.stringify({ error: `Node type "${type}" already exists. Use naumu_add_attribute / naumu_add_connection to extend it.` }, null, 2) }],
51
- };
52
- }
53
- const newNode = {
54
- type,
55
- connections: {
56
- required: required ?? [],
57
- suggested: suggested ?? [],
58
- ...(parent ? { parent } : {}),
59
- },
60
- ...(attributes && attributes.length > 0 ? { attributes } : {}),
61
- ...(color ? { color } : {}),
62
- ...(description ? { description } : {}),
63
- ...(defaultVisibility ? { defaultVisibility } : {}),
64
- };
65
- schema.nodes.push(newNode);
66
- await client.post(`/api/graphs/${graphId}/schema`, { definition: schema });
67
- return {
68
- content: [{ type: 'text', text: JSON.stringify({ message: `Added node type "${type}"`, total_types: schema.nodes.length }, null, 2) }],
69
- };
70
- });
71
- }
72
- //# sourceMappingURL=add-node-type.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-node-type.js","sourceRoot":"","sources":["../../src/tools/add-node-type.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import type { NaumuClient } from '../client.js';
3
- export declare function registerAddNode(server: McpServer, client: NaumuClient): void;
@@ -1,36 +0,0 @@
1
- import { z } from 'zod';
2
- const NodeInput = z.object({
3
- label: z.string().describe('Display name of the node'),
4
- type: z.string().describe('Node type from the graph schema (e.g. Feature, Pain, Metric)'),
5
- content: z
6
- .string()
7
- .min(1)
8
- .describe('Rich text content / description. REQUIRED — every node must explain what it is.'),
9
- attributes: z.record(z.string(), z.unknown()).optional().describe('Additional key-value attributes'),
10
- });
11
- export function registerAddNode(server, client) {
12
- server.registerTool('naumu_add_node', {
13
- title: 'Add Nodes (bulk)',
14
- description: 'Create 1–25 nodes in the knowledge graph in a single call. Keep batches small and atomic (5–25 nodes) so failures stay contained. Each node MUST include a non-empty `content` describing what it is. Returns one entry per input node with `{id, label, type, status: "created"}` — there is NO server-side dedup, every input becomes a node. Dedup is the caller\'s responsibility: BEFORE calling this tool, run `naumu_semantic_search` on each candidate label and skip/route to update if a result has high similarity (≥0.78) and matching type. Warning: nodes are isolated until you connect them with `naumu_add_edge`. **Prefer `naumu_ask`** for general knowledge intake — it discovers and creates connections for you. Use this when you have a vetted, dedup-checked batch ready to insert.',
15
- inputSchema: z.object({
16
- graphId: z.string().describe('The graph ID'),
17
- nodes: z
18
- .array(NodeInput)
19
- .min(1)
20
- .max(25)
21
- .describe('Batch of 1–25 nodes to create. Keep batches small for atomicity.'),
22
- }),
23
- }, async ({ graphId, nodes }) => {
24
- const payload = nodes.map(({ label, type, content, attributes }) => {
25
- const node = { label, type, content };
26
- if (attributes)
27
- Object.assign(node, attributes);
28
- return node;
29
- });
30
- const data = await client.post(`/api/graphs/${graphId}/nodes`, { nodes: payload });
31
- return {
32
- content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
33
- };
34
- });
35
- }
36
- //# sourceMappingURL=add-node.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-node.js","sourceRoot":"","sources":["../../src/tools/add-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;IACtD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8DAA8D,CAAC;IACzF,OAAO,EAAE,CAAC;SACR,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,iFAAiF,CAAC;IAC7F,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;CACpG,CAAC,CAAC;AAEH,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,MAAmB;IACrE,MAAM,CAAC,YAAY,CAClB,gBAAgB,EAChB;QACC,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACV,8wBAA8wB;QAC/wB,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,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE;YAClE,MAAM,IAAI,GAA4B,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YAC/D,IAAI,UAAU;gBAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC;QACb,CAAC,CAAC,CAAC;QAEH,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"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import type { NaumuClient } from '../client.js';
3
- export declare function registerAddReaction(server: McpServer, client: NaumuClient): void;
@@ -1,34 +0,0 @@
1
- import { z } from 'zod';
2
- export function registerAddReaction(server, client) {
3
- server.registerTool('naumu_add_reaction', {
4
- title: 'Add Reaction',
5
- description: 'Add an emoji reaction to a message in a thread you are participating in. Idempotent — calling twice with the same emoji is a no-op (use `naumu_remove_reaction` to undo). Returns `{ ok, messageId, emoji, alreadyExisted, reactionCount, reactions }` so you can confirm the state without re-reading the thread; `alreadyExisted: true` means the reaction was already on the message and the call was a no-op.\n\nWhen to react vs. when to post a message:\n• React (no message) for lightweight acknowledgement (👀, ✅, 👍), appreciation (❤️, 🙌), laughter (😂), or "I saw this".\n• Post a message for direct questions, clarification, important corrections, or final results — situations where words are required.\n• For long tasks: react 👀 first to acknowledge, optionally post a short "On it — I\'ll report back" if the work will take >20s, do the work, then post the final result.\n• Ignore casual human banter, side-conversations someone else already answered, or anything where you would only say "ok"/"nice"/"lol".\n\nUse at most one reaction per message unless explicitly useful. Reactions are social backpressure relief, not a sparkle-confetti channel.',
6
- inputSchema: z.object({
7
- threadId: z
8
- .string()
9
- .describe('Thread containing the message. You must be a participant.'),
10
- messageId: z
11
- .string()
12
- .describe('The message to react to.'),
13
- emoji: z
14
- .string()
15
- .min(1)
16
- .describe('Emoji character (e.g. "👀", "✅", "❤️"). Custom-emoji shortcodes are NOT supported here — pass a real Unicode emoji.'),
17
- }),
18
- }, async ({ threadId, messageId, emoji }) => {
19
- try {
20
- const data = await client.post(`/api/threads/${threadId}/messages/${messageId}/reactions`, { emoji, action: 'add' });
21
- return {
22
- content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
23
- };
24
- }
25
- catch (err) {
26
- const message = err instanceof Error ? err.message : String(err);
27
- return {
28
- content: [{ type: 'text', text: `Error: ${message}` }],
29
- isError: true,
30
- };
31
- }
32
- });
33
- }
34
- //# sourceMappingURL=add-reaction.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-reaction.js","sourceRoot":"","sources":["../../src/tools/add-reaction.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,goCAAgoC;QACjoC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,QAAQ,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,CAAC,2DAA2D,CAAC;YACvE,SAAS,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,CAAC,0BAA0B,CAAC;YACtC,KAAK,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,qHAAqH,CAAC;SACjI,CAAC;KACF,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE;QACxC,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAC7B,gBAAgB,QAAQ,aAAa,SAAS,YAAY,EAC1D,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CACxB,CAAC;YACF,OAAO;gBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aACzE,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO;gBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;gBAC/D,OAAO,EAAE,IAAI;aACb,CAAC;QACH,CAAC;IACF,CAAC,CACD,CAAC;AACH,CAAC"}
@@ -1,3 +0,0 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import type { NaumuClient } from '../client.js';
3
- export declare function registerAskNaumu(server: McpServer, client: NaumuClient): void;