harmony-mcp 1.9.0 → 1.9.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.
Files changed (3) hide show
  1. package/dist/cli.js +206 -14
  2. package/dist/index.js +206 -14
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -30216,37 +30216,50 @@ class HarmonyApiClient {
30216
30216
  this.apiKey = getApiKey();
30217
30217
  this.apiUrl = getApiUrl();
30218
30218
  }
30219
- async request(method, path, body) {
30219
+ async request(method, path, body, options) {
30220
30220
  await requestSemaphore.acquire();
30221
30221
  try {
30222
- return await this.requestWithRetry(method, path, body);
30222
+ return await this.requestWithRetry(method, path, body, options);
30223
30223
  } finally {
30224
30224
  requestSemaphore.release();
30225
30225
  }
30226
30226
  }
30227
- async requestWithRetry(method, path, body) {
30227
+ async requestRaw(method, path, body, options) {
30228
+ await requestSemaphore.acquire();
30229
+ try {
30230
+ return await this.requestRawWithRetry(method, path, body, options);
30231
+ } finally {
30232
+ requestSemaphore.release();
30233
+ }
30234
+ }
30235
+ async requestWithRetry(method, path, body, options) {
30228
30236
  const url2 = `${this.apiUrl}/v1${path}`;
30229
30237
  let lastError = null;
30238
+ const contentType = options?.contentType || "application/json";
30239
+ const accept = options?.accept || "application/json";
30230
30240
  for (let attempt = 0;attempt <= RETRY_CONFIG.maxRetries; attempt++) {
30231
30241
  try {
30232
30242
  const response = await fetch(url2, {
30233
30243
  method,
30234
30244
  headers: {
30235
- "Content-Type": "application/json",
30245
+ "Content-Type": contentType,
30246
+ Accept: accept,
30236
30247
  "X-API-Key": this.apiKey
30237
30248
  },
30238
- body: body ? JSON.stringify(body) : undefined
30249
+ body: options?.rawBody ?? (body ? JSON.stringify(body) : undefined)
30239
30250
  });
30240
30251
  const data = await response.json();
30241
30252
  if (!response.ok) {
30253
+ const errorMsg = data.error || `API error: ${response.status}`;
30242
30254
  if (!isRetryableError(null, response.status)) {
30243
- throw new Error(data.error || `API error: ${response.status}`);
30255
+ throw new Error(errorMsg);
30244
30256
  }
30245
- lastError = new Error(data.error || `API error: ${response.status}`);
30257
+ lastError = new Error(errorMsg);
30246
30258
  if (attempt < RETRY_CONFIG.maxRetries) {
30247
30259
  await sleep(getRetryDelay(attempt));
30248
30260
  continue;
30249
30261
  }
30262
+ throw lastError;
30250
30263
  }
30251
30264
  return data;
30252
30265
  } catch (error48) {
@@ -30261,6 +30274,53 @@ class HarmonyApiClient {
30261
30274
  }
30262
30275
  throw lastError || new Error("Request failed after retries");
30263
30276
  }
30277
+ async requestRawWithRetry(method, path, body, options) {
30278
+ const url2 = `${this.apiUrl}/v1${path}`;
30279
+ let lastError = null;
30280
+ const contentType = options?.contentType || "application/json";
30281
+ const accept = options?.accept || "text/markdown";
30282
+ for (let attempt = 0;attempt <= RETRY_CONFIG.maxRetries; attempt++) {
30283
+ try {
30284
+ const response = await fetch(url2, {
30285
+ method,
30286
+ headers: {
30287
+ "Content-Type": contentType,
30288
+ Accept: accept,
30289
+ "X-API-Key": this.apiKey
30290
+ },
30291
+ body: options?.rawBody ?? (body ? JSON.stringify(body) : undefined)
30292
+ });
30293
+ if (!response.ok) {
30294
+ const text = await response.text();
30295
+ let errorMsg;
30296
+ try {
30297
+ errorMsg = JSON.parse(text).error || `API error: ${response.status}`;
30298
+ } catch {
30299
+ errorMsg = text || `API error: ${response.status}`;
30300
+ }
30301
+ if (!isRetryableError(null, response.status)) {
30302
+ throw new Error(errorMsg);
30303
+ }
30304
+ lastError = new Error(errorMsg);
30305
+ if (attempt < RETRY_CONFIG.maxRetries) {
30306
+ await sleep(getRetryDelay(attempt));
30307
+ continue;
30308
+ }
30309
+ throw lastError;
30310
+ }
30311
+ return await response.text();
30312
+ } catch (error48) {
30313
+ lastError = error48 instanceof Error ? error48 : new Error(String(error48));
30314
+ if (!isRetryableError(error48))
30315
+ throw lastError;
30316
+ if (attempt < RETRY_CONFIG.maxRetries) {
30317
+ await sleep(getRetryDelay(attempt));
30318
+ continue;
30319
+ }
30320
+ }
30321
+ }
30322
+ throw lastError || new Error("Request failed after retries");
30323
+ }
30264
30324
  async listWorkspaces() {
30265
30325
  return this.request("GET", "/workspaces");
30266
30326
  }
@@ -30422,6 +30482,50 @@ class HarmonyApiClient {
30422
30482
  params.set("limit", String(options.limit));
30423
30483
  return this.request("GET", `/memory/search?${params.toString()}`);
30424
30484
  }
30485
+ async listMemoryEntitiesMarkdown(options) {
30486
+ const params = new URLSearchParams;
30487
+ params.set("workspace_id", options.workspace_id);
30488
+ if (options.project_id)
30489
+ params.set("project_id", options.project_id);
30490
+ if (options.type)
30491
+ params.set("type", options.type);
30492
+ if (options.scope)
30493
+ params.set("scope", options.scope);
30494
+ if (options.tags?.length)
30495
+ params.set("tags", options.tags.join(","));
30496
+ if (options.agent_identifier)
30497
+ params.set("agent_identifier", options.agent_identifier);
30498
+ if (options.min_confidence !== undefined)
30499
+ params.set("min_confidence", String(options.min_confidence));
30500
+ if (options.q)
30501
+ params.set("q", options.q);
30502
+ if (options.limit !== undefined)
30503
+ params.set("limit", String(options.limit));
30504
+ if (options.offset !== undefined)
30505
+ params.set("offset", String(options.offset));
30506
+ return this.requestRaw("GET", `/memory/entities?${params.toString()}`, undefined, {
30507
+ accept: "text/markdown"
30508
+ });
30509
+ }
30510
+ async getMemoryEntityMarkdown(entityId) {
30511
+ return this.requestRaw("GET", `/memory/entities/${entityId}`, undefined, {
30512
+ accept: "text/markdown"
30513
+ });
30514
+ }
30515
+ async searchMemoryEntitiesMarkdown(workspaceId, query, options) {
30516
+ const params = new URLSearchParams;
30517
+ params.set("workspace_id", workspaceId);
30518
+ params.set("q", query);
30519
+ if (options?.project_id)
30520
+ params.set("project_id", options.project_id);
30521
+ if (options?.type)
30522
+ params.set("type", options.type);
30523
+ if (options?.limit !== undefined)
30524
+ params.set("limit", String(options.limit));
30525
+ return this.requestRaw("GET", `/memory/search?${params.toString()}`, undefined, {
30526
+ accept: "text/markdown"
30527
+ });
30528
+ }
30425
30529
  async processNLU(data) {
30426
30530
  return this.request("POST", "/nlu", data);
30427
30531
  }
@@ -31295,7 +31399,12 @@ var TOOLS = {
31295
31399
  "pattern",
31296
31400
  "error",
31297
31401
  "solution",
31298
- "preference"
31402
+ "preference",
31403
+ "relationship",
31404
+ "commitment",
31405
+ "lesson",
31406
+ "project",
31407
+ "handoff"
31299
31408
  ],
31300
31409
  description: "Entity type (default: context)"
31301
31410
  },
@@ -31344,7 +31453,12 @@ var TOOLS = {
31344
31453
  "pattern",
31345
31454
  "error",
31346
31455
  "solution",
31347
- "preference"
31456
+ "preference",
31457
+ "relationship",
31458
+ "commitment",
31459
+ "lesson",
31460
+ "project",
31461
+ "handoff"
31348
31462
  ],
31349
31463
  description: "Filter by entity type"
31350
31464
  },
@@ -31378,6 +31492,58 @@ var TOOLS = {
31378
31492
  }
31379
31493
  }
31380
31494
  },
