brains-mcp 1.75.0 → 1.76.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 (38) hide show
  1. package/dist/httpServer.d.ts.map +1 -1
  2. package/dist/httpServer.js +47 -4
  3. package/dist/httpServer.js.map +1 -1
  4. package/dist/observability/metricsQuery.d.ts.map +1 -1
  5. package/dist/observability/metricsQuery.js +11 -0
  6. package/dist/observability/metricsQuery.js.map +1 -1
  7. package/dist/server.d.ts +14 -1
  8. package/dist/server.d.ts.map +1 -1
  9. package/dist/server.js +2 -13
  10. package/dist/server.js.map +1 -1
  11. package/dist/tools/auditIndex.d.ts.map +1 -1
  12. package/dist/tools/auditIndex.js +9 -3
  13. package/dist/tools/auditIndex.js.map +1 -1
  14. package/dist/tools/createPage.d.ts.map +1 -1
  15. package/dist/tools/createPage.js +3 -1
  16. package/dist/tools/createPage.js.map +1 -1
  17. package/dist/tools/createPages.d.ts.map +1 -1
  18. package/dist/tools/createPages.js +4 -1
  19. package/dist/tools/createPages.js.map +1 -1
  20. package/dist/tools/movePage.d.ts.map +1 -1
  21. package/dist/tools/movePage.js +6 -6
  22. package/dist/tools/movePage.js.map +1 -1
  23. package/dist/tools/pushSessionBundle.d.ts.map +1 -1
  24. package/dist/tools/pushSessionBundle.js +4 -1
  25. package/dist/tools/pushSessionBundle.js.map +1 -1
  26. package/dist/tools/pushWiki.d.ts +20 -1
  27. package/dist/tools/pushWiki.d.ts.map +1 -1
  28. package/dist/tools/pushWiki.js +30 -3
  29. package/dist/tools/pushWiki.js.map +1 -1
  30. package/dist/wiki/layoutLint.d.ts +17 -2
  31. package/dist/wiki/layoutLint.d.ts.map +1 -1
  32. package/dist/wiki/layoutLint.js +20 -5
  33. package/dist/wiki/layoutLint.js.map +1 -1
  34. package/dist/wiki/rootFolders.d.ts +34 -0
  35. package/dist/wiki/rootFolders.d.ts.map +1 -0
  36. package/dist/wiki/rootFolders.js +64 -0
  37. package/dist/wiki/rootFolders.js.map +1 -0
  38. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"httpServer.d.ts","sourceRoot":"","sources":["../src/httpServer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAQxB,OAAO,EAAsD,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAkH7G,wBAAgB,8BAA8B,IAAI,IAAI,CAErD;AAi6BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI9D;AAgsBD,wBAAsB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAqpF9F"}
1
+ {"version":3,"file":"httpServer.d.ts","sourceRoot":"","sources":["../src/httpServer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAQxB,OAAO,EAAsD,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAkH7G,wBAAgB,8BAA8B,IAAI,IAAI,CAErD;AAu7BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI9D;AAgsBD,wBAAsB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAkrF9F"}
@@ -229,6 +229,23 @@ function raceWithTimeout(promise, ms) {
229
229
  });
230
230
  return Promise.race([promise, timeoutPromise]).finally(() => clearTimeout(timer));
231
231
  }
