@tambo-ai/react 0.64.1 → 0.65.2

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 (130) hide show
  1. package/README.md +304 -327
  2. package/dist/hooks/use-tambo-threads.d.ts +0 -12
  3. package/dist/hooks/use-tambo-threads.d.ts.map +1 -1
  4. package/dist/hooks/use-tambo-threads.js.map +1 -1
  5. package/dist/index.d.ts +3 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +6 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/mcp/__tests__/elicitation.test.js +7 -3
  10. package/dist/mcp/__tests__/elicitation.test.js.map +1 -1
  11. package/dist/mcp/__tests__/mcp-hooks.test.js +149 -123
  12. package/dist/mcp/__tests__/mcp-hooks.test.js.map +1 -1
  13. package/dist/mcp/__tests__/tambo-mcp-provider.test.js +176 -120
  14. package/dist/mcp/__tests__/tambo-mcp-provider.test.js.map +1 -1
  15. package/dist/mcp/__tests__/use-mcp-servers.test.js +12 -9
  16. package/dist/mcp/__tests__/use-mcp-servers.test.js.map +1 -1
  17. package/dist/mcp/elicitation.d.ts +4 -40
  18. package/dist/mcp/elicitation.d.ts.map +1 -1
  19. package/dist/mcp/elicitation.js +1 -1
  20. package/dist/mcp/elicitation.js.map +1 -1
  21. package/dist/mcp/index.d.ts +2 -1
  22. package/dist/mcp/index.d.ts.map +1 -1
  23. package/dist/mcp/index.js +2 -1
  24. package/dist/mcp/index.js.map +1 -1
  25. package/dist/mcp/mcp-client.d.ts +14 -26
  26. package/dist/mcp/mcp-client.d.ts.map +1 -1
  27. package/dist/mcp/mcp-client.js +4 -7
  28. package/dist/mcp/mcp-client.js.map +1 -1
  29. package/dist/mcp/mcp-hooks.d.ts +27 -78
  30. package/dist/mcp/mcp-hooks.d.ts.map +1 -1
  31. package/dist/mcp/tambo-mcp-provider.d.ts +27 -45
  32. package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
  33. package/dist/mcp/tambo-mcp-provider.js +36 -87
  34. package/dist/mcp/tambo-mcp-provider.js.map +1 -1
  35. package/dist/model/mcp-server-info.d.ts +74 -0
  36. package/dist/model/mcp-server-info.d.ts.map +1 -0
  37. package/dist/model/mcp-server-info.js +29 -0
  38. package/dist/model/mcp-server-info.js.map +1 -0
  39. package/dist/providers/__tests__/tambo-thread-provider-initial-messages.test.js +22 -8
  40. package/dist/providers/__tests__/tambo-thread-provider-initial-messages.test.js.map +1 -1
  41. package/dist/providers/__tests__/tambo-thread-provider.test.js +318 -129
  42. package/dist/providers/__tests__/tambo-thread-provider.test.js.map +1 -1
  43. package/dist/providers/index.d.ts +1 -1
  44. package/dist/providers/index.d.ts.map +1 -1
  45. package/dist/providers/index.js +2 -1
  46. package/dist/providers/index.js.map +1 -1
  47. package/dist/providers/tambo-client-provider.d.ts +4 -0
  48. package/dist/providers/tambo-client-provider.d.ts.map +1 -1
  49. package/dist/providers/tambo-client-provider.js +3 -0
  50. package/dist/providers/tambo-client-provider.js.map +1 -1
  51. package/dist/providers/tambo-mcp-token-provider.d.ts +3 -0
  52. package/dist/providers/tambo-mcp-token-provider.d.ts.map +1 -1
  53. package/dist/providers/tambo-mcp-token-provider.js +11 -3
  54. package/dist/providers/tambo-mcp-token-provider.js.map +1 -1
  55. package/dist/providers/tambo-provider.d.ts +1 -0
  56. package/dist/providers/tambo-provider.d.ts.map +1 -1
  57. package/dist/providers/tambo-provider.js +10 -5
  58. package/dist/providers/tambo-provider.js.map +1 -1
  59. package/dist/providers/tambo-registry-provider.d.ts +37 -0
  60. package/dist/providers/tambo-registry-provider.d.ts.map +1 -1
  61. package/dist/providers/tambo-registry-provider.js +162 -2
  62. package/dist/providers/tambo-registry-provider.js.map +1 -1
  63. package/dist/providers/tambo-stubs.d.ts.map +1 -1
  64. package/dist/providers/tambo-stubs.js +10 -1
  65. package/dist/providers/tambo-stubs.js.map +1 -1
  66. package/esm/hooks/use-tambo-threads.d.ts +0 -12
  67. package/esm/hooks/use-tambo-threads.d.ts.map +1 -1
  68. package/esm/hooks/use-tambo-threads.js.map +1 -1
  69. package/esm/index.d.ts +3 -1
  70. package/esm/index.d.ts.map +1 -1
  71. package/esm/index.js +3 -2
  72. package/esm/index.js.map +1 -1
  73. package/esm/mcp/__tests__/elicitation.test.js +8 -4
  74. package/esm/mcp/__tests__/elicitation.test.js.map +1 -1
  75. package/esm/mcp/__tests__/mcp-hooks.test.js +149 -123
  76. package/esm/mcp/__tests__/mcp-hooks.test.js.map +1 -1
  77. package/esm/mcp/__tests__/tambo-mcp-provider.test.js +178 -122
  78. package/esm/mcp/__tests__/tambo-mcp-provider.test.js.map +1 -1
  79. package/esm/mcp/__tests__/use-mcp-servers.test.js +12 -9
  80. package/esm/mcp/__tests__/use-mcp-servers.test.js.map +1 -1
  81. package/esm/mcp/elicitation.d.ts +4 -40
  82. package/esm/mcp/elicitation.d.ts.map +1 -1
  83. package/esm/mcp/elicitation.js +2 -2
  84. package/esm/mcp/elicitation.js.map +1 -1
  85. package/esm/mcp/index.d.ts +2 -1
  86. package/esm/mcp/index.d.ts.map +1 -1
  87. package/esm/mcp/index.js +1 -1
  88. package/esm/mcp/index.js.map +1 -1
  89. package/esm/mcp/mcp-client.d.ts +14 -26
  90. package/esm/mcp/mcp-client.d.ts.map +1 -1
  91. package/esm/mcp/mcp-client.js +3 -5
  92. package/esm/mcp/mcp-client.js.map +1 -1
  93. package/esm/mcp/mcp-hooks.d.ts +27 -78
  94. package/esm/mcp/mcp-hooks.d.ts.map +1 -1
  95. package/esm/mcp/tambo-mcp-provider.d.ts +27 -45
  96. package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
  97. package/esm/mcp/tambo-mcp-provider.js +35 -86
  98. package/esm/mcp/tambo-mcp-provider.js.map +1 -1
  99. package/esm/model/mcp-server-info.d.ts +74 -0
  100. package/esm/model/mcp-server-info.d.ts.map +1 -0
  101. package/esm/model/mcp-server-info.js +25 -0
  102. package/esm/model/mcp-server-info.js.map +1 -0
  103. package/esm/providers/__tests__/tambo-thread-provider-initial-messages.test.js +23 -9
  104. package/esm/providers/__tests__/tambo-thread-provider-initial-messages.test.js.map +1 -1
  105. package/esm/providers/__tests__/tambo-thread-provider.test.js +319 -130
  106. package/esm/providers/__tests__/tambo-thread-provider.test.js.map +1 -1
  107. package/esm/providers/index.d.ts +1 -1
  108. package/esm/providers/index.d.ts.map +1 -1
  109. package/esm/providers/index.js +1 -1
  110. package/esm/providers/index.js.map +1 -1
  111. package/esm/providers/tambo-client-provider.d.ts +4 -0
  112. package/esm/providers/tambo-client-provider.d.ts.map +1 -1
  113. package/esm/providers/tambo-client-provider.js +3 -0
  114. package/esm/providers/tambo-client-provider.js.map +1 -1
  115. package/esm/providers/tambo-mcp-token-provider.d.ts +3 -0
  116. package/esm/providers/tambo-mcp-token-provider.d.ts.map +1 -1
  117. package/esm/providers/tambo-mcp-token-provider.js +13 -5
  118. package/esm/providers/tambo-mcp-token-provider.js.map +1 -1
  119. package/esm/providers/tambo-provider.d.ts +1 -0
  120. package/esm/providers/tambo-provider.d.ts.map +1 -1
  121. package/esm/providers/tambo-provider.js +11 -6
  122. package/esm/providers/tambo-provider.js.map +1 -1
  123. package/esm/providers/tambo-registry-provider.d.ts +37 -0
  124. package/esm/providers/tambo-registry-provider.d.ts.map +1 -1
  125. package/esm/providers/tambo-registry-provider.js +161 -2
  126. package/esm/providers/tambo-registry-provider.js.map +1 -1
  127. package/esm/providers/tambo-stubs.d.ts.map +1 -1
  128. package/esm/providers/tambo-stubs.js +10 -1
  129. package/esm/providers/tambo-stubs.js.map +1 -1
  130. package/package.json +6 -6
