@gethmy/mcp 2.3.4 → 2.4.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/src/server.ts CHANGED
@@ -58,7 +58,12 @@ import {
58
58
  } from "./context-assembly.js";
59
59
  import { autoExpandGraph } from "./graph-expansion.js";
60
60
  import { runLifecycleMaintenance } from "./lifecycle-maintenance.js";
61
- import { runMemoryCleanup, purgeMemories, type PurgeFilters } from "./memory-cleanup.js";
61
+ import { runMemoryAudit } from "./memory-audit.js";
62
+ import {
63
+ type PurgeFilters,
64
+ purgeMemories,
65
+ runMemoryCleanup,
66
+ } from "./memory-cleanup.js";
62
67
  import { onboardNewUser } from "./onboard.js";
63
68
  import type { PromptVariant } from "./prompt-builder.js";
64
69
 
@@ -1657,7 +1662,7 @@ const TOOLS = {
1657
1662
 
1658
1663
  harmony_cleanup_memories: {
1659
1664
  description:
1660
- "Run a unified memory cleanup: prune stale drafts, consolidate similar memories, detect orphans and duplicates, and backfill embeddings. Returns a health report. Dry-run by default — run with dryRun=false to execute.",
1665
+ "Run a unified memory cleanup: prune stale drafts, consolidate similar memories, detect orphans and duplicates, backfill embeddings, and optionally run a quality audit. Returns a health report. Dry-run by default — run with dryRun=false to execute.",
1661
1666
  inputSchema: {
1662
1667
  type: "object",
1663
1668
  properties: {
@@ -1678,10 +1683,17 @@ const TOOLS = {
1678
1683
  type: "array",
1679
1684
  items: {
1680
1685
  type: "string",
1681
- enum: ["prune", "consolidate", "orphans", "duplicates", "backfill"],
1686
+ enum: [
1687
+ "prune",
1688
+ "consolidate",
1689
+ "orphans",
1690
+ "duplicates",
1691
+ "backfill",
1692
+ "audit",
1693
+ ],
1682
1694
  },
1683
1695
  description:
1684
- "Which cleanup steps to run (default: all). Options: prune, consolidate, orphans, duplicates, backfill.",
1696
+ "Which cleanup steps to run (default: all). Options: prune, consolidate, orphans, duplicates, backfill, audit.",
1685
1697
  },
1686
1698
  maxAgeDays: {
1687
1699
  type: "number",
@@ -1695,6 +1707,59 @@ const TOOLS = {
1695
1707
  type: "number",
1696
1708
  description: "Min age in days for orphan detection (default: 14)",
1697
1709
  },
1710
+ auditArchiveBelow: {
1711
+ type: "number",
1712
+ description:
1713
+ "Audit: archive entities scoring below this (default: 40)",
1714
+ },
1715
+ auditDeleteBelow: {
1716
+ type: "number",
1717
+ description:
1718
+ "Audit: delete entities scoring below this (default: 20)",
1719
+ },
1720
+ },
1721
+ required: [],
1722
+ },
1723
+ },
1724
+ harmony_audit_memories: {
1725
+ description:
1726
+ "Rate every memory against state-of-the-art quality standards (confidence, decay, structural completeness, content, tier-age fit, access). Flags legacy entities from before recent optimizations (default confidence, missing embeddings, stuck drafts). Buckets: keep (≥70), review (40-69), archive (20-39), delete (<20). Dry-run by default.",
1727
+ inputSchema: {
1728
+ type: "object",
1729
+ properties: {
1730
+ workspaceId: {
1731
+ type: "string",
1732
+ description: "Workspace ID (optional if context set)",
1733
+ },
1734
+ projectId: {
1735
+ type: "string",
1736
+ description: "Project ID (optional)",
1737
+ },
1738
+ dryRun: {
1739
+ type: "boolean",
1740
+ description:
1741
+ "Preview audit without flagging/archiving/deleting (default: true)",
1742
+ },
1743
+ archiveBelow: {
1744
+ type: "number",
1745
+ description:
1746
+ "Score threshold below which entities are archived (confidence set to 0.25). Default: 40",
1747
+ },
1748
+ deleteBelow: {
1749
+ type: "number",
1750
+ description:
1751
+ "Score threshold below which entities are hard-deleted. Default: 20. Set to 0 to never delete.",
1752
+ },
1753
+ limit: {
1754
+ type: "number",
1755
+ description:
1756
+ "Max number of entities to audit (default: 500). Paginated fetch.",
1757
+ },
1758
+ staleDraftAgeDays: {
1759
+ type: "number",
1760
+ description:
1761
+ "Age threshold (days) for the stale-draft filter: flags drafts with 0 accesses older than this. Reported separately from bucket scoring — surfaces promote-or-drop candidates the thresholds miss. Default: 7.",
1762
+ },
1698
1763
  },
1699
1764
  required: [],
1700
1765
  },
@@ -4091,6 +4156,39 @@ async function handleToolCall(
4091
4156
  };
4092
4157
  }
4093
4158
 
4159
+ case "harmony_audit_memories": {
4160
+ const workspaceId =
4161
+ (args.workspaceId as string) || deps.getActiveWorkspaceId();
4162
+ if (!workspaceId) {
4163
+ throw new Error(
4164
+ "No workspace specified. Use harmony_set_workspace_context or provide workspaceId.",
4165
+ );
4166
+ }
4167
+ const projectId =
4168
+ (args.projectId as string) || deps.getActiveProjectId() || undefined;
4169
+
4170
+ const report = await runMemoryAudit(client, workspaceId, projectId, {
4171
+ dryRun: args.dryRun as boolean | undefined,
4172
+ archiveBelow: args.archiveBelow as number | undefined,
4173
+ deleteBelow: args.deleteBelow as number | undefined,
4174
+ limit: args.limit as number | undefined,
4175
+ staleDraftAgeDays: args.staleDraftAgeDays as number | undefined,
4176
+ });
4177
+
4178
+ return {
4179
+ success: report.success,
4180
+ dryRun: report.dryRun,
4181
+ summary: report.summary,
4182
+ distribution: report.distribution,
4183
+ legacyBreakdown: report.legacyBreakdown,
4184
+ actionsTaken: report.actionsTaken,
4185
+ lowest: report.lowest,
4186
+ staleDrafts: report.staleDrafts,
4187
+ errors: report.errors,
4188
+ healthReport: report.healthReport,
4189
+ };
4190
+ }
4191
+
4094
4192
  case "harmony_cleanup_memories": {
4095
4193
  const workspaceId =
4096
4194
  (args.workspaceId as string) || deps.getActiveWorkspaceId();
@@ -4108,6 +4206,7 @@ async function handleToolCall(
4108
4206
  "orphans",
4109
4207
  "duplicates",
4110
4208
  "backfill",
4209
+ "audit",
4111
4210
  ];
4112
4211
  const rawSteps = args.steps as string[] | undefined;
4113
4212
  const steps = rawSteps?.filter((s) => validSteps.includes(s));
@@ -4119,10 +4218,21 @@ async function handleToolCall(
4119
4218
 
4120
4219
  const report = await runMemoryCleanup(client, workspaceId, projectId, {
4121
4220
  dryRun: args.dryRun as boolean | undefined,
4122
- steps,
4221
+ steps: steps as
4222
+ | (
4223
+ | "prune"
4224
+ | "consolidate"
4225
+ | "orphans"
4226
+ | "duplicates"
4227
+ | "backfill"
4228
+ | "audit"
4229
+ )[]
4230
+ | undefined,
4123
4231
  maxAgeDays: args.maxAgeDays as number | undefined,
4124
4232
  minClusterSize: args.minClusterSize as number | undefined,
4125
4233
  orphanAgeDays: args.orphanAgeDays as number | undefined,
4234
+ auditArchiveBelow: args.auditArchiveBelow as number | undefined,
4235
+ auditDeleteBelow: args.auditDeleteBelow as number | undefined,
4126
4236
  });
4127
4237
 
4128
4238
  return {
@@ -4142,8 +4252,7 @@ async function handleToolCall(
4142
4252
  "No workspace specified. Use harmony_set_workspace_context or provide workspaceId.",
4143
4253
  );
4144
4254
  }
4145
- const projectId =
4146
- (args.projectId as string) || deps.getActiveProjectId();
4255
+ const projectId = (args.projectId as string) || deps.getActiveProjectId();
4147
4256
  if (!projectId) {
4148
4257
  throw new Error(
4149
4258
  "No project specified. Purge requires a project scope. Use harmony_set_project_context or provide projectId.",