feat(mcp): expose the existing thread search query#10561

merged1
agents/mcp-thin/preferences
agents/mcp-thin/thread-search
openedSep 7, 2026byJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 4d ago
1 unresolved thread · Jump to file
Selected thread: apps/server/src/mcp/toolkits/thread/handlers.ts:76 — This adds new backend behavior (project-scoped filtering of global search results) with no focused test. Consider adding one that registers `ThreadToolkit` with a `Layer.mock(ProjectionSnapshotQuery.ProjectionSnapshotQuery)` returning matches from two projects, and asserts only the caller's `projectId` survives — a test layer for the persistence-backed query only, no mocking of the handler logic itself. `apps/server/src/mcp/toolkits/core.test.ts` already wires `ThreadToolkitRegistrationLive` with `Layer.mock(ThreadManagement.ThreadManagementService)` and is a natural home for it. <sup>Posted via Macroscope — <a href="https://github.com/pingdotgg/t3code/runs/101849996021">Effect Service Conventions</a></sup> <!-- macroscope-meta: {"kind":"check_run","config":".macroscope/check-run-agents/effect-service-conventions.md","check":"Effect Service Conventions"} -->
0 / 4 viewed4 files changedLine totals unavailable

apps/server/src/mcp/toolkits/thread/handlers.ts · Earlier revision 2e1bfbf1 · right 70–76

Original diff
@@ -60,6 +67,13 @@ const readQuestion = Effect.fn("mcp.readQuestion")(function* (
   return { ...context, request, item };
 });
 export const ThreadToolkitHandlersLive = ThreadToolkit.toLayer({
+  t3_thread_search: (input) =>
+    Effect.gen(function* () {
+      const { caller } = yield* readCaller();
+      const query = yield* ProjectionSnapshotQuery.ProjectionSnapshotQuery;
+      const result = yield* query.searchThreads(input).pipe(Effect.mapError(unavailable));
+      return { matches: result.matches.filter((match) => match.projectId === caller.projectId) };
+    }),

apps/server/src/mcp/toolkits/thread/handlers.ts · right 70–76

M
macroscopeappBotSep 7, 2026

This adds new backend behavior (project-scoped filtering of global search results) with no focused test. Consider adding one that registers ThreadToolkit with a Layer.mock(ProjectionSnapshotQuery.ProjectionSnapshotQuery) returning matches from two projects, and asserts only the caller's projectId survives — a test layer for the persistence-backed query only, no mocking of the handler logic itself. apps/server/src/mcp/toolkits/core.test.ts already wires ThreadToolkitRegistrationLive with Layer.mock(ThreadManagement.ThreadManagementService) and is a natural home for it.

Posted via Macroscope — Effect Service Conventions

J
Julius MarmingeSep 7, 2026

Reviewed against the maintainer's explicit testing direction for this rebuild. The handler applies a direct equality filter using the authenticated caller.projectId and leaves query execution in the existing tested search service. It does not implement a new search algorithm or pagination guarantee; underfilled global top-results are explicitly documented in the tool and PR. Core MCP tests cover authenticated scope/registration/errors, and the existing real integration checks foreign-project denial. This suggestion identifies no incorrect filtering path. I am not adding a per-tool mocked query suite solely to restate the one-line filter; custom multi-field output mappings are tested separately where the wrapper introduces meaningful transformation.