diff --git a/apps/server/src/mcp/OrchestratorMcpToolkit.integration.test.ts b/apps/server/src/mcp/OrchestratorMcpToolkit.integration.test.ts index aeae1a94c68b06ec840653c5d069cc912499cdd0..0b3d1b0e18cf2c1c892fbad8d7d4de2a63e43e55 100644 --- a/apps/server/src/mcp/OrchestratorMcpToolkit.integration.test.ts +++ b/apps/server/src/mcp/OrchestratorMcpToolkit.integration.test.ts @@ -1426,6 +1426,12 @@ describe("orchestrator MCP toolkit", () => { expect(threadListTool?.tool.annotations?.idempotentHint).toBe(true); const threadReadTool = server.tools.find(({ tool }) => tool.name === "t3_thread_read"); expect(threadReadTool?.tool.annotations?.readOnlyHint).toBe(false); + expect(threadReadTool?.tool.inputSchema).toMatchObject({ additionalProperties: false }); + const unknownPagingParamError = yield* invoke("t3_thread_read", { + threadId: parentThreadId, + cursor: 90, + }).pipe(Effect.flip); + expect(unknownPagingParamError.message).toContain("Expected no excess property"); const threadUpdateTool = server.tools.find( ({ tool }) => tool.name === "t3_thread_update", ); diff --git a/apps/server/src/mcp/toolkits/orchestrator/tools.ts b/apps/server/src/mcp/toolkits/orchestrator/tools.ts index 3248618a2de08ffb38803ef0c99ac58122d0518d..f2c34bb22cbe151b496d7ec28a0cf33a68bb8520 100644 --- a/apps/server/src/mcp/toolkits/orchestrator/tools.ts +++ b/apps/server/src/mcp/toolkits/orchestrator/tools.ts @@ -214,6 +214,8 @@ const ThreadReadTool = Tool.make("t3_thread_read", { dependencies, }) .annotate(Tool.Title, "Read a T3 thread") + // Strict so a misspelled paging param fails instead of silently reading from position 0. + .annotate(Tool.Strict, true) .annotate(Tool.Readonly, false) .annotate(Tool.Destructive, false) .annotate(Tool.Idempotent, true);