@@ -1,8 +1,8 @@
1
1
  import { render, waitFor } from "@testing-library/react";
2
2
  import React, { useEffect } from "react";
3
- import { useTamboClient } from "../../providers/tambo-client-provider";
3
+ import { TamboClientContext, useTamboClient, } from "../../providers/tambo-client-provider";
4
4
  import { TamboMcpTokenProvider } from "../../providers/tambo-mcp-token-provider";
5
- import { useTamboRegistry } from "../../providers/tambo-registry-provider";
5
+ import { TamboRegistryProvider, useTamboRegistry, } from "../../providers/tambo-registry-provider";
6
6
  import { MCPClient, MCPTransport } from "../mcp-client";
7
7
  import { extractErrorMessage, TamboMcpProvider, useTamboMcpServers, } from "../tambo-mcp-provider";
8
8
  // Import the private function for testing by re-exporting it for tests only
@@ -25,13 +25,34 @@ jest.mock("../mcp-client", () => ({
25
25
  },
26
26
  }));
27
27
  // Mock the registry provider to avoid dependency issues
28
- jest.mock("../../providers/tambo-registry-provider", () => ({
29
- useTamboRegistry: jest.fn(),
30
- }));
28
+ jest.mock("../../providers/tambo-registry-provider", () => {
29
+ const actual = jest.requireActual("../../providers/tambo-registry-provider");
30
+ return {
31
+ ...actual,
32
+ useTamboRegistry: jest.fn(),
33
+ };
34
+ });
31
35
  // Mock the client provider to avoid dependency issues
