velixar-mcp-server 0.2.4 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +120 -64
  2. package/dist/api.d.ts +64 -0
  3. package/dist/api.d.ts.map +1 -0
  4. package/dist/api.js +405 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/errors.d.ts +19 -0
  7. package/dist/errors.d.ts.map +1 -0
  8. package/dist/errors.js +52 -0
  9. package/dist/errors.js.map +1 -0
  10. package/dist/justify.d.ts +9 -0
  11. package/dist/justify.d.ts.map +1 -0
  12. package/dist/justify.js +114 -0
  13. package/dist/justify.js.map +1 -0
  14. package/dist/prompts.d.ts +88 -0
  15. package/dist/prompts.d.ts.map +1 -0
  16. package/dist/prompts.js +693 -0
  17. package/dist/prompts.js.map +1 -0
  18. package/dist/resources.d.ts +25 -0
  19. package/dist/resources.d.ts.map +1 -0
  20. package/dist/resources.js +278 -0
  21. package/dist/resources.js.map +1 -0
  22. package/dist/server.d.ts +3 -0
  23. package/dist/server.d.ts.map +1 -0
  24. package/dist/server.js +392 -0
  25. package/dist/server.js.map +1 -0
  26. package/dist/simulation/personas.d.ts +41 -0
  27. package/dist/simulation/personas.d.ts.map +1 -0
  28. package/dist/simulation/personas.js +173 -0
  29. package/dist/simulation/personas.js.map +1 -0
  30. package/dist/simulation/report.d.ts +28 -0
  31. package/dist/simulation/report.d.ts.map +1 -0
  32. package/dist/simulation/report.js +105 -0
  33. package/dist/simulation/report.js.map +1 -0
  34. package/dist/simulation/runner.d.ts +63 -0
  35. package/dist/simulation/runner.d.ts.map +1 -0
  36. package/dist/simulation/runner.js +167 -0
  37. package/dist/simulation/runner.js.map +1 -0
  38. package/dist/temporal_merge.d.ts +70 -0
  39. package/dist/temporal_merge.d.ts.map +1 -0
  40. package/dist/temporal_merge.js +258 -0
  41. package/dist/temporal_merge.js.map +1 -0
  42. package/dist/tools/clairvoyance.d.ts +9 -0
  43. package/dist/tools/clairvoyance.d.ts.map +1 -0
  44. package/dist/tools/clairvoyance.js +321 -0
  45. package/dist/tools/clairvoyance.js.map +1 -0
  46. package/dist/tools/cognitive.d.ts +10 -0
  47. package/dist/tools/cognitive.d.ts.map +1 -0
  48. package/dist/tools/cognitive.js +462 -0
  49. package/dist/tools/cognitive.js.map +1 -0
  50. package/dist/tools/construction.d.ts +9 -0
  51. package/dist/tools/construction.d.ts.map +1 -0
  52. package/dist/tools/construction.js +350 -0
  53. package/dist/tools/construction.js.map +1 -0
  54. package/dist/tools/graph.d.ts +14 -0
  55. package/dist/tools/graph.d.ts.map +1 -0
  56. package/dist/tools/graph.js +263 -0
  57. package/dist/tools/graph.js.map +1 -0
  58. package/dist/tools/graph_sanitizer.d.ts +24 -0
  59. package/dist/tools/graph_sanitizer.d.ts.map +1 -0
  60. package/dist/tools/graph_sanitizer.js +79 -0
  61. package/dist/tools/graph_sanitizer.js.map +1 -0
  62. package/dist/tools/lifecycle.d.ts +9 -0
  63. package/dist/tools/lifecycle.d.ts.map +1 -0
  64. package/dist/tools/lifecycle.js +1091 -0
  65. package/dist/tools/lifecycle.js.map +1 -0
  66. package/dist/tools/livedata.d.ts +9 -0
  67. package/dist/tools/livedata.d.ts.map +1 -0
  68. package/dist/tools/livedata.js +222 -0
  69. package/dist/tools/livedata.js.map +1 -0
  70. package/dist/tools/memory.d.ts +10 -0
  71. package/dist/tools/memory.d.ts.map +1 -0
  72. package/dist/tools/memory.js +275 -0
  73. package/dist/tools/memory.js.map +1 -0
  74. package/dist/tools/recall.d.ts +9 -0
  75. package/dist/tools/recall.d.ts.map +1 -0
  76. package/dist/tools/recall.js +206 -0
  77. package/dist/tools/recall.js.map +1 -0
  78. package/dist/tools/retrieval.d.ts +9 -0
  79. package/dist/tools/retrieval.d.ts.map +1 -0
  80. package/dist/tools/retrieval.js +338 -0
  81. package/dist/tools/retrieval.js.map +1 -0
  82. package/dist/tools/system.d.ts +12 -0
  83. package/dist/tools/system.d.ts.map +1 -0
  84. package/dist/tools/system.js +228 -0
  85. package/dist/tools/system.js.map +1 -0
  86. package/dist/types.d.ts +234 -0
  87. package/dist/types.d.ts.map +1 -0
  88. package/dist/types.js +5 -0
  89. package/dist/types.js.map +1 -0
  90. package/dist/validate.d.ts +79 -0
  91. package/dist/validate.d.ts.map +1 -0
  92. package/dist/validate.js +174 -0
  93. package/dist/validate.js.map +1 -0
  94. package/dist/validate_retrieval.d.ts +33 -0
  95. package/dist/validate_retrieval.d.ts.map +1 -0
  96. package/dist/validate_retrieval.js +97 -0
  97. package/dist/validate_retrieval.js.map +1 -0
  98. package/package.json +22 -6
  99. package/server.json +2 -2
  100. package/.github/workflows/ci.yml +0 -18
  101. package/.mcpregistry_github_token +0 -1
  102. package/.mcpregistry_registry_token +0 -1
  103. package/src/index.js +0 -262
  104. package/tests/server.test.js +0 -193
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate_retrieval.js","sourceRoot":"","sources":["../src/validate_retrieval.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,14 +1,17 @@
1
1
  {
2
2
  "name": "velixar-mcp-server",
3
- "version": "0.2.4",
4
- "description": "MCP server for Velixar persistent memorygive your AI agents long-term recall",
3
+ "version": "1.2.0",
4
+ "description": "MCP server for Velixar persistent cognitive context memory, identity, graph, time, and contradiction for LLMs",
5
5
  "type": "module",
6
6
  "bin": {
7
- "velixar-mcp-server": "./src/index.js"
7
+ "velixar-mcp-server": "./dist/server.js"
8
8
  },
9
9
  "scripts": {
10
- "start": "node src/index.js",
11
- "test": "node --test tests/*.test.js"
10
+ "build": "tsc",
11
+ "start": "node dist/server.js",
12
+ "dev": "tsc --watch",
13
+ "test": "node --test tests/*.test.js",
14
+ "prepublishOnly": "npm run build"
12
15
  },
13
16
  "keywords": [
14
17
  "mcp",
@@ -17,6 +20,9 @@
17
20
  "memory",
18
21
  "llm",
19
22
  "persistent-memory",
23
+ "cognitive-context",
24
+ "knowledge-graph",
25
+ "identity",
20
26
  "vector-search"
21
27
  ],
22
28
  "author": "Velixar <sdk@velixarai.com>",
@@ -29,5 +35,15 @@
29
35
  "dependencies": {
30
36
  "@modelcontextprotocol/sdk": "1.21.0"
31
37
  },
32
- "mcpName": "io.github.VelixarAi/memory"
38
+ "devDependencies": {
39
+ "@types/node": "^22.13.14",
40
+ "typescript": "^5.8.2"
41
+ },
42
+ "mcpName": "io.github.VelixarAi/memory",
43
+ "files": [
44
+ "dist",
45
+ "README.md",
46
+ "LICENSE",
47
+ "server.json"
48
+ ]
33
49
  }
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/VelixarAi/velixar-mcp-server",
7
7
  "source": "github"