31495
+ harmony_update_memory: {
31496
+ description: "Update an existing memory entity. Can change title, content, tags, confidence, scope, type, or metadata.",
31497
+ inputSchema: {
31498
+ type: "object",
31499
+ properties: {
31500
+ entityId: {
31501
+ type: "string",
31502
+ description: "Memory entity UUID to update"
31503
+ },
31504
+ title: { type: "string", description: "New title" },
31505
+ content: { type: "string", description: "New content (markdown body)" },
31506
+ type: {
31507
+ type: "string",
31508
+ enum: [
31509
+ "agent",
31510
+ "task",
31511
+ "decision",
31512
+ "context",
31513
+ "pattern",
31514
+ "error",
31515
+ "solution",
31516
+ "preference",
31517
+ "relationship",
31518
+ "commitment",
31519
+ "lesson",
31520
+ "project",
31521
+ "handoff"
31522
+ ],
31523
+ description: "New entity type"
31524
+ },
31525
+ scope: {
31526
+ type: "string",
31527
+ enum: ["private", "project", "workspace", "global"],
31528
+ description: "New visibility scope"
31529
+ },
31530
+ tags: {
31531
+ type: "array",
31532
+ items: { type: "string" },
31533
+ description: "New tags (replaces existing)"
31534
+ },
31535
+ confidence: {
31536
+ type: "number",
31537
+ description: "New confidence score 0-1"
31538
+ },
31539
+ metadata: {
31540
+ type: "object",
31541
+ description: "New metadata (merged with existing)"
31542
+ }
31543
+ },
31544
+ required: ["entityId"]
31545
+ }
31546
+ },
31381
31547
  harmony_forget: {
31382
31548
  description: "Archive or delete a memory entity by ID.",
31383
31549
  inputSchema: {
@@ -31444,7 +31610,12 @@ var TOOLS = {
31444
31610
  "pattern",
31445
31611
  "error",
31446
31612
  "solution",
31447
- "preference"
31613
+ "preference",
31614
+ "relationship",
31615
+ "commitment",
31616
+ "lesson",
31617
+ "project",
31618
+ "handoff"
31448
31619
  ],
31449
31620
  description: "Filter results by entity type"
31450
31621
  },
@@ -31567,8 +31738,9 @@ class HarmonyMCPServer {
31567
31738
  const { name, arguments: args } = request.params;
31568
31739
  try {
31569
31740
  const result = await this.handleToolCall(name, args || {});
31741
+ const text = typeof result === "string" ? result : JSON.stringify(result, null, 2);
31570
31742
  return {
31571
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
31743
+ content: [{ type: "text", text }]
31572
31744
  };
31573
31745
  } catch (error48) {
31574
31746
  return {
@@ -32035,7 +32207,7 @@ class HarmonyMCPServer {
32035
32207
  if (!workspaceId) {
32036
32208
  throw new Error("No workspace specified. Use harmony_set_workspace_context or provide workspaceId.");
32037
32209
  }
32038
- const result = await client2.listMemoryEntities({
32210
+ const markdown = await client2.listMemoryEntitiesMarkdown({
32039
32211
  workspace_id: workspaceId,
32040
32212
  project_id: args.projectId || getActiveProjectId() || undefined,
32041
32213
  type: args.type,
@@ -32045,6 +32217,26 @@ class HarmonyMCPServer {
32045
32217
  q: args.query,
32046
32218
  limit: args.limit
32047
32219
  });
32220
+ return markdown || "No memories found.";
32221
+ }
32222
+ case "harmony_update_memory": {
32223
+ const entityId = exports_external.string().uuid().parse(args.entityId);
32224
+ const updates = {};
32225
+ if (args.title !== undefined)
32226
+ updates.title = args.title;
32227
+ if (args.content !== undefined)
32228
+ updates.content = args.content;
32229
+ if (args.type !== undefined)
32230
+ updates.type = args.type;
32231
+ if (args.scope !== undefined)
32232
+ updates.scope = args.scope;
32233
+ if (args.tags !== undefined)
32234
+ updates.tags = args.tags;
32235
+ if (args.confidence !== undefined)
32236
+ updates.confidence = args.confidence;
32237
+ if (args.metadata !== undefined)
32238
+ updates.metadata = args.metadata;
32239
+ const result = await client2.updateMemoryEntity(entityId, updates);
32048
32240
  return { success: true, ...result };
32049
32241
  }
32050
32242
  case "harmony_forget": {
@@ -32078,12 +32270,12 @@ class HarmonyMCPServer {
32078
32270
  if (!workspaceId) {
32079
32271
  throw new Error("No workspace specified. Use harmony_set_workspace_context or provide workspaceId.");
32080
32272
  }
32081
- const result = await client2.searchMemoryEntities(workspaceId, query, {
32273
+ const markdown = await client2.searchMemoryEntitiesMarkdown(workspaceId, query, {
32082
32274
  project_id: args.projectId || getActiveProjectId() || undefined,
32083
32275
  type: args.type,
32084
32276
  limit: args.limit
32085
32277
  });
32086
- return { success: true, ...result };
32278
+ return markdown || "No memories found.";
32087
32279
  }
32088
32280
  case "harmony_create_plan": {
32089
32281
  const title = exports_external.string().min(1).parse(args.title);
package/dist/index.js CHANGED
@@ -27976,37 +27976,50 @@ class HarmonyApiClient {
27976
27976
  this.apiKey = getApiKey();
27977
27977
  this.apiUrl = getApiUrl();
27978
27978
  }
27979
- async request(method, path, body) {
27979
+ async request(method, path, body, options) {
27980
27980
  await requestSemaphore.acquire();
27981
27981
  try {
27982
- return await this.requestWithRetry(method, path, body);
27982
+ return await this.requestWithRetry(method, path, body, options);
27983
27983
  } finally {
27984
27984
  requestSemaphore.release();
27985
27985
  }
27986
27986
  }
27987
- async requestWithRetry(method, path, body) {
27987
+ async requestRaw(method, path, body, options) {
27988
+ await requestSemaphore.acquire();
27989
+ try {
27990
+ return await this.requestRawWithRetry(method, path, body, options);
27991
+ } finally {
27992
+ requestSemaphore.release();
27993
+ }
27994
+ }
27995
+ async requestWithRetry(method, path, body, options) {
27988
27996
  const url2 = `${this.apiUrl}/v1${path}`;
27989
27997
  let lastError = null;
27998
+ const contentType = options?.contentType || "application/json";
27999
+ const accept = options?.accept || "application/json";
27990
28000
  for (let attempt = 0;attempt <= RETRY_CONFIG.maxRetries; attempt++) {
27991
28001
  try {
27992
28002
  const response = await fetch(url2, {
27993
28003
  method,
27994
28004
  headers: {
27995
- "Content-Type": "application/json",
28005
+ "Content-Type": contentType,
28006
+ Accept: accept,
27996
28007
  "X-API-Key": this.apiKey
27997
28008
  },
27998
- body: body ? JSON.stringify(body) : undefined
28009
+ body: options?.rawBody ?? (body ? JSON.stringify(body) : undefined)
27999
28010
  });
28000
28011
  const data = await response.json();
28001
28012
  if (!response.ok) {
28013
+ const errorMsg = data.error || `API error: ${response.status}`;
28002
28014
  if (!isRetryableError(null, response.status)) {
28003
- throw new Error(data.error || `API error: ${response.status}`);
28015
+ throw new Error(errorMsg);
28004
28016
  }
28005
- lastError = new Error(data.error || `API error: ${response.status}`);
28017
+ lastError = new Error(errorMsg);
28006
28018
  if (attempt < RETRY_CONFIG.maxRetries) {
28007
28019
  await sleep(getRetryDelay(attempt));
28008
28020
  continue;
28009
28021
  }
28022
+ throw lastError;
28010
28023
  }
28011
28024
  return data;
28012
28025
  } catch (error48) {
@@ -28021,6 +28034,53 @@ class HarmonyApiClient {
28021
28034
  }
28022
28035
  throw lastError || new Error("Request failed after retries");
28023
28036
  }
28037
+ async requestRawWithRetry(method, path, body, options) {
28038
+ const url2 = `${this.apiUrl}/v1${path}`;
28039
+ let lastError = null;
28040
+ const contentType = options?.contentType || "application/json";
28041
+ const accept = options?.accept || "text/markdown";
28042
+ for (let attempt = 0;attempt <= RETRY_CONFIG.maxRetries; attempt++) {
28043
+ try {
28044
+ const response = await fetch(url2, {
28045
+ method,
28046
+ headers: {
28047
+ "Content-Type": contentType,
28048
+ Accept: accept,
28049
+ "X-API-Key": this.apiKey
28050
+ },
28051
+ body: options?.rawBody ?? (body ? JSON.stringify(body) : undefined)
28052
+ });
28053
+ if (!response.ok) {
28054
+ const text = await response.text();
28055
+ let errorMsg;
28056
+ try {
28057
+ errorMsg = JSON.parse(text).error || `API error: ${response.status}`;
28058
+ } catch {
28059
+ errorMsg = text || `API error: ${response.status}`;
28060
+ }
28061
+ if (!isRetryableError(null, response.status)) {
28062
+ throw new Error(errorMsg);
28063
+ }
28064
+ lastError = new Error(errorMsg);
28065
+ if (attempt < RETRY_CONFIG.maxRetries) {
28066
+ await sleep(getRetryDelay(attempt));
28067
+ continue;
28068
+ }
28069
+ throw lastError;
28070
+ }
28071
+ return await response.text();
28072
+ } catch (error48) {
28073
+ lastError = error48 instanceof Error ? error48 : new Error(String(error48));
28074
+ if (!isRetryableError(error48))
28075
+ throw lastError;
28076
+ if (attempt < RETRY_CONFIG.maxRetries) {
28077
+ await sleep(getRetryDelay(attempt));
28078
+ continue;
28079
+ }
28080
+ }
28081
+ }
28082
+ throw lastError || new Error("Request failed after retries");
28083
+ }
28024
28084
  async listWorkspaces() {
28025
28085
  return this.request("GET", "/workspaces");
28026
28086
  }
@@ -28182,6 +28242,50 @@ class HarmonyApiClient {
28182
28242
  params.set("limit", String(options.limit));
28183
28243
  return this.request("GET", `/memory/search?${params.toString()}`);
28184
28244
  }
28245
+ async listMemoryEntitiesMarkdown(options) {
28246
+ const params = new URLSearchParams;
28247
+ params.set("workspace_id", options.workspace_id);
28248
+ if (options.project_id)
28249
+ params.set("project_id", options.project_id);
28250
+ if (options.type)
28251
+ params.set("type", options.type);
28252
+ if (options.scope)
28253
+ params.set("scope", options.scope);
28254
+ if (options.tags?.length)
28255
+ params.set("tags", options.tags.join(","));
28256
+ if (options.agent_identifier)
28257
+ params.set("agent_identifier", options.agent_identifier);
28258
+ if (options.min_confidence !== undefined)
28259
+ params.set("min_confidence", String(options.min_confidence));
28260
+ if (options.q)
28261
+ params.set("q", options.q);
28262
+ if (options.limit !== undefined)
28263
+ params.set("limit", String(options.limit));
28264
+ if (options.offset !== undefined)
28265
+ params.set("offset", String(options.offset));
28266
+ return this.requestRaw("GET", `/memory/entities?${params.toString()}`, undefined, {
28267
+ accept: "text/markdown"
28268
+ });
28269
+ }
28270
+ async getMemoryEntityMarkdown(entityId) {
28271
+ return this.requestRaw("GET", `/memory/entities/${entityId}`, undefined, {
28272
+ accept: "text/markdown"
28273
+ });
28274
+ }
28275
+ async searchMemoryEntitiesMarkdown(workspaceId, query, options) {
28276
+ const params = new URLSearchParams;
28277
+ params.set("workspace_id", workspaceId);
28278
+ params.set("q", query);
28279
+ if (options?.project_id)
28280
+ params.set("project_id", options.project_id);
28281
+ if (options?.type)
28282
+ params.set("type", options.type);
28283
+ if (options?.limit !== undefined)
28284
+ params.set("limit", String(options.limit));
28285
+ return this.requestRaw("GET", `/memory/search?${params.toString()}`, undefined, {
28286
+ accept: "text/markdown"
28287
+ });
28288
+ }
28185
28289
  async processNLU(data) {
28186
28290
  return this.request("POST", "/nlu", data);
28187
28291
  }
@@ -29055,7 +29159,12 @@ var TOOLS = {
29055
29159
  "pattern",
29056
29160
  "error",
29057
29161
  "solution",
29058
- "preference"
29162
+ "preference",
29163
+ "relationship",
29164
+ "commitment",
29165
+ "lesson",
29166
+ "project",
29167
+ "handoff"
29059
29168
  ],
29060
29169
  description: "Entity type (default: context)"
29061
29170
  },
@@ -29104,7 +29213,12 @@ var TOOLS = {
29104
29213
  "pattern",
29105
29214
  "error",
29106
29215
  "solution",
29107
- "preference"
29216
+ "preference",
29217
+ "relationship",
29218
+ "commitment",
29219
+ "lesson",
29220
+ "project",
29221
+ "handoff"
29108
29222
  ],
29109
29223
  description: "Filter by entity type"
29110
29224
  },
@@ -29138,6 +29252,58 @@ var TOOLS = {
29138
29252
  }
29139
29253
  }
29140
29254
  },
29255
+ harmony_update_memory: {
29256
+ description: "Update an existing memory entity. Can change title, content, tags, confidence, scope, type, or metadata.",
29257
+ inputSchema: {
29258
+ type: "object",
29259
+ properties: {
29260
+ entityId: {
29261
+ type: "string",
29262
+ description: "Memory entity UUID to update"
29263
+ },
29264
+ title: { type: "string", description: "New title" },
29265
+ content: { type: "string", description: "New content (markdown body)" },
29266
+ type: {
29267
+ type: "string",
29268
+ enum: [
29269
+ "agent",
29270
+ "task",
29271
+ "decision",
29272
+ "context",
29273
+ "pattern",
29274
+ "error",
29275
+ "solution",
29276
+ "preference",
29277
+ "relationship",
29278
+ "commitment",
29279
+ "lesson",
29280
+ "project",
29281
+ "handoff"
29282
+ ],
29283
+ description: "New entity type"
29284
+ },
29285
+ scope: {
29286
+ type: "string",
29287
+ enum: ["private", "project", "workspace", "global"],
29288
+ description: "New visibility scope"
29289
+ },
29290
+ tags: {
29291
+ type: "array",
29292
+ items: { type: "string" },
29293
+ description: "New tags (replaces existing)"
29294
+ },
29295
+ confidence: {
29296
+ type: "number",
29297
+ description: "New confidence score 0-1"
29298
+ },
29299
+ metadata: {
29300
+ type: "object",
29301
+ description: "New metadata (merged with existing)"
29302
+ }
29303
+ },
29304
+ required: ["entityId"]
29305
+ }
29306
+ },
29141
29307
  harmony_forget: {
29142
29308
  description: "Archive or delete a memory entity by ID.",
29143
29309
  inputSchema: {
@@ -29204,7 +29370,12 @@ var TOOLS = {
29204
29370
  "pattern",
29205
29371
  "error",
29206
29372
  "solution",
29207
- "preference"
29373
+ "preference",
29374
+ "relationship",
29375
+ "commitment",
29376
+ "lesson",
29377
+ "project",
29378
+ "handoff"
29208
29379
  ],
29209
29380
  description: "Filter results by entity type"
29210
29381
  },
@@ -29327,8 +29498,9 @@ class HarmonyMCPServer {
29327
29498
  const { name, arguments: args } = request.params;
29328
29499
  try {
29329
29500
  const result = await this.handleToolCall(name, args || {});
29501
+ const text = typeof result === "string" ? result : JSON.stringify(result, null, 2);
29330
29502
  return {
29331
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
29503
+ content: [{ type: "text", text }]
29332
29504
  };
29333
29505
  } catch (error48) {
29334
29506
  return {
@@ -29795,7 +29967,7 @@ class HarmonyMCPServer {
29795
29967
  if (!workspaceId) {
29796
29968
  throw new Error("No workspace specified. Use harmony_set_workspace_context or provide workspaceId.");
29797
29969
  }
29798
- const result = await client2.listMemoryEntities({
29970
+ const markdown = await client2.listMemoryEntitiesMarkdown({
29799
29971
  workspace_id: workspaceId,
29800
29972
  project_id: args.projectId || getActiveProjectId() || undefined,
29801
29973
  type: args.type,
@@ -29805,6 +29977,26 @@ class HarmonyMCPServer {
29805
29977
  q: args.query,
29806
29978
  limit: args.limit
29807
29979
  });
29980
+ return markdown || "No memories found.";
29981
+ }
29982
+ case "harmony_update_memory": {
29983
+ const entityId = exports_external.string().uuid().parse(args.entityId);
29984
+ const updates = {};
29985
+ if (args.title !== undefined)
29986
+ updates.title = args.title;
29987
+ if (args.content !== undefined)
29988
+ updates.content = args.content;
29989
+ if (args.type !== undefined)
29990
+ updates.type = args.type;
29991
+ if (args.scope !== undefined)
29992
+ updates.scope = args.scope;
29993
+ if (args.tags !== undefined)
29994
+ updates.tags = args.tags;
29995
+ if (args.confidence !== undefined)
29996
+ updates.confidence = args.confidence;
29997
+ if (args.metadata !== undefined)
29998
+ updates.metadata = args.metadata;
29999
+ const result = await client2.updateMemoryEntity(entityId, updates);
29808
30000
  return { success: true, ...result };
29809
30001
  }
29810
30002
  case "harmony_forget": {
@@ -29838,12 +30030,12 @@ class HarmonyMCPServer {
29838
30030
  if (!workspaceId) {
29839
30031
  throw new Error("No workspace specified. Use harmony_set_workspace_context or provide workspaceId.");
29840
30032
  }
29841
- const result = await client2.searchMemoryEntities(workspaceId, query, {
30033
+ const markdown = await client2.searchMemoryEntitiesMarkdown(workspaceId, query, {
29842
30034
  project_id: args.projectId || getActiveProjectId() || undefined,
29843
30035
  type: args.type,
29844
30036
  limit: args.limit
29845
30037
  });
29846
- return { success: true, ...result };
30038
+ return markdown || "No memories found.";
29847
30039
  }
29848
30040
  case "harmony_create_plan": {
29849
30041
  const title = exports_external.string().min(1).parse(args.title);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "harmony-mcp",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
4
4
  "description": "MCP server for Harmony Kanban board - enables AI coding agents to manage your boards",
5
5
  "publishConfig": {
6
6
  "access": "public"