32
- jest.mock("../../providers/tambo-client-provider", () => ({
33
- useTamboClient: jest.fn(),
34
- }));
36
+ jest.mock("../../providers/tambo-client-provider", () => {
37
+ return {
38
+ useTamboClient: jest.fn(),
39
+ TamboClientContext: React.createContext(undefined),
40
+ };
41
+ });
42
+ // Helper to wrap tests with all required providers (used across multiple describe blocks)
43
+ const TestWrapper = ({ mcpServers, handlers, children }) => {
44
+ const client = useTamboClient();
45
+ return (React.createElement(TamboClientContext.Provider, { value: {
46
+ client,
47
+ queryClient: {},
48
+ isUpdatingToken: false,
49
+ mcpAccessToken: null,
50
+ setMcpAccessToken: () => { },
51
+ } },
52
+ React.createElement(TamboRegistryProvider, { mcpServers: mcpServers },
53
+ React.createElement(TamboMcpTokenProvider, null,
54
+ React.createElement(TamboMcpProvider, { handlers: handlers }, children)))));
55
+ };
35
56
  describe("extractErrorMessage", () => {
36
57
  describe("Array content handling", () => {
37
58
  it("should extract text from array content with multiple text items", () => {
@@ -156,17 +177,33 @@ describe("TamboMcpProvider server list changes", () => {
156
177
  };
157
178
  it("adds a new server when the list grows", async () => {
158
179
  let latest = [];
159
- const { rerender, getByTestId } = render(React.createElement(TamboMcpTokenProvider, null,
160
- React.createElement(TamboMcpProvider, { mcpServers: ["https://a.example"] },
161
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
180
+ const { rerender, getByTestId } = render(React.createElement(TamboClientContext.Provider, { value: {
181
+ client: useTamboClient(),
182
+ queryClient: {},
183
+ isUpdatingToken: false,
184
+ mcpAccessToken: null,
185
+ setMcpAccessToken: () => { },
186
+ } },
187
+ React.createElement(TamboRegistryProvider, { mcpServers: ["https://a.example"] },
188
+ React.createElement(TamboMcpTokenProvider, null,
189
+ React.createElement(TamboMcpProvider, null,
190
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) }))))));
162
191
  // Wait for initial connection
163
192
  await waitFor(() => {
164
193
  expect(latest.length).toBe(1);
165
194
  });
166
195
  // Add new server
167
- rerender(React.createElement(TamboMcpTokenProvider, null,
168
- React.createElement(TamboMcpProvider, { mcpServers: ["https://a.example", "https://b.example"] },
169
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
196
+ rerender(React.createElement(TamboClientContext.Provider, { value: {
197
+ client: useTamboClient(),
198
+ queryClient: {},
199
+ isUpdatingToken: false,
200
+ mcpAccessToken: null,
201
+ setMcpAccessToken: () => { },
202
+ } },
203
+ React.createElement(TamboRegistryProvider, { mcpServers: ["https://a.example", "https://b.example"] },
204
+ React.createElement(TamboMcpTokenProvider, null,
205
+ React.createElement(TamboMcpProvider, null,
206
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) }))))));
170
207
  await waitFor(() => {
171
208
  expect(latest.length).toBe(2);
172
209
  const urls = getByTestId("urls").textContent || "";
@@ -176,16 +213,32 @@ describe("TamboMcpProvider server list changes", () => {
176
213
  });
177
214
  it("removes a server when the list shrinks", async () => {
178
215
  let latest = [];
179
- const { rerender, getByTestId } = render(React.createElement(TamboMcpTokenProvider, null,
180
- React.createElement(TamboMcpProvider, { mcpServers: ["https://a.example", "https://b.example"] },
181
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
216
+ const { rerender, getByTestId } = render(React.createElement(TamboClientContext.Provider, { value: {
217
+ client: useTamboClient(),
218
+ queryClient: {},
219
+ isUpdatingToken: false,
220
+ mcpAccessToken: null,
221
+ setMcpAccessToken: () => { },
222
+ } },
223
+ React.createElement(TamboRegistryProvider, { mcpServers: ["https://a.example", "https://b.example"] },
224
+ React.createElement(TamboMcpTokenProvider, null,
225
+ React.createElement(TamboMcpProvider, null,
226
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) }))))));
182
227
  await waitFor(() => {
183
228
  expect(latest.length).toBe(2);
184
229
  });
185
230
  // Remove one server
186
- rerender(React.createElement(TamboMcpTokenProvider, null,
187
- React.createElement(TamboMcpProvider, { mcpServers: ["https://a.example"] },
188
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
231
+ rerender(React.createElement(TamboClientContext.Provider, { value: {
232
+ client: useTamboClient(),
233
+ queryClient: {},
234
+ isUpdatingToken: false,
235
+ mcpAccessToken: null,
236
+ setMcpAccessToken: () => { },
237
+ } },
238
+ React.createElement(TamboRegistryProvider, { mcpServers: ["https://a.example"] },
239
+ React.createElement(TamboMcpTokenProvider, null,
240
+ React.createElement(TamboMcpProvider, null,
241
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) }))))));
189
242
  await waitFor(() => {
190
243
  expect(latest.length).toBe(1);
191
244
  const urls = getByTestId("urls").textContent || "";
@@ -199,9 +252,8 @@ describe("TamboMcpProvider server list changes", () => {
199
252
  { url: "https://a.example", transport: MCPTransport.SSE },
200
253
  { url: "https://b.example", transport: MCPTransport.SSE },
201
254
  ];
202
- const { rerender } = render(React.createElement(TamboMcpTokenProvider, null,
203
- React.createElement(TamboMcpProvider, { mcpServers: initial },
204
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
255
+ const { rerender } = render(React.createElement(TestWrapper, { mcpServers: initial },
256
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
205
257
  await waitFor(() => {
206
258
  expect(latest.length).toBe(2);
207
259
  });
@@ -210,9 +262,8 @@ describe("TamboMcpProvider server list changes", () => {
210
262
  { url: "https://a.example", transport: MCPTransport.SSE },
211
263
  { url: "https://b.example", transport: MCPTransport.SSE },
212
264
  ];
213
- rerender(React.createElement(TamboMcpTokenProvider, null,
214
- React.createElement(TamboMcpProvider, { mcpServers: same },
215
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
265
+ rerender(React.createElement(TestWrapper, { mcpServers: same },
266
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
216
267
  await waitFor(() => {
217
268
  expect(latest.length).toBe(2);
218
269
  const urls = latest.map((s) => s.url).sort();
@@ -227,9 +278,8 @@ describe("TamboMcpProvider server list changes", () => {
227
278
  MCPClient.create = createSpy;
228
279
  let latest = [];
229
280
  const initial = [{ url: "https://a.example", transport: MCPTransport.SSE }];
230
- const { rerender } = render(React.createElement(TamboMcpTokenProvider, null,
231
- React.createElement(TamboMcpProvider, { mcpServers: initial },
232
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
281
+ const { rerender } = render(React.createElement(TestWrapper, { mcpServers: initial },
282
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
233
283
  await waitFor(() => {
234
284
  expect(latest.length).toBe(1);
235
285
  });
@@ -238,9 +288,8 @@ describe("TamboMcpProvider server list changes", () => {
238
288
  const firstClient = latest[0].client;
239
289
  // Pass a new array with same server
240
290
  const same = [{ url: "https://a.example", transport: MCPTransport.SSE }];
241
- rerender(React.createElement(TamboMcpTokenProvider, null,
242
- React.createElement(TamboMcpProvider, { mcpServers: same },
243
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
291
+ rerender(React.createElement(TestWrapper, { mcpServers: same },
292
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
244
293
  await waitFor(() => {
245
294
  expect(latest.length).toBe(1);
246
295
  });
@@ -257,17 +306,33 @@ describe("TamboMcpProvider server list changes", () => {
257
306
  });
258
307
  MCPClient.create = createSpy;
259
308
  let latest = [];
260
- const { rerender } = render(React.createElement(TamboMcpTokenProvider, null,
261
- React.createElement(TamboMcpProvider, { mcpServers: ["https://a.example", "https://b.example"] },
262
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
309
+ const { rerender } = render(React.createElement(TamboClientContext.Provider, { value: {
310
+ client: useTamboClient(),
311
+ queryClient: {},
312
+ isUpdatingToken: false,
313
+ mcpAccessToken: null,
314
+ setMcpAccessToken: () => { },
315
+ } },
316
+ React.createElement(TamboRegistryProvider, { mcpServers: ["https://a.example", "https://b.example"] },
317
+ React.createElement(TamboMcpTokenProvider, null,
318
+ React.createElement(TamboMcpProvider, null,
319
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) }))))));
263
320
  await waitFor(() => {
264
321
  expect(latest.length).toBe(2);
265
322
  });
266
323
  expect(closeSpy).not.toHaveBeenCalled();
267
324
  // Remove one server
268
- rerender(React.createElement(TamboMcpTokenProvider, null,
269
- React.createElement(TamboMcpProvider, { mcpServers: ["https://a.example"] },
270
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
325
+ rerender(React.createElement(TamboClientContext.Provider, { value: {
326
+ client: useTamboClient(),
327
+ queryClient: {},
328
+ isUpdatingToken: false,
329
+ mcpAccessToken: null,
330
+ setMcpAccessToken: () => { },
331
+ } },
332
+ React.createElement(TamboRegistryProvider, { mcpServers: ["https://a.example"] },
333
+ React.createElement(TamboMcpTokenProvider, null,
334
+ React.createElement(TamboMcpProvider, null,
335
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) }))))));
271
336
  await waitFor(() => {
272
337
  expect(latest.length).toBe(1);
273
338
  });
@@ -282,9 +347,17 @@ describe("TamboMcpProvider server list changes", () => {
282
347
  });
283
348
  MCPClient.create = createSpy;
284
349
  let latest = [];
285
- const { unmount } = render(React.createElement(TamboMcpTokenProvider, null,
286
- React.createElement(TamboMcpProvider, { mcpServers: ["https://a.example", "https://b.example"] },
287
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
350
+ const { unmount } = render(React.createElement(TamboClientContext.Provider, { value: {
351
+ client: useTamboClient(),
352
+ queryClient: {},
353
+ isUpdatingToken: false,
354
+ mcpAccessToken: null,
355
+ setMcpAccessToken: () => { },
356
+ } },
357
+ React.createElement(TamboRegistryProvider, { mcpServers: ["https://a.example", "https://b.example"] },
358
+ React.createElement(TamboMcpTokenProvider, null,
359
+ React.createElement(TamboMcpProvider, null,
360
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) }))))));
288
361
  await waitFor(() => {
289
362
  expect(latest.length).toBe(2);
290
363
  });
@@ -307,15 +380,14 @@ describe("TamboMcpProvider server list changes", () => {
307
380
  });
308
381
  MCPClient.create = createSpy;
309
382
  let latest = [];
310
- const { rerender } = render(React.createElement(TamboMcpTokenProvider, null,
311
- React.createElement(TamboMcpProvider, { mcpServers: [
312
- {
313
- url: "https://a.example",
314
- transport: MCPTransport.SSE,
315
- customHeaders: { Authorization: "Bearer token1" },
316
- },
317
- ] },
318
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
383
+ const { rerender } = render(React.createElement(TestWrapper, { mcpServers: [
384
+ {
385
+ url: "https://a.example",
386
+ transport: MCPTransport.SSE,
387
+ customHeaders: { Authorization: "Bearer token1" },
388
+ },
389
+ ] },
390
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
319
391
  await waitFor(() => {
320
392
  expect(latest.length).toBe(1);
321
393
  expect(createSpy).toHaveBeenCalledTimes(1);
@@ -323,15 +395,14 @@ describe("TamboMcpProvider server list changes", () => {
323
395
  const firstClientId = latest[0].client?.id;
324
396
  expect(firstClientId).toBe(1);
325
397
  // Change the customHeaders
326
- rerender(React.createElement(TamboMcpTokenProvider, null,
327
- React.createElement(TamboMcpProvider, { mcpServers: [
328
- {
329
- url: "https://a.example",
330
- transport: MCPTransport.SSE,
331
- customHeaders: { Authorization: "Bearer token2" },
332
- },
333
- ] },
334
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
398
+ rerender(React.createElement(TestWrapper, { mcpServers: [
399
+ {
400
+ url: "https://a.example",
401
+ transport: MCPTransport.SSE,
402
+ customHeaders: { Authorization: "Bearer token2" },
403
+ },
404
+ ] },
405
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
335
406
  // Wait for old client to be closed and new client to be created
336
407
  await waitFor(() => {
337
408
  expect(closeSpy).toHaveBeenCalledTimes(1);
@@ -383,13 +454,12 @@ describe("TamboMcpProvider handler support", () => {
383
454
  elicitation: mockElicitationHandler,
384
455
  };
385
456
  let latest = [];
386
- render(React.createElement(TamboMcpTokenProvider, null,
387
- React.createElement(TamboMcpProvider, { mcpServers: ["https://test.example"], handlers: handlers },
388
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
457
+ render(React.createElement(TestWrapper, { mcpServers: ["https://test.example"], handlers: handlers },
458
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
389
459
  await waitFor(() => {
390
460
  expect(latest.length).toBe(1);
391
461
  });
392
- // Verify MCPClient.create was called
462
+ // Verify MCPClient.create was called with an HTTP transport and wrapped handler
393
463
  expect(createSpy).toHaveBeenCalledWith("https://test.example", MCPTransport.HTTP, undefined, undefined, undefined, expect.objectContaining({
394
464
  elicitation: expect.any(Function),
395
465
  }));
@@ -405,7 +475,7 @@ describe("TamboMcpProvider handler support", () => {
405
475
  await passedHandlers.elicitation(mockRequest, mockExtra);
406
476
  expect(mockElicitationHandler).toHaveBeenCalledWith(mockRequest, mockExtra, expect.objectContaining({
407
477
  url: "https://test.example",
408
- transport: MCPTransport.HTTP,
478
+ serverKey: "test",
409
479
  }));
410
480
  });
411
481
  it("should pass provider-level sampling handler to MCPClient.create", async () => {
@@ -419,13 +489,12 @@ describe("TamboMcpProvider handler support", () => {
419
489
  sampling: mockSamplingHandler,
420
490
  };
421
491
  let latest = [];
422
- render(React.createElement(TamboMcpTokenProvider, null,
423
- React.createElement(TamboMcpProvider, { mcpServers: ["https://test.example"], handlers: handlers },
424
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
492
+ render(React.createElement(TestWrapper, { mcpServers: ["https://test.example"], handlers: handlers },
493
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
425
494
  await waitFor(() => {
426
495
  expect(latest.length).toBe(1);
427
496
  });
428
- // Verify MCPClient.create was called with sampling handler
497
+ // Verify MCPClient.create was called with HTTP transport and sampling handler
429
498
  expect(createSpy).toHaveBeenCalledWith("https://test.example", MCPTransport.HTTP, undefined, undefined, undefined, expect.objectContaining({
430
499
  sampling: expect.any(Function),
431
500
  }));
@@ -442,7 +511,7 @@ describe("TamboMcpProvider handler support", () => {
442
511
  await passedHandlers.sampling(mockRequest, mockExtra);
443
512
  expect(mockSamplingHandler).toHaveBeenCalledWith(mockRequest, mockExtra, expect.objectContaining({
444
513
  url: "https://test.example",
445
- transport: MCPTransport.HTTP,
514
+ serverKey: "test",
446
515
  }));
447
516
  });
448
517
  it("should allow per-server handlers to override provider-level handlers", async () => {
@@ -456,16 +525,15 @@ describe("TamboMcpProvider handler support", () => {
456
525
  elicitation: providerElicitationHandler,
457
526
  };
458
527
  let latest = [];
459
- render(React.createElement(TamboMcpTokenProvider, null,
460
- React.createElement(TamboMcpProvider, { mcpServers: [
461
- {
462
- url: "https://test.example",
463
- handlers: {
464
- elicitation: serverElicitationHandler,
465
- },
528
+ render(React.createElement(TestWrapper, { mcpServers: [
529
+ {
530
+ url: "https://test.example",
531
+ handlers: {
532
+ elicitation: serverElicitationHandler,
466
533
  },
467
- ], handlers: handlers },
468
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
534
+ },
535
+ ], handlers: handlers },
536
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
469
537
  await waitFor(() => {
470
538
  expect(latest.length).toBe(1);
471
539
  });
@@ -481,12 +549,11 @@ describe("TamboMcpProvider handler support", () => {
481
549
  elicitation: mockElicitationHandler,
482
550
  };
483
551
  let latest = [];
484
- render(React.createElement(TamboMcpTokenProvider, null,
485
- React.createElement(TamboMcpProvider, { mcpServers: [
486
- { url: "https://server-a.example", name: "Server A" },
487
- { url: "https://server-b.example", name: "Server B" },
488
- ], handlers: handlers },
489
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
552
+ render(React.createElement(TestWrapper, { mcpServers: [
553
+ { url: "https://server-a.example", name: "Server A" },
554
+ { url: "https://server-b.example", name: "Server B" },
555
+ ], handlers: handlers },
556
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
490
557
  await waitFor(() => {
491
558
  expect(latest.length).toBe(2);
492
559
  });
@@ -522,16 +589,14 @@ describe("TamboMcpProvider handler support", () => {
522
589
  content: [{ type: "text", text: "updated" }],
523
590
  });
524
591
  let latest = [];
525
- const { rerender } = render(React.createElement(TamboMcpTokenProvider, null,
526
- React.createElement(TamboMcpProvider, { mcpServers: ["https://test.example"], handlers: { elicitation: initialHandler } },
527
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
592
+ const { rerender } = render(React.createElement(TestWrapper, { mcpServers: ["https://test.example"], handlers: { elicitation: initialHandler } },
593
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
528
594
  await waitFor(() => {
529
595
  expect(latest.length).toBe(1);
530
596
  });
531
597
  // Update the handlers
532
- rerender(React.createElement(TamboMcpTokenProvider, null,
533
- React.createElement(TamboMcpProvider, { mcpServers: ["https://test.example"], handlers: { elicitation: updatedHandler } },
534
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
598
+ rerender(React.createElement(TestWrapper, { mcpServers: ["https://test.example"], handlers: { elicitation: updatedHandler } },
599
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
535
600
  await waitFor(() => {
536
601
  expect(mockClient.updateElicitationHandler).toHaveBeenCalled();
537
602
  });
@@ -564,9 +629,8 @@ describe("TamboMcpProvider serverKey derivation and tool prefixing", () => {
564
629
  close: jest.fn(),
565
630
  });
566
631
  let latest = [];
567
- render(React.createElement(TamboMcpTokenProvider, null,
568
- React.createElement(TamboMcpProvider, { mcpServers: ["https://mcp.linear.app/mcp"] },
569
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
632
+ render(React.createElement(TestWrapper, { mcpServers: ["https://mcp.linear.app/mcp"] },
633
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
570
634
  await waitFor(() => {
571
635
  expect(latest.length).toBe(1);
572
636
  expect(latest[0].serverKey).toBe("linear");
@@ -578,14 +642,13 @@ describe("TamboMcpProvider serverKey derivation and tool prefixing", () => {
578
642
  close: jest.fn(),
579
643
  });
580
644
  let latest = [];
581
- render(React.createElement(TamboMcpTokenProvider, null,
582
- React.createElement(TamboMcpProvider, { mcpServers: [
583
- {
584
- url: "https://mcp.linear.app/mcp",
585
- serverKey: "custom-key",
586
- },
587
- ] },
588
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
645
+ render(React.createElement(TestWrapper, { mcpServers: [
646
+ {
647
+ url: "https://mcp.linear.app/mcp",
648
+ serverKey: "custom-key",
649
+ },
650
+ ] },
651
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
589
652
  await waitFor(() => {
590
653
  expect(latest.length).toBe(1);
591
654
  expect(latest[0].serverKey).toBe("custom-key");
@@ -605,9 +668,8 @@ describe("TamboMcpProvider serverKey derivation and tool prefixing", () => {
605
668
  ];
606
669
  for (const { url, expected } of testCases) {
607
670
  let latest = [];
608
- const { unmount } = render(React.createElement(TamboMcpTokenProvider, null,
609
- React.createElement(TamboMcpProvider, { mcpServers: [url] },
610
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
671
+ const { unmount } = render(React.createElement(TestWrapper, { mcpServers: [url] },
672
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
611
673
  await waitFor(() => {
612
674
  expect(latest.length).toBe(1);
613
675
  expect(latest[0].serverKey).toBe(expected);
@@ -627,9 +689,8 @@ describe("TamboMcpProvider serverKey derivation and tool prefixing", () => {
627
689
  close: jest.fn(),
628
690
  });
629
691
  let latest = [];
630
- render(React.createElement(TamboMcpTokenProvider, null,
631
- React.createElement(TamboMcpProvider, { mcpServers: ["https://mcp.linear.app/mcp"] },
632
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
692
+ render(React.createElement(TestWrapper, { mcpServers: ["https://mcp.linear.app/mcp"] },
693
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
633
694
  await waitFor(() => {
634
695
  expect(latest.length).toBe(1);
635
696
  expect(mockRegisterTool).toHaveBeenCalledWith(expect.objectContaining({
@@ -647,12 +708,8 @@ describe("TamboMcpProvider serverKey derivation and tool prefixing", () => {
647
708
  close: jest.fn(),
648
709
  });
649
710
  let latest = [];
650
- render(React.createElement(TamboMcpTokenProvider, null,
651
- React.createElement(TamboMcpProvider, { mcpServers: [
652
- "https://mcp.linear.app/mcp",
653
- "https://api.github.com",
654
- ] },
655
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
711
+ render(React.createElement(TestWrapper, { mcpServers: ["https://mcp.linear.app/mcp", "https://api.github.com"] },
712
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
656
713
  await waitFor(() => {
657
714
  expect(latest.length).toBe(2);
658
715
  // Check that tools are registered with prefixed names
@@ -676,15 +733,14 @@ describe("TamboMcpProvider serverKey derivation and tool prefixing", () => {
676
733
  close: jest.fn(),
677
734
  });
678
735
  let latest = [];
679
- render(React.createElement(TamboMcpTokenProvider, null,
680
- React.createElement(TamboMcpProvider, { mcpServers: [
681
- {
682
- url: "https://mcp.linear.app/mcp",
683
- serverKey: "my-server",
684
- },
685
- "https://api.github.com",
686
- ] },
687
- React.createElement(Capture, { onUpdate: (s) => (latest = s) }))));
736
+ render(React.createElement(TestWrapper, { mcpServers: [
737
+ {
738
+ url: "https://mcp.linear.app/mcp",
739
+ serverKey: "my-server",
740
+ },
741
+ "https://api.github.com",
742
+ ] },
743
+ React.createElement(Capture, { onUpdate: (s) => (latest = s) })));
688
744
  await waitFor(() => {
689
745
  expect(latest.length).toBe(2);
690
746
  const calls = mockRegisterTool.mock.calls;