8
8
  },
9
- "version": "0.2.4",
9
+ "version": "1.2.0",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "velixar-mcp-server",
14
- "version": "0.2.4",
14
+ "version": "1.2.0",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },
@@ -1,18 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches: [main]
6
- pull_request:
7
- branches: [main]
8
-
9
- jobs:
10
- test:
11
- runs-on: ubuntu-latest
12
- steps:
13
- - uses: actions/checkout@v4
14
- - uses: actions/setup-node@v4
15
- with:
16
- node-version: 20
17
- - run: npm ci
18
- - run: npm test
@@ -1 +0,0 @@
1
- ghu_XyGugN45ZtrH33LuAhQ1pyng0FurMx1rrj9m
@@ -1 +0,0 @@
1
- {"token":"eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJtY3AtcmVnaXN0cnkiLCJleHAiOjE3NzIyNDkxNDYsIm5iZiI6MTc3MjI0ODg0NiwiaWF0IjoxNzcyMjQ4ODQ2LCJhdXRoX21ldGhvZCI6ImdpdGh1Yi1hdCIsImF1dGhfbWV0aG9kX3N1YiI6IlZlbGl4YXJBaSIsInBlcm1pc3Npb25zIjpbeyJhY3Rpb24iOiJwdWJsaXNoIiwicmVzb3VyY2UiOiJpby5naXRodWIuVmVsaXhhckFpLyoifV19.g4eVEiRuPpPq2ruohLN_rZCCDeyFz0VI7TeLfEcPbL5StDOz8FVCK7B9pfVLTqVY09NmRbkSuPbcjOASHzrhDg","expires_at":1772249146}
package/src/index.js DELETED
@@ -1,262 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import {
5
- CallToolRequestSchema,
6
- ListToolsRequestSchema,
7
- ListResourcesRequestSchema,
8
- ReadResourceRequestSchema,
9
- } from "@modelcontextprotocol/sdk/types.js";
10
-
11
- const API_KEY = process.env.VELIXAR_API_KEY;
12
- const API_BASE = process.env.VELIXAR_API_URL || "https://api.velixarai.com";
13
- const USER_ID = process.env.VELIXAR_USER_ID || "mcp-user";
14
- const AUTO_RECALL = process.env.VELIXAR_AUTO_RECALL !== "false"; // on by default
15
- const RECALL_LIMIT = parseInt(process.env.VELIXAR_RECALL_LIMIT || "10", 10);
16
- const TIMEOUT_MS = 30000; // Increased from 15s to match Lambda timeout
17
-
18
- if (!API_KEY) {
19
- console.error("VELIXAR_API_KEY environment variable required");
20
- process.exit(1);
21
- }
22
-
23
- async function apiRequest(path, options = {}) {
24
- const controller = new AbortController();
25
- const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
26
- try {
27
- const res = await fetch(`${API_BASE}${path}`, {
28
- ...options,
29
- signal: controller.signal,
30
- headers: {
31
- "authorization": `Bearer ${API_KEY}`,
32
- "Content-Type": "application/json",
33
- ...options.headers,
34
- },
35
- });
36
- if (!res.ok) {
37
- const body = await res.text().catch(() => "");
38
- throw new Error(`API ${res.status}: ${body.slice(0, 200)}`);
39
- }
40
- return res.json();
41
- } catch (e) {
42
- if (e.name === "AbortError") throw new Error(`API timeout after ${TIMEOUT_MS}ms`);
43
- throw e;
44
- } finally {
45
- clearTimeout(timer);
46
- }
47
- }
48
-
49
- const server = new Server(
50
- { name: "velixar-mcp-server", version: "0.2.4" },
51
- { capabilities: { tools: {}, resources: {} } }
52
- );
53
-
54
- // ── Auto-recall: expose recent memories as a resource ──
55
-
56
- let _recalledMemories = null;
57
-
58
- async function fetchRecall() {
59
- if (!AUTO_RECALL) return;
60
- try {
61
- const params = new URLSearchParams({ user_id: USER_ID, limit: String(RECALL_LIMIT) });
62
- const result = await apiRequest(`/memory/list?${params}`);
63
- _recalledMemories = result.memories || [];
64
- } catch {
65
- _recalledMemories = [];
66
- }
67
- }
68
-
69
- // Fetch on startup (non-blocking)
70
- fetchRecall();
71
-
72
- server.setRequestHandler(ListResourcesRequestSchema, async () => {
73
- if (!AUTO_RECALL || !_recalledMemories?.length) return { resources: [] };
74
- return {
75
- resources: [{
76
- uri: "velixar://memories/recent",
77
- name: "Velixar — Recent Memories",
78
- description: `${_recalledMemories.length} most recent memories from your Velixar memory store`,
79
- mimeType: "text/plain",
80
- }],
81
- };
82
- });
83
-
84
- server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
85
- if (request.params.uri === "velixar://memories/recent") {
86
- if (!_recalledMemories) await fetchRecall();
87
- const text = (_recalledMemories || []).map((m) => {
88
- const tags = m.tags?.length ? ` [${m.tags.join(", ")}]` : "";
89
- const tier = m.tier != null ? ` (tier ${m.tier})` : "";
90
- return `${m.content}${tags}${tier}`;
91
- }).join("\n---\n");
92
- return {
93
- contents: [{
94
- uri: "velixar://memories/recent",
95
- mimeType: "text/plain",
96
- text: text || "No memories found.",
97
- }],
98
- };
99
- }
100
- throw new Error(`Unknown resource: ${request.params.uri}`);
101
- });
102
-
103
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
104
- tools: [
105
- {
106
- name: "velixar_store",
107
- description: "Store a memory for later retrieval. Use for important facts, user preferences, project context, or anything worth remembering.",
108
- inputSchema: {
109
- type: "object",
110
- properties: {
111
- content: { type: "string", description: "The memory content to store" },
112
- tags: { type: "array", items: { type: "string" }, description: "Optional tags for categorization" },
113
- tier: { type: "number", description: "Memory tier: 0=pinned, 1=session, 2=semantic (default), 3=org" },
114
- },
115
- required: ["content"],
116
- },
117
- },
118
- {
119
- name: "velixar_search",
120
- description: "Search stored memories by semantic similarity. Use to recall past context, preferences, or facts.",
121
- inputSchema: {
122
- type: "object",
123
- properties: {
124
- query: { type: "string", description: "Search query" },
125
- limit: { type: "number", description: "Max results (default 5)" },
126
- },
127
- required: ["query"],
128
- },
129
- },
130
- {
131
- name: "velixar_delete",
132
- description: "Delete a memory by ID. Use velixar_list to find memory IDs first.",
133
- inputSchema: {
134
- type: "object",
135
- properties: {
136
- id: { type: "string", description: "Memory ID to delete" },
137
- },
138
- required: ["id"],
139
- },
140
- },
141
- {
142
- name: "velixar_list",
143
- description: "List memories with pagination. Returns full metadata including IDs, tags, salience, and timestamps.",
144
- inputSchema: {
145
- type: "object",
146
- properties: {
147
- limit: { type: "number", description: "Max results (default 10)" },
148
- cursor: { type: "string", description: "Pagination cursor from previous response" },
149
- },
150
- required: [],
151
- },
152
- },
153
- {
154
- name: "velixar_update",
155
- description: "Update an existing memory's content or tags. Use velixar_list to find memory IDs first.",
156
- inputSchema: {
157
- type: "object",
158
- properties: {
159
- id: { type: "string", description: "Memory ID to update" },
160
- content: { type: "string", description: "New content" },
161
- tags: { type: "array", items: { type: "string" }, description: "New tags" },
162
- },
163
- required: ["id"],
164
- },
165
- },
166
- ],
167
- }));
168
-
169
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
170
- const { name, arguments: args } = request.params;
171
-
172
- try {
173
- if (name === "velixar_store") {
174
- const result = await apiRequest("/memory", {
175
- method: "POST",
176
- body: JSON.stringify({
177
- content: args.content,
178
- user_id: USER_ID,
179
- tier: args.tier ?? 2,
180
- tags: args.tags || [],
181
- }),
182
- });
183
- if (result.error) throw new Error(result.error);
184
- if (!result.id) throw new Error("Store succeeded but no ID returned");
185
- return { content: [{ type: "text", text: `✓ Stored memory (id: ${result.id})` }] };
186
- }
187
-
188
- if (name === "velixar_search") {
189
- const params = new URLSearchParams({ q: args.query, user_id: USER_ID });
190
- if (args.limit) params.set("limit", String(args.limit));
191
- const result = await apiRequest(`/memory/search?${params}`);
192
- if (result.error) throw new Error(result.error);
193
-
194
- if (!result.memories?.length) {
195
- return { content: [{ type: "text", text: "No memories found." }] };
196
- }
197
- const memories = result.memories.map((m) =>
198
- `• ${m.content}${m.score ? ` (score: ${m.score})` : ""}`
199
- ).join("\n");
200
- return { content: [{ type: "text", text: `Found ${result.count} memories:\n${memories}` }] };
201
- }
202
-
203
- if (name === "velixar_delete") {
204
- const result = await apiRequest(`/memory/${args.id}`, { method: "DELETE" });
205
- if (result.error) throw new Error(result.error);
206
- return { content: [{ type: "text", text: `✓ Deleted memory: ${args.id}` }] };
207
- }
208
-
209
- if (name === "velixar_list") {
210
- const params = new URLSearchParams({ user_id: USER_ID });
211
- if (args.limit) params.set("limit", String(args.limit));
212
- if (args.cursor) params.set("cursor", args.cursor);
213
- const result = await apiRequest(`/memory/list?${params}`);
214
- if (result.error) throw new Error(result.error);
215
-
216
- if (!result.memories?.length) {
217
- return { content: [{ type: "text", text: "No memories found." }] };
218
- }
219
- const memories = result.memories.map((m) => {
220
- const tags = m.tags?.length ? ` [${m.tags.join(", ")}]` : "";
221
- const preview = m.content.length > 120 ? m.content.substring(0, 120) + "…" : m.content;
222
- return `• ${m.id}: ${preview}${tags}`;
223
- }).join("\n");
224
- const cursor = result.cursor ? `\nNext cursor: ${result.cursor}` : "";
225
- return { content: [{ type: "text", text: `${result.count} memories:${cursor}\n${memories}` }] };
226
- }
227
-
228
- if (name === "velixar_update") {
229
- const body = { user_id: USER_ID };
230
- if (args.content) body.content = args.content;
231
- if (args.tags) body.tags = args.tags;
232
- const result = await apiRequest(`/memory/${args.id}`, {
233
- method: "PATCH",
234
- body: JSON.stringify(body),
235
- });
236
- if (result.error) throw new Error(result.error);
237
- return { content: [{ type: "text", text: `✓ Updated memory: ${args.id}` }] };
238
- }
239
-
240
- return {
241
- content: [{
242
- type: "text",
243
- text: `Unknown tool: ${name}\n\nNote: Velixar MCP tools are only available in the primary agent context. If you're seeing this in a subagent, memory operations must be handled by the primary agent.`
244
- }],
245
- isError: true
246
- };
247
- } catch (error) {
248
- const helpText = error.message.includes("tool") || error.message.includes("not found")
249
- ? "\n\nNote: Velixar MCP tools are only available in the primary agent context. If you're using subagents, handle memory operations in the primary agent before/after delegating other tasks."
250
- : "";
251
- return {
252
- content: [{
253
- type: "text",
254
- text: `Error: ${error.message}${helpText}`
255
- }],
256
- isError: true
257
- };
258
- }
259
- });
260
-
261
- const transport = new StdioServerTransport();
262
- await server.connect(transport);
@@ -1,193 +0,0 @@
1
- import { test, describe, beforeEach } from "node:test";
2
- import assert from "node:assert";
3
-
4
- // Capture the last fetch call for assertions
5
- let lastFetch = {};
6
- let mockResponse = {};
7
-
8
- global.fetch = async (url, options) => {
9
- lastFetch = { url, options };
10
- const path = url.replace(/^.*\/v1/, "").split("?")[0];
11
- const resp = mockResponse[path] || {};
12
- return {
13
- ok: resp._fail ? false : true,
14
- status: resp._fail ? 500 : 200,
15
- json: async () => resp,
16
- text: async () => JSON.stringify(resp),
17
- };
18
- };
19
-
20
- process.env.VELIXAR_API_KEY = "test-key";
21
- process.env.VELIXAR_USER_ID = "test-user";
22
-
23
- // Import the handler by extracting it from the server
24
- // Since index.js connects to stdio on import, we test the logic via API calls
25
- // These tests validate the request/response contract
26
-
27
- describe("velixar_store", () => {
28
- test("sends correct POST body", async () => {
29
- mockResponse = { "/memory": { id: "abc-123", stored: true } };
30
- const handler = makeHandler("velixar_store", { content: "test fact", tags: ["a"], tier: 0 });
31
- const result = await handler();
32
- assert.ok(lastFetch.url.endsWith("/memory"));
33
- const body = JSON.parse(lastFetch.options.body);
34
- assert.strictEqual(body.content, "test fact");
35
- assert.strictEqual(body.tier, 0);
36
- assert.deepStrictEqual(body.tags, ["a"]);
37
- assert.strictEqual(body.user_id, "test-user");
38
- });
39
-
40
- test("tier defaults to 2 when omitted", async () => {
41
- mockResponse = { "/memory": { id: "abc-123", stored: true } };
42
- const handler = makeHandler("velixar_store", { content: "test" });
43
- await handler();
44
- const body = JSON.parse(lastFetch.options.body);
45
- assert.strictEqual(body.tier, 2);
46
- });
47
-
48
- test("tier 0 is allowed (not coerced to default)", async () => {
49
- mockResponse = { "/memory": { id: "abc-123", stored: true } };
50
- const handler = makeHandler("velixar_store", { content: "pinned", tier: 0 });
51
- await handler();
52
- const body = JSON.parse(lastFetch.options.body);
53
- assert.strictEqual(body.tier, 0);
54
- });
55
- });
56
-
57
- describe("velixar_search", () => {
58
- test("passes query and limit as URL params", async () => {
59
- mockResponse = { "/memory/search": { memories: [{ content: "found it" }], count: 1 } };
60
- const handler = makeHandler("velixar_search", { query: "test query", limit: 3 });
61
- await handler();
62
- assert.ok(lastFetch.url.includes("q=test+query") || lastFetch.url.includes("q=test%20query"));
63
- assert.ok(lastFetch.url.includes("limit=3"));
64
- });
65
-
66
- test("returns 'No memories found' when empty", async () => {
67
- mockResponse = { "/memory/search": { memories: [], count: 0 } };
68
- const handler = makeHandler("velixar_search", { query: "nothing" });
69
- const result = await handler();
70
- assert.strictEqual(result.text, "No memories found.");
71
- });
72
- });
73
-
74
- describe("velixar_list", () => {
75
- test("passes cursor for pagination", async () => {
76
- mockResponse = { "/memory/list": { memories: [{ id: "x", content: "hi", tags: [] }], count: 1 } };
77
- const handler = makeHandler("velixar_list", { limit: 5, cursor: "abc" });
78
- await handler();
79
- assert.ok(lastFetch.url.includes("cursor=abc"));
80
- assert.ok(lastFetch.url.includes("limit=5"));
81
- });
82
-
83
- test("returns 'No memories found' when empty", async () => {
84
- mockResponse = { "/memory/list": { memories: [], count: 0 } };
85
- const handler = makeHandler("velixar_list", {});
86
- const result = await handler();
87
- assert.strictEqual(result.text, "No memories found.");
88
- });
89
- });
90
-
91
- describe("velixar_update", () => {
92
- test("sends PATCH with content and tags", async () => {
93
- mockResponse = { "/memory/up-123": { updated: true } };
94
- const handler = makeHandler("velixar_update", { id: "up-123", content: "new", tags: ["x"] });
95
- await handler();
96
- assert.ok(lastFetch.url.includes("/memory/up-123"));
97
- assert.strictEqual(lastFetch.options.method, "PATCH");
98
- const body = JSON.parse(lastFetch.options.body);
99
- assert.strictEqual(body.content, "new");
100
- assert.deepStrictEqual(body.tags, ["x"]);
101
- });
102
- });
103
-
104
- describe("velixar_delete", () => {
105
- test("sends DELETE to correct URL", async () => {
106
- mockResponse = { "/memory/del-456": { deleted: true } };
107
- const handler = makeHandler("velixar_delete", { id: "del-456" });
108
- await handler();
109
- assert.ok(lastFetch.url.includes("/memory/del-456"));
110
- assert.strictEqual(lastFetch.options.method, "DELETE");
111
- });
112
- });
113
-
114
- describe("error handling", () => {
115
- test("returns isError on API error response", async () => {
116
- mockResponse = { "/memory": { error: "bad request" } };
117
- const handler = makeHandler("velixar_store", { content: "fail" });
118
- const result = await handler();
119
- assert.ok(result.text.includes("Error:"));
120
- assert.strictEqual(result.isError, true);
121
- });
122
- });
123
-
124
- // Helper: simulates the CallTool handler logic from index.js
125
- // This mirrors the actual handler without needing stdio transport
126
- function makeHandler(name, args) {
127
- const API_BASE = "https://api.velixarai.com";
128
- const API_KEY = process.env.VELIXAR_API_KEY;
129
- const USER_ID = process.env.VELIXAR_USER_ID;
130
-
131
- async function apiRequest(path, options = {}) {
132
- const res = await fetch(`${API_BASE}${path}`, {
133
- ...options,
134
- headers: { authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", ...options.headers },
135
- });
136
- if (!res.ok) { const body = await res.text().catch(() => ""); throw new Error(`API ${res.status}: ${body.slice(0, 200)}`); }
137
- return res.json();
138
- }
139
-
140
- return async () => {
141
- try {
142
- if (name === "velixar_store") {
143
- const result = await apiRequest("/memory", {
144
- method: "POST",
145
- body: JSON.stringify({ content: args.content, user_id: USER_ID, tier: args.tier ?? 2, tags: args.tags || [] }),
146
- });
147
- if (result.error) throw new Error(result.error);
148
- if (!result.id) throw new Error("Store succeeded but no ID returned");
149
- return { text: `✓ Stored memory (id: ${result.id})` };
150
- }
151
- if (name === "velixar_search") {
152
- const params = new URLSearchParams({ q: args.query, user_id: USER_ID });
153
- if (args.limit) params.set("limit", String(args.limit));
154
- const result = await apiRequest(`/memory/search?${params}`);
155
- if (result.error) throw new Error(result.error);
156
- if (!result.memories?.length) return { text: "No memories found." };
157
- const memories = result.memories.map((m) => `• ${m.content}${m.score ? ` (score: ${m.score})` : ""}`).join("\n");
158
- return { text: `Found ${result.count} memories:\n${memories}` };
159
- }
160
- if (name === "velixar_delete") {
161
- const result = await apiRequest(`/memory/${args.id}`, { method: "DELETE" });
162
- if (result.error) throw new Error(result.error);
163
- return { text: `✓ Deleted memory: ${args.id}` };
164
- }
165
- if (name === "velixar_list") {
166
- const params = new URLSearchParams({ user_id: USER_ID });
167
- if (args.limit) params.set("limit", String(args.limit));
168
- if (args.cursor) params.set("cursor", args.cursor);
169
- const result = await apiRequest(`/memory/list?${params}`);
170
- if (result.error) throw new Error(result.error);
171
- if (!result.memories?.length) return { text: "No memories found." };
172
- const memories = result.memories.map((m) => {
173
- const tags = m.tags?.length ? ` [${m.tags.join(", ")}]` : "";
174
- const preview = m.content.length > 120 ? m.content.substring(0, 120) + "…" : m.content;
175
- return `• ${m.id}: ${preview}${tags}`;
176
- }).join("\n");
177
- const cursor = result.cursor ? `\nNext cursor: ${result.cursor}` : "";
178
- return { text: `${result.count} memories:${cursor}\n${memories}` };
179
- }
180
- if (name === "velixar_update") {
181
- const body = { user_id: USER_ID };
182
- if (args.content) body.content = args.content;
183
- if (args.tags) body.tags = args.tags;
184
- const result = await apiRequest(`/memory/${args.id}`, { method: "PATCH", body: JSON.stringify(body) });
185
- if (result.error) throw new Error(result.error);
186
- return { text: `✓ Updated memory: ${args.id}` };
187
- }
188
- return { text: `Unknown tool: ${name}`, isError: true };
189
- } catch (error) {
190
- return { text: `Error: ${error.message}`, isError: true };
191
- }
192
- };
193
- }