From 905076ca1e380dd4a37fd4101d27d4e703f1ded6 Mon Sep 17 00:00:00 2001 From: Brian Newman Date: Wed, 18 Mar 2026 13:57:28 -0700 Subject: [PATCH 1/2] fix(memory): correct QMD mcporter tool name mapping + add capability validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mcporter bridge mapped searchMode 'query' to MCP tool 'deep_search', but QMD's MCP server exposes this as 'query'. This mismatch caused all mcporter-routed queries to fail silently, falling back to builtin BM25. Changes: - Fix 'deep_search' → 'query' in tool name mapping and type annotations - Add startup capability validation: after mcporter daemon starts, run 'mcporter list ' and warn if expected tools are missing The validation catches tool-name drift between the bridge and QMD MCP server at startup rather than failing silently at query time. Fixes #49768 --- src/memory/qmd-manager.ts | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/memory/qmd-manager.ts b/src/memory/qmd-manager.ts index 46a80156677..7f8bc22b45b 100644 --- a/src/memory/qmd-manager.ts +++ b/src/memory/qmd-manager.ts @@ -749,12 +749,12 @@ export class QmdMemoryManager implements MemorySearchManager { ): Promise => { try { if (mcporterEnabled) { - const tool: "search" | "vector_search" | "deep_search" = + const tool: "search" | "vector_search" | "query" = qmdSearchCommand === "search" ? "search" : qmdSearchCommand === "vsearch" ? "vector_search" - : "deep_search"; + : "query"; const minScore = opts?.minScore ?? 0; if (collectionNames.length > 1) { return await this.runMcporterAcrossCollections({ @@ -1234,6 +1234,31 @@ export class QmdMemoryManager implements MemorySearchManager { log.warn(`mcporter daemon start failed: ${String(err)}`); // Allow future searches to retry daemon start on transient failures. delete g.__openclawMcporterDaemonStart; + return; + } + + // Validate that the QMD MCP server exposes the expected tools. + try { + const expectedTools = ["search", "vector_search", "query"]; + const listResult = await this.runMcporter(["list", mcporter.serverName], { + timeoutMs: 10_000, + }); + const actualTools = listResult.stdout + .split("\n") + .map((l) => l.trim()) + .filter(Boolean); + const missing = expectedTools.filter((t) => !actualTools.some((a) => a.includes(t))); + if (missing.length > 0) { + log.warn( + `mcporter bridge tool mismatch for server "${mcporter.serverName}": ` + + `expected tools [${expectedTools.join(", ")}], ` + + `actual tools [${actualTools.join(", ")}], ` + + `missing [${missing.join(", ")}]`, + ); + } + } catch { + // Non-fatal: capability validation is best-effort. + log.warn("mcporter tool capability validation failed; continuing anyway"); } })(); } @@ -1263,7 +1288,7 @@ export class QmdMemoryManager implements MemorySearchManager { private async runQmdSearchViaMcporter(params: { mcporter: ResolvedQmdMcporterConfig; - tool: "search" | "vector_search" | "deep_search"; + tool: "search" | "vector_search" | "query"; query: string; limit: number; minScore: number; @@ -1997,7 +2022,7 @@ export class QmdMemoryManager implements MemorySearchManager { } private async runMcporterAcrossCollections(params: { - tool: "search" | "vector_search" | "deep_search"; + tool: "search" | "vector_search" | "query"; query: string; limit: number; minScore: number; From 1518fc7a436ff8fcb6a4a21e8e6fbe33e86d0549 Mon Sep 17 00:00:00 2001 From: Brian Newman Date: Wed, 18 Mar 2026 14:09:05 -0700 Subject: [PATCH 2/2] fix: use exact match for mcporter tool capability validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit actualTools.some(a => a.includes(t)) is a substring check — 'vector_search'.includes('search') === true, so a missing 'search' tool would be silently masked by 'vector_search' existing. Switch to actualTools.includes(t) for strict equality per element. --- src/memory/qmd-manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/memory/qmd-manager.ts b/src/memory/qmd-manager.ts index 7f8bc22b45b..05a5967d65e 100644 --- a/src/memory/qmd-manager.ts +++ b/src/memory/qmd-manager.ts @@ -1247,7 +1247,7 @@ export class QmdMemoryManager implements MemorySearchManager { .split("\n") .map((l) => l.trim()) .filter(Boolean); - const missing = expectedTools.filter((t) => !actualTools.some((a) => a.includes(t))); + const missing = expectedTools.filter((t) => !actualTools.includes(t)); if (missing.length > 0) { log.warn( `mcporter bridge tool mismatch for server "${mcporter.serverName}": ` +