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.
- package/dist/cli.js +206 -14
- package/dist/index.js +206 -14
- 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
|
|
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":
|
|
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(
|
|
30255
|
+
throw new Error(errorMsg);
|
|
30244
30256
|
}
|
|
30245
|
-
lastError = new Error(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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":
|
|
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(
|
|
28015
|
+
throw new Error(errorMsg);
|
|
28004
28016
|
}
|
|
28005
|
-
lastError = new Error(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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);
|