232
+ // Shared enrichment for any request_events row produced by a raw
233
+ // executeToolCall() result — used by both the /mcp tools/call path and the
234
+ // /tool passthrough path, mirroring what the standalone REST /api/v1/search
235
+ // handler has always set for itself (GH #411: neither path set this before).
236
+ function toolResultLogExtras(result) {
237
+ const r = result;
238
+ if (!r || typeof r !== "object")
239
+ return {};
240
+ return {
241
+ backend: r.backend,
242
+ queryMs: r.timings?.queryMs,
243
+ syncMs: r.timings?.syncMs,
244
+ resultCount: r.count,
245
+ zeroResults: typeof r.count === "number" ? r.count === 0 : undefined,
246
+ pageCount: r.pageCount,
247
+ };
248
+ }
232
249
  function emitRequestLog(method, reqPath, status, durationMs, extras = {}) {
233
250
  const logFormat = (process.env.LOG_FORMAT ?? "").toLowerCase();
234
251
  if (logFormat === "json") {
@@ -1898,7 +1915,8 @@ export async function startHttpServer(drive, port) {
1898
1915
  // Re-resolve the drive on every tool call rather than baking in a
1899
1916
  // snapshot here — otherwise a project-share grant revoked mid-session
1900
1917
  // keeps being honored for the lifetime of this MCP session (BRA-377).
1901
- const mcpServer = createBrainsServer(() => resolveDriveForAuthorization(authorization), mcpUserId, mcpUserAccessLevel);
1918
+ const toolCallHook = {};
1919
+ const mcpServer = createBrainsServer(() => resolveDriveForAuthorization(authorization), mcpUserId, mcpUserAccessLevel, toolCallHook);
1902
1920
  const transport = new StreamableHTTPServerTransport({
1903
1921
  sessionIdGenerator: () => staleSid,
1904
1922
  });
@@ -1910,7 +1928,7 @@ export async function startHttpServer(drive, port) {
1910
1928
  if (!ok) {
1911
1929
  return null;
1912
1930
  }
1913
- const entry = { server: mcpServer, transport };
1931
+ const entry = { server: mcpServer, transport, toolCallHook };
1914
1932
  mcpSessions.set(staleSid, entry);
1915
1933
  return entry;
1916
1934
  })().finally(() => {
@@ -1938,7 +1956,8 @@ export async function startHttpServer(drive, port) {
1938
1956
  // Re-resolve the drive on every tool call rather than baking in a
1939
1957
  // snapshot here — otherwise a project-share grant revoked mid-session
1940
1958
  // keeps being honored for the lifetime of this MCP session (BRA-377).
1941
- const mcpServer = createBrainsServer(() => resolveDriveForAuthorization(authorization), mcpUserId, mcpUserAccessLevel);
1959
+ const toolCallHook = {};
1960
+ const mcpServer = createBrainsServer(() => resolveDriveForAuthorization(authorization), mcpUserId, mcpUserAccessLevel, toolCallHook);
1942
1961
  const transport = new StreamableHTTPServerTransport({
1943
1962
  sessionIdGenerator: () => randomUUID(),
1944
1963
  });
@@ -1949,7 +1968,7 @@ export async function startHttpServer(drive, port) {
1949
1968
  }
1950
1969
  };
1951
1970
  await mcpServer.connect(transport);
1952
- existing = { server: mcpServer, transport };
1971
+ existing = { server: mcpServer, transport, toolCallHook };
1953
1972
  }
1954
1973
  }
1955
1974
  const { transport } = existing;
@@ -1957,6 +1976,21 @@ export async function startHttpServer(drive, port) {
1957
1976
  // Inject timing headers before the transport writes its response headers.
1958
1977
  res.setHeader("X-Brains-Auth-Ms", String(mcpAuthMs));
1959
1978
  res.setHeader("X-Brains-Handler-Start-Ms", String(mcpHandlerStart));
1979
+ // Wire this one request's hook so query_ms/backend/etc. reach
1980
+ // res._logExtras once the tool call the MCP SDK dispatches inside
1981
+ // transport.handleRequest() actually resolves (GH #411: this
1982
+ // enrichment previously only existed on the standalone REST
1983
+ // /api/v1/search handler, never on the shared /mcp path).
1984
+ if (rpcToolName) {
1985
+ existing.toolCallHook.current = (name, result) => {
1986
+ const priorExtras = res._logExtras ?? {};
1987
+ res._logExtras = {
1988
+ ...priorExtras,
1989
+ tool: name,
1990
+ ...toolResultLogExtras(result),
1991
+ };
1992
+ };
1993
+ }
1960
1994
  try {
1961
1995
  await transport.handleRequest(req, res, body);
1962
1996
  }
@@ -1964,6 +1998,9 @@ export async function startHttpServer(drive, port) {
1964
1998
  console.error("[brains] MCP transport error:", mcpErr instanceof Error ? mcpErr.stack : String(mcpErr));
1965
1999
  throw mcpErr;
1966
2000
  }
2001
+ finally {
2002
+ existing.toolCallHook.current = undefined;
2003
+ }
1967
2004
  if (!res.headersSent) {
1968
2005
  res.setHeader("X-Brains-Handler-End-Ms", String(Date.now()));
1969
2006
  }
@@ -3625,6 +3662,12 @@ export async function startHttpServer(drive, port) {
3625
3662
  const body = await readJsonBody(req);
3626
3663
  const parsed = toolCallSchema.parse(body);
3627
3664
  const result = await executeToolCall(requestDrive, parsed.name, parsed.arguments ?? {}, requestUserId, requestAccessCtx);
3665
+ // GH #411: this passthrough endpoint never set _logExtras at all, so
3666
+ // its request_events rows had a null `tool` even before query_ms.
3667
+ res._logExtras = {
3668
+ tool: parsed.name,
3669
+ ...toolResultLogExtras(result),
3670
+ };
3628
3671
  json(req, res, 200, { ok: true, result });
3629
3672
  return;
3630
3673
  }