@tambo-ai/react 1.1.0 → 1.2.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.
- package/dist/context-helpers/current-interactables-context-helper.d.ts +16 -2
- package/dist/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
- package/dist/context-helpers/current-interactables-context-helper.js.map +1 -1
- package/dist/context-helpers/current-interactables-context-helper.test.d.ts +2 -0
- package/dist/context-helpers/current-interactables-context-helper.test.d.ts.map +1 -0
- package/dist/context-helpers/current-interactables-context-helper.test.js +70 -0
- package/dist/context-helpers/current-interactables-context-helper.test.js.map +1 -0
- package/dist/mcp/elicitation.d.ts +3 -37
- package/dist/mcp/elicitation.d.ts.map +1 -1
- package/dist/mcp/elicitation.js +7 -24
- package/dist/mcp/elicitation.js.map +1 -1
- package/dist/mcp/index.d.ts +4 -4
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +2 -2
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/mcp-client.test.js +17 -17
- package/dist/mcp/mcp-client.test.js.map +1 -1
- package/dist/mcp/mcp-hooks.d.ts.map +1 -1
- package/dist/mcp/mcp-hooks.js +8 -5
- package/dist/mcp/mcp-hooks.js.map +1 -1
- package/dist/mcp/mcp-hooks.test.js +30 -29
- package/dist/mcp/mcp-hooks.test.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.d.ts +6 -9
- package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/dist/mcp/tambo-mcp-provider.js +9 -13
- package/dist/mcp/tambo-mcp-provider.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.test.js +26 -25
- package/dist/mcp/tambo-mcp-provider.test.js.map +1 -1
- package/dist/mcp/use-mcp-servers.test.js +2 -1
- package/dist/mcp/use-mcp-servers.test.js.map +1 -1
- package/dist/model/component-metadata.d.ts +7 -372
- package/dist/model/component-metadata.d.ts.map +1 -1
- package/dist/model/component-metadata.js.map +1 -1
- package/dist/model/validate-input.test.d.ts +2 -0
- package/dist/model/validate-input.test.d.ts.map +1 -0
- package/dist/model/validate-input.test.js +38 -0
- package/dist/model/validate-input.test.js.map +1 -0
- package/dist/providers/tambo-interactable-provider.d.ts +7 -7
- package/dist/providers/tambo-registry-provider.d.ts +1 -1
- package/dist/providers/tambo-registry-provider.d.ts.map +1 -1
- package/dist/providers/tambo-registry-provider.js.map +1 -1
- package/dist/providers/tambo-registry-schema-compat.test.js +4 -4
- package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -1
- package/dist/schema/index.d.ts +2 -4
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +9 -11
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/json-schema.d.ts +1 -17
- package/dist/schema/json-schema.d.ts.map +1 -1
- package/dist/schema/json-schema.js +5 -69
- package/dist/schema/json-schema.js.map +1 -1
- package/dist/schema/schema.test.js +24 -25
- package/dist/schema/schema.test.js.map +1 -1
- package/dist/schema/standard-schema.test.js +25 -25
- package/dist/schema/standard-schema.test.js.map +1 -1
- package/dist/schema/validate.test.js +33 -33
- package/dist/schema/validate.test.js.map +1 -1
- package/dist/testing/tools.d.ts +4 -4
- package/dist/testing/tools.test.d.ts +2 -0
- package/dist/testing/tools.test.d.ts.map +1 -0
- package/dist/testing/tools.test.js +60 -0
- package/dist/testing/tools.test.js.map +1 -0
- package/dist/util/mcp-server-utils.d.ts +1 -1
- package/dist/util/mcp-server-utils.d.ts.map +1 -1
- package/dist/util/mcp-server-utils.js +4 -4
- package/dist/util/mcp-server-utils.js.map +1 -1
- package/dist/util/mcp-server-utils.test.js +27 -27
- package/dist/util/mcp-server-utils.test.js.map +1 -1
- package/dist/util/registry.js +1 -1
- package/dist/util/registry.js.map +1 -1
- package/dist/util/resource-content-resolver.js +5 -5
- package/dist/util/resource-content-resolver.js.map +1 -1
- package/dist/util/resource-content-resolver.test.js +6 -6
- package/dist/util/resource-content-resolver.test.js.map +1 -1
- package/dist/util/tool-caller.test.d.ts +2 -0
- package/dist/util/tool-caller.test.d.ts.map +1 -0
- package/dist/util/tool-caller.test.js +71 -0
- package/dist/util/tool-caller.test.js.map +1 -0
- package/dist/v1/__tests__/v1-interactables.test.js +1 -0
- package/dist/v1/__tests__/v1-interactables.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts +1 -1
- package/dist/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-auth-state.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.js +2 -2
- package/dist/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js +1 -1
- package/dist/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.js +17 -17
- package/dist/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js +1 -1
- package/dist/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.js +2 -2
- package/dist/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js +9 -5
- package/dist/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-suggestions.js +2 -2
- package/dist/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js +1 -0
- package/dist/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.d.ts +7 -6
- package/dist/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.js +2 -2
- package/dist/v1/hooks/use-tambo-v1.js.map +1 -1
- package/dist/v1/hooks/use-tambo-v1.test.js +23 -23
- package/dist/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/dist/v1/index.d.ts +6 -6
- package/dist/v1/index.d.ts.map +1 -1
- package/dist/v1/index.js +2 -2
- package/dist/v1/index.js.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts +2 -1
- package/dist/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-provider.js +2 -0
- package/dist/v1/providers/tambo-v1-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.d.ts +2 -2
- package/dist/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.js +9 -9
- package/dist/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stream-context.test.js +35 -0
- package/dist/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.js +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/dist/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/dist/v1/providers/tambo-v1-thread-input-provider.js +2 -2
- package/dist/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/dist/v1/types/event.test.js +13 -13
- package/dist/v1/types/event.test.js.map +1 -1
- package/dist/v1/types/message.d.ts +12 -109
- package/dist/v1/types/message.d.ts.map +1 -1
- package/dist/v1/types/message.js +0 -7
- package/dist/v1/types/message.js.map +1 -1
- package/dist/v1/utils/event-accumulator.test.js +183 -184
- package/dist/v1/utils/event-accumulator.test.js.map +1 -1
- package/dist/v1/utils/json-patch.test.js +4 -4
- package/dist/v1/utils/json-patch.test.js.map +1 -1
- package/dist/v1/utils/keyed-throttle.test.js +12 -12
- package/dist/v1/utils/keyed-throttle.test.js.map +1 -1
- package/dist/v1/utils/registry-conversion.test.js +13 -13
- package/dist/v1/utils/registry-conversion.test.js.map +1 -1
- package/dist/v1/utils/stream-handler.test.js +5 -5
- package/dist/v1/utils/stream-handler.test.js.map +1 -1
- package/dist/v1/utils/tool-call-tracker.test.js +15 -9
- package/dist/v1/utils/tool-call-tracker.test.js.map +1 -1
- package/dist/v1/utils/tool-executor.test.js +25 -26
- package/dist/v1/utils/tool-executor.test.js.map +1 -1
- package/dist/v1/utils/unstrictify.test.js +16 -16
- package/dist/v1/utils/unstrictify.test.js.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.d.ts +16 -2
- package/esm/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.js.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.test.d.ts +2 -0
- package/esm/context-helpers/current-interactables-context-helper.test.d.ts.map +1 -0
- package/esm/context-helpers/current-interactables-context-helper.test.js +68 -0
- package/esm/context-helpers/current-interactables-context-helper.test.js.map +1 -0
- package/esm/mcp/elicitation.d.ts +3 -37
- package/esm/mcp/elicitation.d.ts.map +1 -1
- package/esm/mcp/elicitation.js +4 -24
- package/esm/mcp/elicitation.js.map +1 -1
- package/esm/mcp/index.d.ts +4 -4
- package/esm/mcp/index.d.ts.map +1 -1
- package/esm/mcp/index.js +1 -1
- package/esm/mcp/index.js.map +1 -1
- package/esm/mcp/mcp-client.test.js +1 -1
- package/esm/mcp/mcp-client.test.js.map +1 -1
- package/esm/mcp/mcp-hooks.d.ts.map +1 -1
- package/esm/mcp/mcp-hooks.js +4 -1
- package/esm/mcp/mcp-hooks.js.map +1 -1
- package/esm/mcp/mcp-hooks.test.js +3 -2
- package/esm/mcp/mcp-hooks.test.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.d.ts +6 -9
- package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/esm/mcp/tambo-mcp-provider.js +4 -8
- package/esm/mcp/tambo-mcp-provider.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.test.js +3 -2
- package/esm/mcp/tambo-mcp-provider.test.js.map +1 -1
- package/esm/mcp/use-mcp-servers.test.js +2 -1
- package/esm/mcp/use-mcp-servers.test.js.map +1 -1
- package/esm/model/component-metadata.d.ts +7 -372
- package/esm/model/component-metadata.d.ts.map +1 -1
- package/esm/model/component-metadata.js.map +1 -1
- package/esm/model/validate-input.test.d.ts +2 -0
- package/esm/model/validate-input.test.d.ts.map +1 -0
- package/esm/model/validate-input.test.js +36 -0
- package/esm/model/validate-input.test.js.map +1 -0
- package/esm/providers/tambo-interactable-provider.d.ts +7 -7
- package/esm/providers/tambo-registry-provider.d.ts +1 -1
- package/esm/providers/tambo-registry-provider.d.ts.map +1 -1
- package/esm/providers/tambo-registry-provider.js.map +1 -1
- package/esm/providers/tambo-registry-schema-compat.test.js +4 -4
- package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -1
- package/esm/schema/index.d.ts +2 -4
- package/esm/schema/index.d.ts.map +1 -1
- package/esm/schema/index.js +2 -4
- package/esm/schema/index.js.map +1 -1
- package/esm/schema/json-schema.d.ts +1 -17
- package/esm/schema/json-schema.d.ts.map +1 -1
- package/esm/schema/json-schema.js +2 -67
- package/esm/schema/json-schema.js.map +1 -1
- package/esm/schema/schema.test.js +1 -2
- package/esm/schema/schema.test.js.map +1 -1
- package/esm/schema/standard-schema.test.js +1 -1
- package/esm/schema/standard-schema.test.js.map +1 -1
- package/esm/schema/validate.test.js +1 -1
- package/esm/schema/validate.test.js.map +1 -1
- package/esm/testing/tools.d.ts +4 -4
- package/esm/testing/tools.test.d.ts +2 -0
- package/esm/testing/tools.test.d.ts.map +1 -0
- package/esm/testing/tools.test.js +58 -0
- package/esm/testing/tools.test.js.map +1 -0
- package/esm/util/mcp-server-utils.d.ts +1 -1
- package/esm/util/mcp-server-utils.d.ts.map +1 -1
- package/esm/util/mcp-server-utils.js +1 -1
- package/esm/util/mcp-server-utils.js.map +1 -1
- package/esm/util/mcp-server-utils.test.js +1 -1
- package/esm/util/mcp-server-utils.test.js.map +1 -1
- package/esm/util/registry.js +1 -1
- package/esm/util/registry.js.map +1 -1
- package/esm/util/resource-content-resolver.js +1 -1
- package/esm/util/resource-content-resolver.js.map +1 -1
- package/esm/util/resource-content-resolver.test.js +2 -2
- package/esm/util/resource-content-resolver.test.js.map +1 -1
- package/esm/util/tool-caller.test.d.ts +2 -0
- package/esm/util/tool-caller.test.d.ts.map +1 -0
- package/esm/util/tool-caller.test.js +69 -0
- package/esm/util/tool-caller.test.js.map +1 -0
- package/esm/v1/__tests__/v1-interactables.test.js +1 -0
- package/esm/v1/__tests__/v1-interactables.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-auth-state.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-auth-state.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-component-state.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.js +6 -6
- package/esm/v1/hooks/use-tambo-v1-send-message.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-send-message.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js +9 -5
- package/esm/v1/hooks/use-tambo-v1-stream-status.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.js +1 -1
- package/esm/v1/hooks/use-tambo-v1-suggestions.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js +1 -0
- package/esm/v1/hooks/use-tambo-v1-thread-input.test.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.d.ts +7 -6
- package/esm/v1/hooks/use-tambo-v1.d.ts.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.js +1 -1
- package/esm/v1/hooks/use-tambo-v1.js.map +1 -1
- package/esm/v1/hooks/use-tambo-v1.test.js +22 -22
- package/esm/v1/hooks/use-tambo-v1.test.js.map +1 -1
- package/esm/v1/index.d.ts +6 -6
- package/esm/v1/index.d.ts.map +1 -1
- package/esm/v1/index.js +1 -1
- package/esm/v1/index.js.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts +2 -1
- package/esm/v1/providers/tambo-v1-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-provider.js +2 -0
- package/esm/v1/providers/tambo-v1-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.d.ts +2 -2
- package/esm/v1/providers/tambo-v1-stream-context.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.js +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stream-context.test.js +35 -0
- package/esm/v1/providers/tambo-v1-stream-context.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.js +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.js.map +1 -1
- package/esm/v1/providers/tambo-v1-stub-provider.test.js.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.d.ts.map +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.js +1 -1
- package/esm/v1/providers/tambo-v1-thread-input-provider.js.map +1 -1
- package/esm/v1/types/event.test.js +1 -1
- package/esm/v1/types/event.test.js.map +1 -1
- package/esm/v1/types/message.d.ts +12 -109
- package/esm/v1/types/message.d.ts.map +1 -1
- package/esm/v1/types/message.js +0 -7
- package/esm/v1/types/message.js.map +1 -1
- package/esm/v1/utils/event-accumulator.test.js +2 -3
- package/esm/v1/utils/event-accumulator.test.js.map +1 -1
- package/esm/v1/utils/json-patch.test.js +1 -1
- package/esm/v1/utils/json-patch.test.js.map +1 -1
- package/esm/v1/utils/keyed-throttle.test.js +1 -1
- package/esm/v1/utils/keyed-throttle.test.js.map +1 -1
- package/esm/v1/utils/registry-conversion.test.js +1 -1
- package/esm/v1/utils/registry-conversion.test.js.map +1 -1
- package/esm/v1/utils/stream-handler.test.js +1 -1
- package/esm/v1/utils/stream-handler.test.js.map +1 -1
- package/esm/v1/utils/tool-call-tracker.test.js +9 -3
- package/esm/v1/utils/tool-call-tracker.test.js.map +1 -1
- package/esm/v1/utils/tool-executor.test.js +1 -2
- package/esm/v1/utils/tool-executor.test.js.map +1 -1
- package/esm/v1/utils/unstrictify.test.js +1 -1
- package/esm/v1/utils/unstrictify.test.js.map +1 -1
- package/package.json +10 -11
- package/dist/mcp/mcp-client.d.ts +0 -185
- package/dist/mcp/mcp-client.d.ts.map +0 -1
- package/dist/mcp/mcp-client.js +0 -219
- package/dist/mcp/mcp-client.js.map +0 -1
- package/dist/mcp/mcp-constants.d.ts +0 -19
- package/dist/mcp/mcp-constants.d.ts.map +0 -1
- package/dist/mcp/mcp-constants.js +0 -21
- package/dist/mcp/mcp-constants.js.map +0 -1
- package/dist/model/mcp-server-info.d.ts +0 -76
- package/dist/model/mcp-server-info.d.ts.map +0 -1
- package/dist/model/mcp-server-info.js +0 -29
- package/dist/model/mcp-server-info.js.map +0 -1
- package/dist/schema/schema.d.ts +0 -49
- package/dist/schema/schema.d.ts.map +0 -1
- package/dist/schema/schema.js +0 -129
- package/dist/schema/schema.js.map +0 -1
- package/dist/schema/standard-schema.d.ts +0 -22
- package/dist/schema/standard-schema.d.ts.map +0 -1
- package/dist/schema/standard-schema.js +0 -42
- package/dist/schema/standard-schema.js.map +0 -1
- package/dist/schema/validate.d.ts +0 -14
- package/dist/schema/validate.d.ts.map +0 -1
- package/dist/schema/validate.js +0 -148
- package/dist/schema/validate.js.map +0 -1
- package/dist/v1/types/auth.d.ts +0 -24
- package/dist/v1/types/auth.d.ts.map +0 -1
- package/dist/v1/types/auth.js +0 -3
- package/dist/v1/types/auth.js.map +0 -1
- package/dist/v1/types/event.d.ts +0 -89
- package/dist/v1/types/event.d.ts.map +0 -1
- package/dist/v1/types/event.js +0 -57
- package/dist/v1/types/event.js.map +0 -1
- package/dist/v1/types/thread.d.ts +0 -58
- package/dist/v1/types/thread.d.ts.map +0 -1
- package/dist/v1/types/thread.js +0 -9
- package/dist/v1/types/thread.js.map +0 -1
- package/dist/v1/types/tool-choice.d.ts +0 -8
- package/dist/v1/types/tool-choice.d.ts.map +0 -1
- package/dist/v1/types/tool-choice.js +0 -3
- package/dist/v1/types/tool-choice.js.map +0 -1
- package/dist/v1/utils/event-accumulator.d.ts +0 -165
- package/dist/v1/utils/event-accumulator.d.ts.map +0 -1
- package/dist/v1/utils/event-accumulator.js +0 -1277
- package/dist/v1/utils/event-accumulator.js.map +0 -1
- package/dist/v1/utils/json-patch.d.ts +0 -18
- package/dist/v1/utils/json-patch.d.ts.map +0 -1
- package/dist/v1/utils/json-patch.js +0 -35
- package/dist/v1/utils/json-patch.js.map +0 -1
- package/dist/v1/utils/keyed-throttle.d.ts +0 -42
- package/dist/v1/utils/keyed-throttle.d.ts.map +0 -1
- package/dist/v1/utils/keyed-throttle.js +0 -86
- package/dist/v1/utils/keyed-throttle.js.map +0 -1
- package/dist/v1/utils/registry-conversion.d.ts +0 -53
- package/dist/v1/utils/registry-conversion.d.ts.map +0 -1
- package/dist/v1/utils/registry-conversion.js +0 -115
- package/dist/v1/utils/registry-conversion.js.map +0 -1
- package/dist/v1/utils/stream-handler.d.ts +0 -45
- package/dist/v1/utils/stream-handler.d.ts.map +0 -1
- package/dist/v1/utils/stream-handler.js +0 -47
- package/dist/v1/utils/stream-handler.js.map +0 -1
- package/dist/v1/utils/thread-utils.d.ts +0 -16
- package/dist/v1/utils/thread-utils.d.ts.map +0 -1
- package/dist/v1/utils/thread-utils.js +0 -34
- package/dist/v1/utils/thread-utils.js.map +0 -1
- package/dist/v1/utils/tool-call-tracker.d.ts +0 -73
- package/dist/v1/utils/tool-call-tracker.d.ts.map +0 -1
- package/dist/v1/utils/tool-call-tracker.js +0 -180
- package/dist/v1/utils/tool-call-tracker.js.map +0 -1
- package/dist/v1/utils/tool-executor.d.ts +0 -67
- package/dist/v1/utils/tool-executor.d.ts.map +0 -1
- package/dist/v1/utils/tool-executor.js +0 -160
- package/dist/v1/utils/tool-executor.js.map +0 -1
- package/dist/v1/utils/unstrictify.d.ts +0 -32
- package/dist/v1/utils/unstrictify.d.ts.map +0 -1
- package/dist/v1/utils/unstrictify.js +0 -159
- package/dist/v1/utils/unstrictify.js.map +0 -1
- package/esm/mcp/mcp-client.d.ts +0 -185
- package/esm/mcp/mcp-client.d.ts.map +0 -1
- package/esm/mcp/mcp-client.js +0 -216
- package/esm/mcp/mcp-client.js.map +0 -1
- package/esm/mcp/mcp-constants.d.ts +0 -19
- package/esm/mcp/mcp-constants.d.ts.map +0 -1
- package/esm/mcp/mcp-constants.js +0 -18
- package/esm/mcp/mcp-constants.js.map +0 -1
- package/esm/model/mcp-server-info.d.ts +0 -76
- package/esm/model/mcp-server-info.d.ts.map +0 -1
- package/esm/model/mcp-server-info.js +0 -25
- package/esm/model/mcp-server-info.js.map +0 -1
- package/esm/schema/schema.d.ts +0 -49
- package/esm/schema/schema.d.ts.map +0 -1
- package/esm/schema/schema.js +0 -124
- package/esm/schema/schema.js.map +0 -1
- package/esm/schema/standard-schema.d.ts +0 -22
- package/esm/schema/standard-schema.d.ts.map +0 -1
- package/esm/schema/standard-schema.js +0 -39
- package/esm/schema/standard-schema.js.map +0 -1
- package/esm/schema/validate.d.ts +0 -14
- package/esm/schema/validate.d.ts.map +0 -1
- package/esm/schema/validate.js +0 -145
- package/esm/schema/validate.js.map +0 -1
- package/esm/v1/types/auth.d.ts +0 -24
- package/esm/v1/types/auth.d.ts.map +0 -1
- package/esm/v1/types/auth.js +0 -2
- package/esm/v1/types/auth.js.map +0 -1
- package/esm/v1/types/event.d.ts +0 -89
- package/esm/v1/types/event.d.ts.map +0 -1
- package/esm/v1/types/event.js +0 -53
- package/esm/v1/types/event.js.map +0 -1
- package/esm/v1/types/thread.d.ts +0 -58
- package/esm/v1/types/thread.d.ts.map +0 -1
- package/esm/v1/types/thread.js +0 -8
- package/esm/v1/types/thread.js.map +0 -1
- package/esm/v1/types/tool-choice.d.ts +0 -8
- package/esm/v1/types/tool-choice.d.ts.map +0 -1
- package/esm/v1/types/tool-choice.js +0 -2
- package/esm/v1/types/tool-choice.js.map +0 -1
- package/esm/v1/utils/event-accumulator.d.ts +0 -165
- package/esm/v1/utils/event-accumulator.d.ts.map +0 -1
- package/esm/v1/utils/event-accumulator.js +0 -1268
- package/esm/v1/utils/event-accumulator.js.map +0 -1
- package/esm/v1/utils/json-patch.d.ts +0 -18
- package/esm/v1/utils/json-patch.d.ts.map +0 -1
- package/esm/v1/utils/json-patch.js +0 -32
- package/esm/v1/utils/json-patch.js.map +0 -1
- package/esm/v1/utils/keyed-throttle.d.ts +0 -42
- package/esm/v1/utils/keyed-throttle.d.ts.map +0 -1
- package/esm/v1/utils/keyed-throttle.js +0 -83
- package/esm/v1/utils/keyed-throttle.js.map +0 -1
- package/esm/v1/utils/registry-conversion.d.ts +0 -53
- package/esm/v1/utils/registry-conversion.d.ts.map +0 -1
- package/esm/v1/utils/registry-conversion.js +0 -109
- package/esm/v1/utils/registry-conversion.js.map +0 -1
- package/esm/v1/utils/stream-handler.d.ts +0 -45
- package/esm/v1/utils/stream-handler.d.ts.map +0 -1
- package/esm/v1/utils/stream-handler.js +0 -44
- package/esm/v1/utils/stream-handler.js.map +0 -1
- package/esm/v1/utils/thread-utils.d.ts +0 -16
- package/esm/v1/utils/thread-utils.d.ts.map +0 -1
- package/esm/v1/utils/thread-utils.js +0 -31
- package/esm/v1/utils/thread-utils.js.map +0 -1
- package/esm/v1/utils/tool-call-tracker.d.ts +0 -73
- package/esm/v1/utils/tool-call-tracker.d.ts.map +0 -1
- package/esm/v1/utils/tool-call-tracker.js +0 -176
- package/esm/v1/utils/tool-call-tracker.js.map +0 -1
- package/esm/v1/utils/tool-executor.d.ts +0 -67
- package/esm/v1/utils/tool-executor.d.ts.map +0 -1
- package/esm/v1/utils/tool-executor.js +0 -154
- package/esm/v1/utils/tool-executor.js.map +0 -1
- package/esm/v1/utils/unstrictify.d.ts +0 -32
- package/esm/v1/utils/unstrictify.d.ts.map +0 -1
- package/esm/v1/utils/unstrictify.js +0 -155
- package/esm/v1/utils/unstrictify.js.map +0 -1
|
@@ -36,13 +36,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.useTamboElicitationContext = exports.useTamboMcpElicitation = exports.useTamboMcpServers = exports.TamboMcpProvider = void 0;
|
|
37
37
|
exports.extractErrorMessage = extractErrorMessage;
|
|
38
38
|
const react_1 = __importStar(require("react"));
|
|
39
|
-
const
|
|
40
|
-
const mcp_server_info_1 = require("../model/mcp-server-info");
|
|
39
|
+
const client_1 = require("@tambo-ai/client");
|
|
41
40
|
const tambo_mcp_token_provider_1 = require("../providers/tambo-mcp-token-provider");
|
|
42
41
|
const tambo_registry_provider_1 = require("../providers/tambo-registry-provider");
|
|
43
42
|
const content_parts_1 = require("../util/content-parts");
|
|
44
43
|
const elicitation_1 = require("./elicitation");
|
|
45
|
-
const
|
|
44
|
+
const client_2 = require("@tambo-ai/client");
|
|
46
45
|
/**
|
|
47
46
|
* Extracts error message from MCP tool result content.
|
|
48
47
|
* Handles both array and string content formats.
|
|
@@ -144,7 +143,7 @@ function useServerConfigs(mcpServers, mcpAccessToken, tamboBaseUrl) {
|
|
|
144
143
|
const serverMap = new Map();
|
|
145
144
|
// Add user-provided MCP servers (browser-side)
|
|
146
145
|
mcpServers.forEach((server) => {
|
|
147
|
-
const serverInfo = normalizeServerInfo(server,
|
|
146
|
+
const serverInfo = normalizeServerInfo(server, client_1.ServerType.BROWSER_SIDE);
|
|
148
147
|
serverMap.set(serverInfo.key, serverInfo);
|
|
149
148
|
});
|
|
150
149
|
// Add internal Tambo MCP server if we have an access token and a base URL
|
|
@@ -156,13 +155,13 @@ function useServerConfigs(mcpServers, mcpAccessToken, tamboBaseUrl) {
|
|
|
156
155
|
const internalServer = {
|
|
157
156
|
name: TAMBO_INTERNAL_MCP_SERVER_NAME,
|
|
158
157
|
url: tamboMcpUrl,
|
|
159
|
-
transport:
|
|
158
|
+
transport: client_2.MCPTransport.HTTP,
|
|
160
159
|
serverKey: `tambo-${tokenHash}`,
|
|
161
160
|
customHeaders: {
|
|
162
161
|
Authorization: `Bearer ${mcpAccessToken}`,
|
|
163
162
|
},
|
|
164
163
|
};
|
|
165
|
-
const serverInfo = normalizeServerInfo(internalServer,
|
|
164
|
+
const serverInfo = normalizeServerInfo(internalServer, client_1.ServerType.TAMBO_INTERNAL);
|
|
166
165
|
serverMap.set(serverInfo.key, serverInfo);
|
|
167
166
|
}
|
|
168
167
|
return serverMap;
|
|
@@ -310,7 +309,7 @@ function useClientLifecycle(currentServersMap, clientMapRef, ownershipRefs, prov
|
|
|
310
309
|
const serverInfo = currentServersMap.get(key);
|
|
311
310
|
try {
|
|
312
311
|
const effectiveHandlers = buildEffectiveHandlers(serverInfo, providerElicitationHandler, providerSamplingHandler);
|
|
313
|
-
const client = await
|
|
312
|
+
const client = await client_2.MCPClient.create(serverInfo.url, serverInfo.transport, serverInfo.customHeaders, undefined, undefined, effectiveHandlers);
|
|
314
313
|
const connectedServer = {
|
|
315
314
|
...serverInfo,
|
|
316
315
|
client,
|
|
@@ -469,8 +468,8 @@ exports.useTamboElicitationContext = exports.useTamboMcpElicitation;
|
|
|
469
468
|
* Normalizes registry server metadata into a `McpServerConfig`.
|
|
470
469
|
*
|
|
471
470
|
* Accepts a `NormalizedMcpServerInfo`, which already guarantees a concrete
|
|
472
|
-
* `transport
|
|
473
|
-
*
|
|
471
|
+
* `transport`, a `serverKey` derived by the registry, and a typed
|
|
472
|
+
* `handlers` field (`Partial<MCPHandlers>`).
|
|
474
473
|
* @param server - The normalized MCP server info from the registry
|
|
475
474
|
* @param serverType - The type of server (internal vs browser-side)
|
|
476
475
|
* @returns The server config with typed handlers, unique key, and server type
|
|
@@ -480,12 +479,9 @@ function normalizeServerInfo(server, serverType) {
|
|
|
480
479
|
// that changes to URL, transport, or customHeaders trigger client recreation.
|
|
481
480
|
// The serverKey is kept for namespacing purposes (readable short name),
|
|
482
481
|
// but the connection identity key must include all connection properties.
|
|
483
|
-
const key = (0,
|
|
484
|
-
// Cast handlers to proper type if present
|
|
485
|
-
const handlers = server.handlers;
|
|
482
|
+
const key = (0, client_1.getMcpServerUniqueKey)(server);
|
|
486
483
|
return {
|
|
487
484
|
...server,
|
|
488
|
-
handlers,
|
|
489
485
|
key,
|
|
490
486
|
serverType,
|
|
491
487
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tambo-mcp-provider.js","sourceRoot":"","sources":["../../src/mcp/tambo-mcp-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {\n createContext,\n FC,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { ServerType } from \"./mcp-constants\";\nimport {\n getMcpServerUniqueKey,\n type NormalizedMcpServerInfo,\n} from \"../model/mcp-server-info\";\nimport { useTamboMcpToken } from \"../providers/tambo-mcp-token-provider\";\nimport {\n useTamboMcpServerInfos,\n useTamboRegistry,\n} from \"../providers/tambo-registry-provider\";\nimport { isContentPartArray, toText } from \"../util/content-parts\";\nimport { type ElicitationContextState, useElicitation } from \"./elicitation\";\nimport {\n MCPClient,\n MCPElicitationHandler,\n MCPHandlers,\n MCPSamplingHandler,\n MCPTransport,\n} from \"./mcp-client\";\n\n/**\n * Extracts error message from MCP tool result content.\n * Handles both array and string content formats.\n * Always returns a string, even for invalid/null inputs.\n * @returns The extracted error message as a string\n */\nexport function extractErrorMessage(content: unknown): string {\n if (content === undefined || content === null) {\n return \"Unknown error occurred\";\n }\n\n if (Array.isArray(content)) {\n const textItems = content\n .filter((item) => item?.type === \"text\" && typeof item.text === \"string\")\n .map((item) => item.text);\n\n return textItems.length > 0\n ? textItems.join(\" \")\n : \"Error occurred but no details provided\";\n }\n\n if (typeof content === \"object\") {\n return JSON.stringify(content);\n }\n\n return `${content}`;\n}\n\n/**\n * Normalized MCP server information as consumed by the provider.\n *\n * Extends `NormalizedMcpServerInfo` from the core model by:\n * - narrowing `handlers` to `Partial<MCPHandlers>`\n * - adding a stable `key` derived from URL/transport/headers\n * - adding `serverType` to distinguish internal vs browser-side servers\n *\n * The registry is responsible for producing `NormalizedMcpServerInfo`\n * instances; this type adds the MCP-specific wiring needed to connect and\n * track clients.\n */\ninterface McpServerConfig extends NormalizedMcpServerInfo {\n /**\n * Optional handlers for elicitation and sampling requests from the server.\n * Interpreted as a partial set of MCP handlers.\n */\n handlers?: Partial<MCPHandlers>;\n /**\n * Stable identity for this server derived from its URL/transport/headers.\n * Present for all server states (connected or failed).\n */\n key: string;\n /**\n * Type of server - determines how resources are resolved.\n * Internal servers are resolved server-side, browser-side servers are resolved client-side.\n */\n serverType: ServerType;\n}\n\n/**\n * Connected MCP server with an active client.\n */\nexport interface ConnectedMcpServer extends McpServerConfig {\n client: MCPClient;\n}\n\n/**\n * Failed MCP server with a connection error.\n */\nexport interface FailedMcpServer extends McpServerConfig {\n client?: never;\n connectionError: Error;\n}\n\n/**\n * An active or failed MCP server, with access to the MCP client.\n */\nexport type McpServer = ConnectedMcpServer | FailedMcpServer;\n\n/**\n * Provider-level MCP handlers that receive the McpServerInfo as context in addition to the request.\n * These handlers are applied to all MCP servers unless overridden by per-server handlers.\n *\n * Handlers receive three parameters:\n * 1. request - The MCP request\n * 2. extra - RequestHandlerExtra containing AbortSignal and other metadata\n * 3. serverInfo - Configuration of the MCP server that triggered this request\n */\nexport interface ProviderMCPHandlers {\n elicitation?: (\n request: Parameters<MCPElicitationHandler>[0],\n extra: Parameters<MCPElicitationHandler>[1],\n serverInfo: McpServerConfig,\n ) => ReturnType<MCPElicitationHandler>;\n sampling?: (\n request: Parameters<MCPSamplingHandler>[0],\n extra: Parameters<MCPSamplingHandler>[1],\n serverInfo: McpServerConfig,\n ) => ReturnType<MCPSamplingHandler>;\n}\n\n/**\n * Context value for MCP provider including server list and elicitation state\n */\ninterface McpProviderContextValue extends ElicitationContextState {\n servers: McpServer[];\n}\n\nconst McpProviderContext = createContext<McpProviderContextValue>({\n servers: [],\n elicitation: null,\n resolveElicitation: null,\n});\n\n// Constant for the internal Tambo MCP server name\nconst TAMBO_INTERNAL_MCP_SERVER_NAME = \"__tambo_internal_mcp_server__\";\n\n/**\n * Creates a stable hash of a string for use as a cache key.\n * Uses Java-style string hashing (DJB2-like) for deterministic results.\n *\n * Note: We use a synchronous hash instead of crypto.subtle.digest because:\n * - crypto.subtle.digest is async, which adds complexity in React hooks (useMemo, useEffect)\n * - This is not for security, just for creating a stable identifier to detect token changes\n * - Synchronous hashing avoids race conditions and simplifies component lifecycle\n * @param input - The string to hash\n * @returns A compact base36 hash string\n */\nfunction hashString(input: string): string {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n hash = (Math.imul(31, hash) + input.charCodeAt(i)) | 0;\n }\n return (hash >>> 0).toString(36);\n}\n\n/**\n * Safely closes an MCP client, handling both sync and async close methods.\n * Logs errors but doesn't throw.\n */\nfunction closeClientSafely(server: McpServer): void {\n if (!server?.client?.close) return;\n\n try {\n const closeResult = server.client.close();\n // If it returns a promise, handle errors but don't wait\n if (closeResult && typeof closeResult.catch === \"function\") {\n void closeResult.catch((error) => {\n const url = server.url ?? \"(unknown url)\";\n console.error(`Error closing MCP client for ${url}:`, error);\n });\n }\n } catch (error) {\n const url = server.url ?? \"(unknown url)\";\n console.error(`Error closing MCP client for ${url}:`, error);\n }\n}\n\n/**\n * Builds effective handlers for a server, with per-server overrides taking\n * precedence over provider-level handlers.\n * @returns The effective handlers with per-server overrides applied\n */\nfunction buildEffectiveHandlers(\n serverInfo: McpServerConfig,\n providerElicitationHandler: ProviderMCPHandlers[\"elicitation\"] | undefined,\n providerSamplingHandler: ProviderMCPHandlers[\"sampling\"] | undefined,\n): Partial<MCPHandlers> {\n const effectiveHandlers: Partial<MCPHandlers> = {};\n\n if (serverInfo.handlers?.elicitation) {\n effectiveHandlers.elicitation = serverInfo.handlers.elicitation;\n } else if (providerElicitationHandler) {\n effectiveHandlers.elicitation = async (\n request: Parameters<MCPElicitationHandler>[0],\n extra: Parameters<MCPElicitationHandler>[1],\n ) => await providerElicitationHandler(request, extra, serverInfo);\n }\n\n if (serverInfo.handlers?.sampling) {\n effectiveHandlers.sampling = serverInfo.handlers.sampling;\n } else if (providerSamplingHandler) {\n effectiveHandlers.sampling = async (\n request: Parameters<MCPSamplingHandler>[0],\n extra: Parameters<MCPSamplingHandler>[1],\n ) => await providerSamplingHandler(request, extra, serverInfo);\n }\n\n return effectiveHandlers;\n}\n\n/**\n * Hook to compute the stable map of server configurations from registry servers\n * and the internal Tambo MCP server (when token is available).\n * @returns A map of server key to server configuration\n */\nfunction useServerConfigs(\n mcpServers: NormalizedMcpServerInfo[],\n mcpAccessToken: string | null | undefined,\n tamboBaseUrl: string | null | undefined,\n): Map<string, McpServerConfig> {\n return useMemo(() => {\n const serverMap = new Map<string, McpServerConfig>();\n\n // Add user-provided MCP servers (browser-side)\n mcpServers.forEach((server) => {\n const serverInfo = normalizeServerInfo(server, ServerType.BROWSER_SIDE);\n serverMap.set(serverInfo.key, serverInfo);\n });\n\n // Add internal Tambo MCP server if we have an access token and a base URL\n if (mcpAccessToken && tamboBaseUrl) {\n const base = new URL(tamboBaseUrl);\n base.pathname = `${base.pathname.replace(/\\/+$/, \"\")}/mcp`;\n const tamboMcpUrl = base.toString();\n const tokenHash = hashString(mcpAccessToken);\n const internalServer: NormalizedMcpServerInfo = {\n name: TAMBO_INTERNAL_MCP_SERVER_NAME,\n url: tamboMcpUrl,\n transport: MCPTransport.HTTP,\n serverKey: `tambo-${tokenHash}`,\n customHeaders: {\n Authorization: `Bearer ${mcpAccessToken}`,\n },\n };\n const serverInfo = normalizeServerInfo(\n internalServer,\n ServerType.TAMBO_INTERNAL,\n );\n serverMap.set(serverInfo.key, serverInfo);\n }\n\n return serverMap;\n }, [mcpServers, mcpAccessToken, tamboBaseUrl]);\n}\n\ninterface ToolOwnershipRefs {\n toolOwnerRef: React.MutableRefObject<Map<string, string>>;\n keyToToolsRef: React.MutableRefObject<Map<string, Set<string>>>;\n}\n\n/**\n * Registers tools from a connected MCP server with deduplication.\n */\nasync function registerServerTools(\n client: MCPClient,\n serverInfo: McpServerConfig,\n key: string,\n shouldPrefix: boolean,\n clientMap: Map<string, McpServer>,\n ownershipRefs: ToolOwnershipRefs,\n registerTool: ReturnType<typeof useTamboRegistry>[\"registerTool\"],\n): Promise<void> {\n const { toolOwnerRef, keyToToolsRef } = ownershipRefs;\n\n try {\n const tools = await client.listTools();\n\n tools.forEach((tool) => {\n const toolName = shouldPrefix\n ? `${serverInfo.serverKey}__${tool.name}`\n : tool.name;\n\n // Skip if another server already owns this tool\n const currentOwner = toolOwnerRef.current.get(toolName);\n if (currentOwner && currentOwner !== key) {\n return;\n }\n\n // Record ownership\n if (!currentOwner) {\n toolOwnerRef.current.set(toolName, key);\n if (!keyToToolsRef.current.has(key)) {\n keyToToolsRef.current.set(key, new Set());\n }\n keyToToolsRef.current.get(key)!.add(toolName);\n }\n\n registerTool({\n description: tool.description ?? \"\",\n name: toolName,\n tool: async (args: Record<string, unknown> = {}) => {\n const server = clientMap.get(key);\n if (!server?.client) {\n throw new Error(\n `MCP server for tool ${tool.name} is not connected`,\n );\n }\n const result = await server.client.callTool(tool.name, args);\n if (result.isError) {\n const errorMessage = extractErrorMessage(result.content);\n throw new Error(errorMessage);\n }\n return result.content;\n },\n inputSchema: tool.inputSchema ?? {},\n outputSchema: {},\n transformToContent: (content: unknown) => {\n if (isContentPartArray(content)) {\n return content;\n }\n return [{ type: \"text\", text: toText(content) }];\n },\n ...(\"maxCalls\" in tool && tool.maxCalls !== undefined\n ? { maxCalls: tool.maxCalls }\n : {}),\n });\n });\n } catch (error) {\n console.error(\n `Failed to register tools from MCP server ${serverInfo.url}:`,\n error,\n );\n }\n}\n\n/**\n * Releases tool ownership for a server being removed.\n */\nfunction releaseToolOwnership(\n key: string,\n ownershipRefs: ToolOwnershipRefs,\n): void {\n const { toolOwnerRef, keyToToolsRef } = ownershipRefs;\n const owned = keyToToolsRef.current.get(key);\n if (owned) {\n for (const name of owned) {\n toolOwnerRef.current.delete(name);\n }\n keyToToolsRef.current.delete(key);\n }\n}\n\n/**\n * This provider is used to register tools from MCP servers.\n * It automatically includes an internal Tambo MCP server when an MCP access token is available.\n *\n * **BREAKING CHANGE**: This provider no longer accepts `mcpServers` as a prop.\n * Instead, pass `mcpServers` to `TamboProvider` or `TamboRegistryProvider`.\n * This provider must be wrapped inside `TamboProvider` to access the MCP server registry.\n * @param props - The provider props\n * @param props.handlers - Optional handlers applied to all MCP servers unless overridden per-server\n * @param props.contextKey - Optional context key for fetching threadless MCP tokens when not in a thread\n * @param props.children - The children to wrap\n * @returns The TamboMcpProvider component\n */\nexport const TamboMcpProvider: FC<{\n handlers?: ProviderMCPHandlers;\n contextKey?: string;\n children: React.ReactNode;\n}> = ({ handlers, contextKey, children }) => {\n const { registerTool } = useTamboRegistry();\n const { mcpAccessToken, tamboBaseUrl } = useTamboMcpToken(contextKey);\n const mcpServers = useTamboMcpServerInfos();\n const providerSamplingHandler = handlers?.sampling;\n\n // Elicitation state and default handler\n const { elicitation, resolveElicitation, defaultElicitationHandler } =\n useElicitation();\n\n // Use provided handler or fall back to default\n const providerElicitationHandler =\n handlers?.elicitation ?? defaultElicitationHandler;\n\n // Stable reference to track active clients by server key\n const clientMapRef = useRef<Map<string, McpServer>>(new Map());\n // Track tool ownership to prevent duplicate registrations across servers\n const toolOwnerRef = useRef<Map<string, string>>(new Map());\n const keyToToolsRef = useRef<Map<string, Set<string>>>(new Map());\n const ownershipRefs: ToolOwnershipRefs = { toolOwnerRef, keyToToolsRef };\n\n // State for exposing connected servers to consumers\n const [connectedMcpServers, setConnectedMcpServers] = useState<McpServer[]>(\n [],\n );\n\n // Compute server configurations from registry and internal server\n const currentServersMap = useServerConfigs(\n mcpServers,\n mcpAccessToken,\n tamboBaseUrl,\n );\n\n // Main effect: manage client lifecycle (create/remove)\n useClientLifecycle(\n currentServersMap,\n clientMapRef,\n ownershipRefs,\n providerElicitationHandler,\n providerSamplingHandler,\n registerTool,\n setConnectedMcpServers,\n );\n\n // Update handlers when they change (without recreating clients)\n useHandlerUpdates(\n currentServersMap,\n clientMapRef,\n providerElicitationHandler,\n providerSamplingHandler,\n );\n\n // Cleanup on unmount: close all clients\n useCleanupOnUnmount(clientMapRef, ownershipRefs);\n\n const contextValue = useMemo(\n () => ({\n servers: connectedMcpServers,\n elicitation,\n resolveElicitation,\n }),\n [connectedMcpServers, elicitation, resolveElicitation],\n );\n\n return (\n <McpProviderContext.Provider value={contextValue}>\n {children}\n </McpProviderContext.Provider>\n );\n};\n\n/**\n * Hook to manage client lifecycle: creating clients for new servers,\n * removing clients for servers that are no longer in the list.\n */\nfunction useClientLifecycle(\n currentServersMap: Map<string, McpServerConfig>,\n clientMapRef: React.MutableRefObject<Map<string, McpServer>>,\n ownershipRefs: ToolOwnershipRefs,\n providerElicitationHandler: ProviderMCPHandlers[\"elicitation\"] | undefined,\n providerSamplingHandler: ProviderMCPHandlers[\"sampling\"] | undefined,\n registerTool: ReturnType<typeof useTamboRegistry>[\"registerTool\"],\n setConnectedMcpServers: React.Dispatch<React.SetStateAction<McpServer[]>>,\n): void {\n useEffect(() => {\n const clientMap = clientMapRef.current;\n const currentKeys = new Set(currentServersMap.keys());\n const existingKeys = new Set(clientMap.keys());\n\n // 1. Remove clients that are no longer in the current server list\n const keysToRemove = Array.from(existingKeys).filter(\n (key) => !currentKeys.has(key),\n );\n keysToRemove.forEach((key) => {\n const server = clientMap.get(key);\n if (server) {\n closeClientSafely(server);\n }\n releaseToolOwnership(key, ownershipRefs);\n clientMap.delete(key);\n });\n\n // 2. Add new clients for servers that don't exist yet\n const keysToAdd = Array.from(currentKeys).filter(\n (key) => !existingKeys.has(key),\n );\n\n async function addClients(keys: string[]) {\n await Promise.allSettled(\n keys.map(async (key) => {\n const serverInfo = currentServersMap.get(key)!;\n\n try {\n const effectiveHandlers = buildEffectiveHandlers(\n serverInfo,\n providerElicitationHandler,\n providerSamplingHandler,\n );\n\n const client = await MCPClient.create(\n serverInfo.url,\n serverInfo.transport,\n serverInfo.customHeaders,\n undefined,\n undefined,\n effectiveHandlers,\n );\n\n const connectedServer: ConnectedMcpServer = {\n ...serverInfo,\n client,\n };\n\n clientMap.set(key, connectedServer);\n setConnectedMcpServers(Array.from(clientMap.values()));\n\n // Register tools from this server\n const shouldPrefix = currentServersMap.size > 1;\n await registerServerTools(\n client,\n serverInfo,\n key,\n shouldPrefix,\n clientMap,\n ownershipRefs,\n registerTool,\n );\n } catch (error) {\n const failedServer: FailedMcpServer = {\n ...serverInfo,\n connectionError: error as Error,\n };\n clientMap.set(key, failedServer);\n setConnectedMcpServers(Array.from(clientMap.values()));\n console.error(\n `Failed to connect to MCP server ${serverInfo.url}:`,\n error,\n );\n }\n }),\n );\n }\n\n if (keysToAdd.length > 0) {\n addClients(keysToAdd).catch((err) => {\n console.error(\"Unexpected error in addClients:\", err);\n });\n }\n\n // Update state after removals\n if (keysToRemove.length > 0) {\n setConnectedMcpServers(Array.from(clientMap.values()));\n }\n // Note: refs (clientMapRef, ownershipRefs) and setters (setConnectedMcpServers)\n // are intentionally excluded from deps as they are stable references\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n currentServersMap,\n providerElicitationHandler,\n providerSamplingHandler,\n registerTool,\n ]);\n}\n\n/**\n * Hook to update handlers on connected clients when provider handlers change.\n */\nfunction useHandlerUpdates(\n currentServersMap: Map<string, McpServerConfig>,\n clientMapRef: React.MutableRefObject<Map<string, McpServer>>,\n providerElicitationHandler: ProviderMCPHandlers[\"elicitation\"] | undefined,\n providerSamplingHandler: ProviderMCPHandlers[\"sampling\"] | undefined,\n): void {\n useEffect(() => {\n const clientMap = clientMapRef.current;\n\n clientMap.forEach((server, key) => {\n if (!server.client) {\n return; // Skip failed servers\n }\n\n const serverInfo = currentServersMap.get(key);\n if (!serverInfo) {\n return; // Server was removed, handled by lifecycle effect\n }\n\n // Build effective handlers and update the client\n const effectiveElicitationHandler =\n serverInfo.handlers?.elicitation ??\n (providerElicitationHandler\n ? async (\n request: Parameters<MCPElicitationHandler>[0],\n extra: Parameters<MCPElicitationHandler>[1],\n ) => await providerElicitationHandler(request, extra, serverInfo)\n : undefined);\n\n const effectiveSamplingHandler =\n serverInfo.handlers?.sampling ??\n (providerSamplingHandler\n ? async (\n request: Parameters<MCPSamplingHandler>[0],\n extra: Parameters<MCPSamplingHandler>[1],\n ) => await providerSamplingHandler(request, extra, serverInfo)\n : undefined);\n\n server.client.updateElicitationHandler?.(effectiveElicitationHandler);\n server.client.updateSamplingHandler?.(effectiveSamplingHandler);\n });\n // Note: clientMapRef is intentionally excluded from deps as it's a stable ref\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [currentServersMap, providerElicitationHandler, providerSamplingHandler]);\n}\n\n/**\n * Hook to cleanup all clients and tool ownership on component unmount.\n */\nfunction useCleanupOnUnmount(\n clientMapRef: React.MutableRefObject<Map<string, McpServer>>,\n ownershipRefs: ToolOwnershipRefs,\n): void {\n useEffect(() => {\n const clientMap = clientMapRef.current;\n const { toolOwnerRef, keyToToolsRef } = ownershipRefs;\n return () => {\n clientMap.forEach((server) => {\n closeClientSafely(server);\n });\n clientMap.clear();\n toolOwnerRef.current.clear();\n keyToToolsRef.current.clear();\n };\n // Only run cleanup on unmount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n}\n\n/**\n * Hook to access the actual MCP servers, as they are connected (or fail to\n * connect).\n *\n * You can call methods on the MCP client that is included in the MCP server\n * object.\n *\n * If the server fails to connect, the `client` property will be `undefined` and\n * the `connectionError` property will be set.\n *\n * For example, to forcibly disconnect and reconnect all MCP servers:\n *\n * ```tsx\n * const mcpServers = useTamboMcpServers();\n * mcpServers.forEach((mcpServer) => {\n * mcpServer.client?.reconnect();\n * });\n * ```\n *\n * Note that the MCP servers are not guaranteed to be in the same order as the\n * input array, because they are added as they are connected.\n * @returns The MCP servers\n */\nexport const useTamboMcpServers = () => {\n return useContext(McpProviderContext).servers;\n};\n\n/**\n * Hook to access MCP elicitation state from TamboMcpProvider.\n * This provides access to the current elicitation request and methods to respond to it.\n *\n * The elicitation state is automatically managed by TamboMcpProvider when MCP servers\n * request user input through the elicitation protocol.\n * @returns The elicitation state with current request and response handler\n * @example\n * ```tsx\n * function ElicitationUI() {\n * const { elicitation, resolveElicitation } = useTamboMcpElicitation();\n *\n * if (!elicitation) return null;\n *\n * return (\n * <div>\n * <p>{elicitation.message}</p>\n * <button onClick={() => resolveElicitation?.({ action: \"accept\", content: {} })}>\n * Accept\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport const useTamboMcpElicitation = (): ElicitationContextState => {\n const context = useContext(McpProviderContext);\n return {\n elicitation: context.elicitation,\n resolveElicitation: context.resolveElicitation,\n };\n};\n\n/**\n * @deprecated Use `useTamboMcpElicitation` instead.\n * This hook will be removed in a future version.\n */\nexport const useTamboElicitationContext = useTamboMcpElicitation;\n\n/**\n * Normalizes registry server metadata into a `McpServerConfig`.\n *\n * Accepts a `NormalizedMcpServerInfo`, which already guarantees a concrete\n * `transport` and a `serverKey` derived by the registry, and narrows the\n * opaque `handlers` field to `Partial<MCPHandlers>`.\n * @param server - The normalized MCP server info from the registry\n * @param serverType - The type of server (internal vs browser-side)\n * @returns The server config with typed handlers, unique key, and server type\n */\nfunction normalizeServerInfo(\n server: NormalizedMcpServerInfo,\n serverType: ServerType,\n): McpServerConfig {\n // Always use getMcpServerUniqueKey for connection identity to ensure\n // that changes to URL, transport, or customHeaders trigger client recreation.\n // The serverKey is kept for namespacing purposes (readable short name),\n // but the connection identity key must include all connection properties.\n const key = getMcpServerUniqueKey(server);\n // Cast handlers to proper type if present\n const handlers = server.handlers as Partial<MCPHandlers> | undefined;\n return {\n ...server,\n handlers,\n key,\n serverType,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tambo-mcp-provider.js","sourceRoot":"","sources":["../../src/mcp/tambo-mcp-provider.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,kDAoBC;AAvDD,+CAQe;AACf,6CAI0B;AAC1B,oFAAyE;AACzE,kFAG8C;AAC9C,yDAAmE;AACnE,+CAA6E;AAC7E,6CAM0B;AAE1B;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,OAAgB;IAClD,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,wBAAwB,CAAC;IAClC,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,OAAO;aACtB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;aACxE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE5B,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC;YACzB,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;YACrB,CAAC,CAAC,wCAAwC,CAAC;IAC/C,CAAC;IAED,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,GAAG,OAAO,EAAE,CAAC;AACtB,CAAC;AA+ED,MAAM,kBAAkB,GAAG,IAAA,qBAAa,EAA0B;IAChE,OAAO,EAAE,EAAE;IACX,WAAW,EAAE,IAAI;IACjB,kBAAkB,EAAE,IAAI;CACzB,CAAC,CAAC;AAEH,kDAAkD;AAClD,MAAM,8BAA8B,GAAG,+BAA+B,CAAC;AAEvE;;;;;;;;;;GAUG;AACH,SAAS,UAAU,CAAC,KAAa;IAC/B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,MAAiB;IAC1C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK;QAAE,OAAO;IAEnC,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC1C,wDAAwD;QACxD,IAAI,WAAW,IAAI,OAAO,WAAW,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YAC3D,KAAK,WAAW,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,eAAe,CAAC;gBAC1C,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC;YAC/D,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,eAAe,CAAC;QAC1C,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAC7B,UAA2B,EAC3B,0BAA0E,EAC1E,uBAAoE;IAEpE,MAAM,iBAAiB,GAAyB,EAAE,CAAC;IAEnD,IAAI,UAAU,CAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;QACrC,iBAAiB,CAAC,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC;IAClE,CAAC;SAAM,IAAI,0BAA0B,EAAE,CAAC;QACtC,iBAAiB,CAAC,WAAW,GAAG,KAAK,EACnC,OAA6C,EAC7C,KAA2C,EAC3C,EAAE,CAAC,MAAM,0BAA0B,CAAC,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC;QAClC,iBAAiB,CAAC,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAC5D,CAAC;SAAM,IAAI,uBAAuB,EAAE,CAAC;QACnC,iBAAiB,CAAC,QAAQ,GAAG,KAAK,EAChC,OAA0C,EAC1C,KAAwC,EACxC,EAAE,CAAC,MAAM,uBAAuB,CAAC,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CACvB,UAAqC,EACrC,cAAyC,EACzC,YAAuC;IAEvC,OAAO,IAAA,eAAO,EAAC,GAAG,EAAE;QAClB,MAAM,SAAS,GAAG,IAAI,GAAG,EAA2B,CAAC;QAErD,+CAA+C;QAC/C,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAC5B,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,EAAE,mBAAU,CAAC,YAAY,CAAC,CAAC;YACxE,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,0EAA0E;QAC1E,IAAI,cAAc,IAAI,YAAY,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;YACnC,IAAI,CAAC,QAAQ,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC;YAC3D,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,MAAM,SAAS,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;YAC7C,MAAM,cAAc,GAA4B;gBAC9C,IAAI,EAAE,8BAA8B;gBACpC,GAAG,EAAE,WAAW;gBAChB,SAAS,EAAE,qBAAY,CAAC,IAAI;gBAC5B,SAAS,EAAE,SAAS,SAAS,EAAE;gBAC/B,aAAa,EAAE;oBACb,aAAa,EAAE,UAAU,cAAc,EAAE;iBAC1C;aACF,CAAC;YACF,MAAM,UAAU,GAAG,mBAAmB,CACpC,cAAc,EACd,mBAAU,CAAC,cAAc,CAC1B,CAAC;YACF,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC;AACjD,CAAC;AAOD;;GAEG;AACH,KAAK,UAAU,mBAAmB,CAChC,MAAiB,EACjB,UAA2B,EAC3B,GAAW,EACX,YAAqB,EACrB,SAAiC,EACjC,aAAgC,EAChC,YAAiE;IAEjE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;IAEtD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;QAEvC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACrB,MAAM,QAAQ,GAAG,YAAY;gBAC3B,CAAC,CAAC,GAAG,UAAU,CAAC,SAAS,KAAK,IAAI,CAAC,IAAI,EAAE;gBACzC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAEd,gDAAgD;YAChD,MAAM,YAAY,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxD,IAAI,YAAY,IAAI,YAAY,KAAK,GAAG,EAAE,CAAC;gBACzC,OAAO;YACT,CAAC;YAED,mBAAmB;YACnB,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBACxC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBACpC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;gBAC5C,CAAC;gBACD,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAChD,CAAC;YAED,YAAY,CAAC;gBACX,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;gBACnC,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,KAAK,EAAE,OAAgC,EAAE,EAAE,EAAE;oBACjD,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBAClC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;wBACpB,MAAM,IAAI,KAAK,CACb,uBAAuB,IAAI,CAAC,IAAI,mBAAmB,CACpD,CAAC;oBACJ,CAAC;oBACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBAC7D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;wBACnB,MAAM,YAAY,GAAG,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;wBACzD,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;oBAChC,CAAC;oBACD,OAAO,MAAM,CAAC,OAAO,CAAC;gBACxB,CAAC;gBACD,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;gBACnC,YAAY,EAAE,EAAE;gBAChB,kBAAkB,EAAE,CAAC,OAAgB,EAAE,EAAE;oBACvC,IAAI,IAAA,kCAAkB,EAAC,OAAO,CAAC,EAAE,CAAC;wBAChC,OAAO,OAAO,CAAC;oBACjB,CAAC;oBACD,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAA,sBAAM,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACnD,CAAC;gBACD,GAAG,CAAC,UAAU,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;oBACnD,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;oBAC7B,CAAC,CAAC,EAAE,CAAC;aACR,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,4CAA4C,UAAU,CAAC,GAAG,GAAG,EAC7D,KAAK,CACN,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAC3B,GAAW,EACX,aAAgC;IAEhC,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;IACtD,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,KAAK,EAAE,CAAC;QACV,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QACD,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACI,MAAM,gBAAgB,GAIxB,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC1C,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,0CAAgB,GAAE,CAAC;IAC5C,MAAM,EAAE,cAAc,EAAE,YAAY,EAAE,GAAG,IAAA,2CAAgB,EAAC,UAAU,CAAC,CAAC;IACtE,MAAM,UAAU,GAAG,IAAA,gDAAsB,GAAE,CAAC;IAC5C,MAAM,uBAAuB,GAAG,QAAQ,EAAE,QAAQ,CAAC;IAEnD,wCAAwC;IACxC,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,GAClE,IAAA,4BAAc,GAAE,CAAC;IAEnB,+CAA+C;IAC/C,MAAM,0BAA0B,GAC9B,QAAQ,EAAE,WAAW,IAAI,yBAAyB,CAAC;IAErD,yDAAyD;IACzD,MAAM,YAAY,GAAG,IAAA,cAAM,EAAyB,IAAI,GAAG,EAAE,CAAC,CAAC;IAC/D,yEAAyE;IACzE,MAAM,YAAY,GAAG,IAAA,cAAM,EAAsB,IAAI,GAAG,EAAE,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,IAAA,cAAM,EAA2B,IAAI,GAAG,EAAE,CAAC,CAAC;IAClE,MAAM,aAAa,GAAsB,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;IAEzE,oDAAoD;IACpD,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,IAAA,gBAAQ,EAC5D,EAAE,CACH,CAAC;IAEF,kEAAkE;IAClE,MAAM,iBAAiB,GAAG,gBAAgB,CACxC,UAAU,EACV,cAAc,EACd,YAAY,CACb,CAAC;IAEF,uDAAuD;IACvD,kBAAkB,CAChB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,0BAA0B,EAC1B,uBAAuB,EACvB,YAAY,EACZ,sBAAsB,CACvB,CAAC;IAEF,gEAAgE;IAChE,iBAAiB,CACf,iBAAiB,EACjB,YAAY,EACZ,0BAA0B,EAC1B,uBAAuB,CACxB,CAAC;IAEF,wCAAwC;IACxC,mBAAmB,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IAEjD,MAAM,YAAY,GAAG,IAAA,eAAO,EAC1B,GAAG,EAAE,CAAC,CAAC;QACL,OAAO,EAAE,mBAAmB;QAC5B,WAAW;QACX,kBAAkB;KACnB,CAAC,EACF,CAAC,mBAAmB,EAAE,WAAW,EAAE,kBAAkB,CAAC,CACvD,CAAC;IAEF,OAAO,CACL,8BAAC,kBAAkB,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY,IAC7C,QAAQ,CACmB,CAC/B,CAAC;AACJ,CAAC,CAAC;AAzEW,QAAA,gBAAgB,oBAyE3B;AAEF;;;GAGG;AACH,SAAS,kBAAkB,CACzB,iBAA+C,EAC/C,YAA4D,EAC5D,aAAgC,EAChC,0BAA0E,EAC1E,uBAAoE,EACpE,YAAiE,EACjE,sBAAyE;IAEzE,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;QACvC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC;QACtD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QAE/C,kEAAkE;QAClE,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAClD,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAC/B,CAAC;QACF,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YAC3B,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,MAAM,EAAE,CAAC;gBACX,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;YACD,oBAAoB,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;YACzC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,sDAAsD;QACtD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAC9C,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAChC,CAAC;QAEF,KAAK,UAAU,UAAU,CAAC,IAAc;YACtC,MAAM,OAAO,CAAC,UAAU,CACtB,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBACrB,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;gBAE/C,IAAI,CAAC;oBACH,MAAM,iBAAiB,GAAG,sBAAsB,CAC9C,UAAU,EACV,0BAA0B,EAC1B,uBAAuB,CACxB,CAAC;oBAEF,MAAM,MAAM,GAAG,MAAM,kBAAS,CAAC,MAAM,CACnC,UAAU,CAAC,GAAG,EACd,UAAU,CAAC,SAAS,EACpB,UAAU,CAAC,aAAa,EACxB,SAAS,EACT,SAAS,EACT,iBAAiB,CAClB,CAAC;oBAEF,MAAM,eAAe,GAAuB;wBAC1C,GAAG,UAAU;wBACb,MAAM;qBACP,CAAC;oBAEF,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;oBACpC,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;oBAEvD,kCAAkC;oBAClC,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,GAAG,CAAC,CAAC;oBAChD,MAAM,mBAAmB,CACvB,MAAM,EACN,UAAU,EACV,GAAG,EACH,YAAY,EACZ,SAAS,EACT,aAAa,EACb,YAAY,CACb,CAAC;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,YAAY,GAAoB;wBACpC,GAAG,UAAU;wBACb,eAAe,EAAE,KAAc;qBAChC,CAAC;oBACF,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;oBACjC,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;oBACvD,OAAO,CAAC,KAAK,CACX,mCAAmC,UAAU,CAAC,GAAG,GAAG,EACpD,KAAK,CACN,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC,CACH,CAAC;QACJ,CAAC;QAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,UAAU,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBAClC,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;YACxD,CAAC,CAAC,CAAC;QACL,CAAC;QAED,8BAA8B;QAC9B,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,gFAAgF;QAChF,qEAAqE;QACrE,uDAAuD;IACzD,CAAC,EAAE;QACD,iBAAiB;QACjB,0BAA0B;QAC1B,uBAAuB;QACvB,YAAY;KACb,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CACxB,iBAA+C,EAC/C,YAA4D,EAC5D,0BAA0E,EAC1E,uBAAoE;IAEpE,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;QAEvC,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;YAChC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACnB,OAAO,CAAC,sBAAsB;YAChC,CAAC;YAED,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC9C,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,CAAC,kDAAkD;YAC5D,CAAC;YAED,iDAAiD;YACjD,MAAM,2BAA2B,GAC/B,UAAU,CAAC,QAAQ,EAAE,WAAW;gBAChC,CAAC,0BAA0B;oBACzB,CAAC,CAAC,KAAK,EACH,OAA6C,EAC7C,KAA2C,EAC3C,EAAE,CAAC,MAAM,0BAA0B,CAAC,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC;oBACnE,CAAC,CAAC,SAAS,CAAC,CAAC;YAEjB,MAAM,wBAAwB,GAC5B,UAAU,CAAC,QAAQ,EAAE,QAAQ;gBAC7B,CAAC,uBAAuB;oBACtB,CAAC,CAAC,KAAK,EACH,OAA0C,EAC1C,KAAwC,EACxC,EAAE,CAAC,MAAM,uBAAuB,CAAC,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC;oBAChE,CAAC,CAAC,SAAS,CAAC,CAAC;YAEjB,MAAM,CAAC,MAAM,CAAC,wBAAwB,EAAE,CAAC,2BAA2B,CAAC,CAAC;YACtE,MAAM,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC,wBAAwB,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,8EAA8E;QAC9E,uDAAuD;IACzD,CAAC,EAAE,CAAC,iBAAiB,EAAE,0BAA0B,EAAE,uBAAuB,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAC1B,YAA4D,EAC5D,aAAgC;IAEhC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;QACvC,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;QACtD,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC3B,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC,CAAC,CAAC;YACH,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC7B,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAChC,CAAC,CAAC;QACF,8BAA8B;QAC9B,uDAAuD;IACzD,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACI,MAAM,kBAAkB,GAAG,GAAG,EAAE;IACrC,OAAO,IAAA,kBAAU,EAAC,kBAAkB,CAAC,CAAC,OAAO,CAAC;AAChD,CAAC,CAAC;AAFW,QAAA,kBAAkB,sBAE7B;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACI,MAAM,sBAAsB,GAAG,GAA4B,EAAE;IAClE,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,kBAAkB,CAAC,CAAC;IAC/C,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;KAC/C,CAAC;AACJ,CAAC,CAAC;AANW,QAAA,sBAAsB,0BAMjC;AAEF;;;GAGG;AACU,QAAA,0BAA0B,GAAG,8BAAsB,CAAC;AAEjE;;;;;;;;;GASG;AACH,SAAS,mBAAmB,CAC1B,MAA+B,EAC/B,UAAsB;IAEtB,qEAAqE;IACrE,8EAA8E;IAC9E,wEAAwE;IACxE,0EAA0E;IAC1E,MAAM,GAAG,GAAG,IAAA,8BAAqB,EAAC,MAAM,CAAC,CAAC;IAC1C,OAAO;QACL,GAAG,MAAM;QACT,GAAG;QACH,UAAU;KACX,CAAC;AACJ,CAAC","sourcesContent":["import React, {\n createContext,\n FC,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n ServerType,\n getMcpServerUniqueKey,\n type NormalizedMcpServerInfo,\n} from \"@tambo-ai/client\";\nimport { useTamboMcpToken } from \"../providers/tambo-mcp-token-provider\";\nimport {\n useTamboMcpServerInfos,\n useTamboRegistry,\n} from \"../providers/tambo-registry-provider\";\nimport { isContentPartArray, toText } from \"../util/content-parts\";\nimport { type ElicitationContextState, useElicitation } from \"./elicitation\";\nimport {\n MCPClient,\n MCPElicitationHandler,\n MCPHandlers,\n MCPSamplingHandler,\n MCPTransport,\n} from \"@tambo-ai/client\";\n\n/**\n * Extracts error message from MCP tool result content.\n * Handles both array and string content formats.\n * Always returns a string, even for invalid/null inputs.\n * @returns The extracted error message as a string\n */\nexport function extractErrorMessage(content: unknown): string {\n if (content === undefined || content === null) {\n return \"Unknown error occurred\";\n }\n\n if (Array.isArray(content)) {\n const textItems = content\n .filter((item) => item?.type === \"text\" && typeof item.text === \"string\")\n .map((item) => item.text);\n\n return textItems.length > 0\n ? textItems.join(\" \")\n : \"Error occurred but no details provided\";\n }\n\n if (typeof content === \"object\") {\n return JSON.stringify(content);\n }\n\n return `${content}`;\n}\n\n/**\n * Normalized MCP server information as consumed by the provider.\n *\n * Extends `NormalizedMcpServerInfo` from the core model by:\n * - adding a stable `key` derived from URL/transport/headers\n * - adding `serverType` to distinguish internal vs browser-side servers\n *\n * The `handlers` field is inherited from `McpServerInfo` (via\n * `NormalizedMcpServerInfo`) as `Partial<MCPHandlers>` — no redeclaration\n * needed here.\n *\n * The registry is responsible for producing `NormalizedMcpServerInfo`\n * instances; this type adds the MCP-specific wiring needed to connect and\n * track clients.\n */\ninterface McpServerConfig extends NormalizedMcpServerInfo {\n /**\n * Stable identity for this server derived from its URL/transport/headers.\n * Present for all server states (connected or failed).\n */\n key: string;\n /**\n * Type of server - determines how resources are resolved.\n * Internal servers are resolved server-side, browser-side servers are resolved client-side.\n */\n serverType: ServerType;\n}\n\n/**\n * Connected MCP server with an active client.\n */\nexport interface ConnectedMcpServer extends McpServerConfig {\n client: MCPClient;\n}\n\n/**\n * Failed MCP server with a connection error.\n */\nexport interface FailedMcpServer extends McpServerConfig {\n client?: never;\n connectionError: Error;\n}\n\n/**\n * An active or failed MCP server, with access to the MCP client.\n */\nexport type McpServer = ConnectedMcpServer | FailedMcpServer;\n\n/**\n * Provider-level MCP handlers that receive the McpServerInfo as context in addition to the request.\n * These handlers are applied to all MCP servers unless overridden by per-server handlers.\n *\n * Handlers receive three parameters:\n * 1. request - The MCP request\n * 2. extra - RequestHandlerExtra containing AbortSignal and other metadata\n * 3. serverInfo - Configuration of the MCP server that triggered this request\n */\nexport interface ProviderMCPHandlers {\n elicitation?: (\n request: Parameters<MCPElicitationHandler>[0],\n extra: Parameters<MCPElicitationHandler>[1],\n serverInfo: McpServerConfig,\n ) => ReturnType<MCPElicitationHandler>;\n sampling?: (\n request: Parameters<MCPSamplingHandler>[0],\n extra: Parameters<MCPSamplingHandler>[1],\n serverInfo: McpServerConfig,\n ) => ReturnType<MCPSamplingHandler>;\n}\n\n/**\n * Context value for MCP provider including server list and elicitation state\n */\ninterface McpProviderContextValue extends ElicitationContextState {\n servers: McpServer[];\n}\n\nconst McpProviderContext = createContext<McpProviderContextValue>({\n servers: [],\n elicitation: null,\n resolveElicitation: null,\n});\n\n// Constant for the internal Tambo MCP server name\nconst TAMBO_INTERNAL_MCP_SERVER_NAME = \"__tambo_internal_mcp_server__\";\n\n/**\n * Creates a stable hash of a string for use as a cache key.\n * Uses Java-style string hashing (DJB2-like) for deterministic results.\n *\n * Note: We use a synchronous hash instead of crypto.subtle.digest because:\n * - crypto.subtle.digest is async, which adds complexity in React hooks (useMemo, useEffect)\n * - This is not for security, just for creating a stable identifier to detect token changes\n * - Synchronous hashing avoids race conditions and simplifies component lifecycle\n * @param input - The string to hash\n * @returns A compact base36 hash string\n */\nfunction hashString(input: string): string {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n hash = (Math.imul(31, hash) + input.charCodeAt(i)) | 0;\n }\n return (hash >>> 0).toString(36);\n}\n\n/**\n * Safely closes an MCP client, handling both sync and async close methods.\n * Logs errors but doesn't throw.\n */\nfunction closeClientSafely(server: McpServer): void {\n if (!server?.client?.close) return;\n\n try {\n const closeResult = server.client.close();\n // If it returns a promise, handle errors but don't wait\n if (closeResult && typeof closeResult.catch === \"function\") {\n void closeResult.catch((error) => {\n const url = server.url ?? \"(unknown url)\";\n console.error(`Error closing MCP client for ${url}:`, error);\n });\n }\n } catch (error) {\n const url = server.url ?? \"(unknown url)\";\n console.error(`Error closing MCP client for ${url}:`, error);\n }\n}\n\n/**\n * Builds effective handlers for a server, with per-server overrides taking\n * precedence over provider-level handlers.\n * @returns The effective handlers with per-server overrides applied\n */\nfunction buildEffectiveHandlers(\n serverInfo: McpServerConfig,\n providerElicitationHandler: ProviderMCPHandlers[\"elicitation\"] | undefined,\n providerSamplingHandler: ProviderMCPHandlers[\"sampling\"] | undefined,\n): Partial<MCPHandlers> {\n const effectiveHandlers: Partial<MCPHandlers> = {};\n\n if (serverInfo.handlers?.elicitation) {\n effectiveHandlers.elicitation = serverInfo.handlers.elicitation;\n } else if (providerElicitationHandler) {\n effectiveHandlers.elicitation = async (\n request: Parameters<MCPElicitationHandler>[0],\n extra: Parameters<MCPElicitationHandler>[1],\n ) => await providerElicitationHandler(request, extra, serverInfo);\n }\n\n if (serverInfo.handlers?.sampling) {\n effectiveHandlers.sampling = serverInfo.handlers.sampling;\n } else if (providerSamplingHandler) {\n effectiveHandlers.sampling = async (\n request: Parameters<MCPSamplingHandler>[0],\n extra: Parameters<MCPSamplingHandler>[1],\n ) => await providerSamplingHandler(request, extra, serverInfo);\n }\n\n return effectiveHandlers;\n}\n\n/**\n * Hook to compute the stable map of server configurations from registry servers\n * and the internal Tambo MCP server (when token is available).\n * @returns A map of server key to server configuration\n */\nfunction useServerConfigs(\n mcpServers: NormalizedMcpServerInfo[],\n mcpAccessToken: string | null | undefined,\n tamboBaseUrl: string | null | undefined,\n): Map<string, McpServerConfig> {\n return useMemo(() => {\n const serverMap = new Map<string, McpServerConfig>();\n\n // Add user-provided MCP servers (browser-side)\n mcpServers.forEach((server) => {\n const serverInfo = normalizeServerInfo(server, ServerType.BROWSER_SIDE);\n serverMap.set(serverInfo.key, serverInfo);\n });\n\n // Add internal Tambo MCP server if we have an access token and a base URL\n if (mcpAccessToken && tamboBaseUrl) {\n const base = new URL(tamboBaseUrl);\n base.pathname = `${base.pathname.replace(/\\/+$/, \"\")}/mcp`;\n const tamboMcpUrl = base.toString();\n const tokenHash = hashString(mcpAccessToken);\n const internalServer: NormalizedMcpServerInfo = {\n name: TAMBO_INTERNAL_MCP_SERVER_NAME,\n url: tamboMcpUrl,\n transport: MCPTransport.HTTP,\n serverKey: `tambo-${tokenHash}`,\n customHeaders: {\n Authorization: `Bearer ${mcpAccessToken}`,\n },\n };\n const serverInfo = normalizeServerInfo(\n internalServer,\n ServerType.TAMBO_INTERNAL,\n );\n serverMap.set(serverInfo.key, serverInfo);\n }\n\n return serverMap;\n }, [mcpServers, mcpAccessToken, tamboBaseUrl]);\n}\n\ninterface ToolOwnershipRefs {\n toolOwnerRef: React.MutableRefObject<Map<string, string>>;\n keyToToolsRef: React.MutableRefObject<Map<string, Set<string>>>;\n}\n\n/**\n * Registers tools from a connected MCP server with deduplication.\n */\nasync function registerServerTools(\n client: MCPClient,\n serverInfo: McpServerConfig,\n key: string,\n shouldPrefix: boolean,\n clientMap: Map<string, McpServer>,\n ownershipRefs: ToolOwnershipRefs,\n registerTool: ReturnType<typeof useTamboRegistry>[\"registerTool\"],\n): Promise<void> {\n const { toolOwnerRef, keyToToolsRef } = ownershipRefs;\n\n try {\n const tools = await client.listTools();\n\n tools.forEach((tool) => {\n const toolName = shouldPrefix\n ? `${serverInfo.serverKey}__${tool.name}`\n : tool.name;\n\n // Skip if another server already owns this tool\n const currentOwner = toolOwnerRef.current.get(toolName);\n if (currentOwner && currentOwner !== key) {\n return;\n }\n\n // Record ownership\n if (!currentOwner) {\n toolOwnerRef.current.set(toolName, key);\n if (!keyToToolsRef.current.has(key)) {\n keyToToolsRef.current.set(key, new Set());\n }\n keyToToolsRef.current.get(key)!.add(toolName);\n }\n\n registerTool({\n description: tool.description ?? \"\",\n name: toolName,\n tool: async (args: Record<string, unknown> = {}) => {\n const server = clientMap.get(key);\n if (!server?.client) {\n throw new Error(\n `MCP server for tool ${tool.name} is not connected`,\n );\n }\n const result = await server.client.callTool(tool.name, args);\n if (result.isError) {\n const errorMessage = extractErrorMessage(result.content);\n throw new Error(errorMessage);\n }\n return result.content;\n },\n inputSchema: tool.inputSchema ?? {},\n outputSchema: {},\n transformToContent: (content: unknown) => {\n if (isContentPartArray(content)) {\n return content;\n }\n return [{ type: \"text\", text: toText(content) }];\n },\n ...(\"maxCalls\" in tool && tool.maxCalls !== undefined\n ? { maxCalls: tool.maxCalls }\n : {}),\n });\n });\n } catch (error) {\n console.error(\n `Failed to register tools from MCP server ${serverInfo.url}:`,\n error,\n );\n }\n}\n\n/**\n * Releases tool ownership for a server being removed.\n */\nfunction releaseToolOwnership(\n key: string,\n ownershipRefs: ToolOwnershipRefs,\n): void {\n const { toolOwnerRef, keyToToolsRef } = ownershipRefs;\n const owned = keyToToolsRef.current.get(key);\n if (owned) {\n for (const name of owned) {\n toolOwnerRef.current.delete(name);\n }\n keyToToolsRef.current.delete(key);\n }\n}\n\n/**\n * This provider is used to register tools from MCP servers.\n * It automatically includes an internal Tambo MCP server when an MCP access token is available.\n *\n * **BREAKING CHANGE**: This provider no longer accepts `mcpServers` as a prop.\n * Instead, pass `mcpServers` to `TamboProvider` or `TamboRegistryProvider`.\n * This provider must be wrapped inside `TamboProvider` to access the MCP server registry.\n * @param props - The provider props\n * @param props.handlers - Optional handlers applied to all MCP servers unless overridden per-server\n * @param props.contextKey - Optional context key for fetching threadless MCP tokens when not in a thread\n * @param props.children - The children to wrap\n * @returns The TamboMcpProvider component\n */\nexport const TamboMcpProvider: FC<{\n handlers?: ProviderMCPHandlers;\n contextKey?: string;\n children: React.ReactNode;\n}> = ({ handlers, contextKey, children }) => {\n const { registerTool } = useTamboRegistry();\n const { mcpAccessToken, tamboBaseUrl } = useTamboMcpToken(contextKey);\n const mcpServers = useTamboMcpServerInfos();\n const providerSamplingHandler = handlers?.sampling;\n\n // Elicitation state and default handler\n const { elicitation, resolveElicitation, defaultElicitationHandler } =\n useElicitation();\n\n // Use provided handler or fall back to default\n const providerElicitationHandler =\n handlers?.elicitation ?? defaultElicitationHandler;\n\n // Stable reference to track active clients by server key\n const clientMapRef = useRef<Map<string, McpServer>>(new Map());\n // Track tool ownership to prevent duplicate registrations across servers\n const toolOwnerRef = useRef<Map<string, string>>(new Map());\n const keyToToolsRef = useRef<Map<string, Set<string>>>(new Map());\n const ownershipRefs: ToolOwnershipRefs = { toolOwnerRef, keyToToolsRef };\n\n // State for exposing connected servers to consumers\n const [connectedMcpServers, setConnectedMcpServers] = useState<McpServer[]>(\n [],\n );\n\n // Compute server configurations from registry and internal server\n const currentServersMap = useServerConfigs(\n mcpServers,\n mcpAccessToken,\n tamboBaseUrl,\n );\n\n // Main effect: manage client lifecycle (create/remove)\n useClientLifecycle(\n currentServersMap,\n clientMapRef,\n ownershipRefs,\n providerElicitationHandler,\n providerSamplingHandler,\n registerTool,\n setConnectedMcpServers,\n );\n\n // Update handlers when they change (without recreating clients)\n useHandlerUpdates(\n currentServersMap,\n clientMapRef,\n providerElicitationHandler,\n providerSamplingHandler,\n );\n\n // Cleanup on unmount: close all clients\n useCleanupOnUnmount(clientMapRef, ownershipRefs);\n\n const contextValue = useMemo(\n () => ({\n servers: connectedMcpServers,\n elicitation,\n resolveElicitation,\n }),\n [connectedMcpServers, elicitation, resolveElicitation],\n );\n\n return (\n <McpProviderContext.Provider value={contextValue}>\n {children}\n </McpProviderContext.Provider>\n );\n};\n\n/**\n * Hook to manage client lifecycle: creating clients for new servers,\n * removing clients for servers that are no longer in the list.\n */\nfunction useClientLifecycle(\n currentServersMap: Map<string, McpServerConfig>,\n clientMapRef: React.MutableRefObject<Map<string, McpServer>>,\n ownershipRefs: ToolOwnershipRefs,\n providerElicitationHandler: ProviderMCPHandlers[\"elicitation\"] | undefined,\n providerSamplingHandler: ProviderMCPHandlers[\"sampling\"] | undefined,\n registerTool: ReturnType<typeof useTamboRegistry>[\"registerTool\"],\n setConnectedMcpServers: React.Dispatch<React.SetStateAction<McpServer[]>>,\n): void {\n useEffect(() => {\n const clientMap = clientMapRef.current;\n const currentKeys = new Set(currentServersMap.keys());\n const existingKeys = new Set(clientMap.keys());\n\n // 1. Remove clients that are no longer in the current server list\n const keysToRemove = Array.from(existingKeys).filter(\n (key) => !currentKeys.has(key),\n );\n keysToRemove.forEach((key) => {\n const server = clientMap.get(key);\n if (server) {\n closeClientSafely(server);\n }\n releaseToolOwnership(key, ownershipRefs);\n clientMap.delete(key);\n });\n\n // 2. Add new clients for servers that don't exist yet\n const keysToAdd = Array.from(currentKeys).filter(\n (key) => !existingKeys.has(key),\n );\n\n async function addClients(keys: string[]) {\n await Promise.allSettled(\n keys.map(async (key) => {\n const serverInfo = currentServersMap.get(key)!;\n\n try {\n const effectiveHandlers = buildEffectiveHandlers(\n serverInfo,\n providerElicitationHandler,\n providerSamplingHandler,\n );\n\n const client = await MCPClient.create(\n serverInfo.url,\n serverInfo.transport,\n serverInfo.customHeaders,\n undefined,\n undefined,\n effectiveHandlers,\n );\n\n const connectedServer: ConnectedMcpServer = {\n ...serverInfo,\n client,\n };\n\n clientMap.set(key, connectedServer);\n setConnectedMcpServers(Array.from(clientMap.values()));\n\n // Register tools from this server\n const shouldPrefix = currentServersMap.size > 1;\n await registerServerTools(\n client,\n serverInfo,\n key,\n shouldPrefix,\n clientMap,\n ownershipRefs,\n registerTool,\n );\n } catch (error) {\n const failedServer: FailedMcpServer = {\n ...serverInfo,\n connectionError: error as Error,\n };\n clientMap.set(key, failedServer);\n setConnectedMcpServers(Array.from(clientMap.values()));\n console.error(\n `Failed to connect to MCP server ${serverInfo.url}:`,\n error,\n );\n }\n }),\n );\n }\n\n if (keysToAdd.length > 0) {\n addClients(keysToAdd).catch((err) => {\n console.error(\"Unexpected error in addClients:\", err);\n });\n }\n\n // Update state after removals\n if (keysToRemove.length > 0) {\n setConnectedMcpServers(Array.from(clientMap.values()));\n }\n // Note: refs (clientMapRef, ownershipRefs) and setters (setConnectedMcpServers)\n // are intentionally excluded from deps as they are stable references\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n currentServersMap,\n providerElicitationHandler,\n providerSamplingHandler,\n registerTool,\n ]);\n}\n\n/**\n * Hook to update handlers on connected clients when provider handlers change.\n */\nfunction useHandlerUpdates(\n currentServersMap: Map<string, McpServerConfig>,\n clientMapRef: React.MutableRefObject<Map<string, McpServer>>,\n providerElicitationHandler: ProviderMCPHandlers[\"elicitation\"] | undefined,\n providerSamplingHandler: ProviderMCPHandlers[\"sampling\"] | undefined,\n): void {\n useEffect(() => {\n const clientMap = clientMapRef.current;\n\n clientMap.forEach((server, key) => {\n if (!server.client) {\n return; // Skip failed servers\n }\n\n const serverInfo = currentServersMap.get(key);\n if (!serverInfo) {\n return; // Server was removed, handled by lifecycle effect\n }\n\n // Build effective handlers and update the client\n const effectiveElicitationHandler =\n serverInfo.handlers?.elicitation ??\n (providerElicitationHandler\n ? async (\n request: Parameters<MCPElicitationHandler>[0],\n extra: Parameters<MCPElicitationHandler>[1],\n ) => await providerElicitationHandler(request, extra, serverInfo)\n : undefined);\n\n const effectiveSamplingHandler =\n serverInfo.handlers?.sampling ??\n (providerSamplingHandler\n ? async (\n request: Parameters<MCPSamplingHandler>[0],\n extra: Parameters<MCPSamplingHandler>[1],\n ) => await providerSamplingHandler(request, extra, serverInfo)\n : undefined);\n\n server.client.updateElicitationHandler?.(effectiveElicitationHandler);\n server.client.updateSamplingHandler?.(effectiveSamplingHandler);\n });\n // Note: clientMapRef is intentionally excluded from deps as it's a stable ref\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [currentServersMap, providerElicitationHandler, providerSamplingHandler]);\n}\n\n/**\n * Hook to cleanup all clients and tool ownership on component unmount.\n */\nfunction useCleanupOnUnmount(\n clientMapRef: React.MutableRefObject<Map<string, McpServer>>,\n ownershipRefs: ToolOwnershipRefs,\n): void {\n useEffect(() => {\n const clientMap = clientMapRef.current;\n const { toolOwnerRef, keyToToolsRef } = ownershipRefs;\n return () => {\n clientMap.forEach((server) => {\n closeClientSafely(server);\n });\n clientMap.clear();\n toolOwnerRef.current.clear();\n keyToToolsRef.current.clear();\n };\n // Only run cleanup on unmount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n}\n\n/**\n * Hook to access the actual MCP servers, as they are connected (or fail to\n * connect).\n *\n * You can call methods on the MCP client that is included in the MCP server\n * object.\n *\n * If the server fails to connect, the `client` property will be `undefined` and\n * the `connectionError` property will be set.\n *\n * For example, to forcibly disconnect and reconnect all MCP servers:\n *\n * ```tsx\n * const mcpServers = useTamboMcpServers();\n * mcpServers.forEach((mcpServer) => {\n * mcpServer.client?.reconnect();\n * });\n * ```\n *\n * Note that the MCP servers are not guaranteed to be in the same order as the\n * input array, because they are added as they are connected.\n * @returns The MCP servers\n */\nexport const useTamboMcpServers = () => {\n return useContext(McpProviderContext).servers;\n};\n\n/**\n * Hook to access MCP elicitation state from TamboMcpProvider.\n * This provides access to the current elicitation request and methods to respond to it.\n *\n * The elicitation state is automatically managed by TamboMcpProvider when MCP servers\n * request user input through the elicitation protocol.\n * @returns The elicitation state with current request and response handler\n * @example\n * ```tsx\n * function ElicitationUI() {\n * const { elicitation, resolveElicitation } = useTamboMcpElicitation();\n *\n * if (!elicitation) return null;\n *\n * return (\n * <div>\n * <p>{elicitation.message}</p>\n * <button onClick={() => resolveElicitation?.({ action: \"accept\", content: {} })}>\n * Accept\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport const useTamboMcpElicitation = (): ElicitationContextState => {\n const context = useContext(McpProviderContext);\n return {\n elicitation: context.elicitation,\n resolveElicitation: context.resolveElicitation,\n };\n};\n\n/**\n * @deprecated Use `useTamboMcpElicitation` instead.\n * This hook will be removed in a future version.\n */\nexport const useTamboElicitationContext = useTamboMcpElicitation;\n\n/**\n * Normalizes registry server metadata into a `McpServerConfig`.\n *\n * Accepts a `NormalizedMcpServerInfo`, which already guarantees a concrete\n * `transport`, a `serverKey` derived by the registry, and a typed\n * `handlers` field (`Partial<MCPHandlers>`).\n * @param server - The normalized MCP server info from the registry\n * @param serverType - The type of server (internal vs browser-side)\n * @returns The server config with typed handlers, unique key, and server type\n */\nfunction normalizeServerInfo(\n server: NormalizedMcpServerInfo,\n serverType: ServerType,\n): McpServerConfig {\n // Always use getMcpServerUniqueKey for connection identity to ensure\n // that changes to URL, transport, or customHeaders trigger client recreation.\n // The serverKey is kept for namespacing purposes (readable short name),\n // but the connection identity key must include all connection properties.\n const key = getMcpServerUniqueKey(server);\n return {\n ...server,\n key,\n serverType,\n };\n}\n"]}
|
|
@@ -38,7 +38,7 @@ const react_2 = __importStar(require("react"));
|
|
|
38
38
|
const tambo_client_provider_1 = require("../providers/tambo-client-provider");
|
|
39
39
|
const tambo_mcp_token_provider_1 = require("../providers/tambo-mcp-token-provider");
|
|
40
40
|
const tambo_registry_provider_1 = require("../providers/tambo-registry-provider");
|
|
41
|
-
const
|
|
41
|
+
const client_1 = require("@tambo-ai/client");
|
|
42
42
|
const tambo_mcp_provider_1 = require("./tambo-mcp-provider");
|
|
43
43
|
// Import the private function for testing by re-exporting it for tests only
|
|
44
44
|
// We'll need to export it temporarily or test it through public API
|
|
@@ -52,7 +52,8 @@ function createMockExtra() {
|
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
// Mock the MCP client to avoid ES module issues
|
|
55
|
-
jest.mock("
|
|
55
|
+
jest.mock("@tambo-ai/client", () => ({
|
|
56
|
+
...jest.requireActual("@tambo-ai/client"),
|
|
56
57
|
MCPClient: jest.fn(),
|
|
57
58
|
MCPTransport: {
|
|
58
59
|
SSE: "sse",
|
|
@@ -199,7 +200,7 @@ describe("TamboMcpProvider server list changes", () => {
|
|
|
199
200
|
baseURL: "https://api.tambo.co",
|
|
200
201
|
});
|
|
201
202
|
// Ensure MCPClient.create exists and returns a fake client with listTools and close
|
|
202
|
-
|
|
203
|
+
client_1.MCPClient.create = jest.fn().mockResolvedValue({
|
|
203
204
|
listTools: jest.fn().mockResolvedValue([]),
|
|
204
205
|
close: jest.fn(),
|
|
205
206
|
});
|
|
@@ -289,8 +290,8 @@ describe("TamboMcpProvider server list changes", () => {
|
|
|
289
290
|
it("does not duplicate when a new copy of the same list is passed", async () => {
|
|
290
291
|
let latest = [];
|
|
291
292
|
const initial = [
|
|
292
|
-
{ url: "https://a.example", transport:
|
|
293
|
-
{ url: "https://b.example", transport:
|
|
293
|
+
{ url: "https://a.example", transport: client_1.MCPTransport.SSE },
|
|
294
|
+
{ url: "https://b.example", transport: client_1.MCPTransport.SSE },
|
|
294
295
|
];
|
|
295
296
|
const { rerender } = (0, react_1.render)(react_2.default.createElement(TestWrapper, { mcpServers: initial },
|
|
296
297
|
react_2.default.createElement(Capture, { onUpdate: (s) => (latest = s) })));
|
|
@@ -299,8 +300,8 @@ describe("TamboMcpProvider server list changes", () => {
|
|
|
299
300
|
});
|
|
300
301
|
// Pass a new array instance with the same logical servers
|
|
301
302
|
const same = [
|
|
302
|
-
{ url: "https://a.example", transport:
|
|
303
|
-
{ url: "https://b.example", transport:
|
|
303
|
+
{ url: "https://a.example", transport: client_1.MCPTransport.SSE },
|
|
304
|
+
{ url: "https://b.example", transport: client_1.MCPTransport.SSE },
|
|
304
305
|
];
|
|
305
306
|
rerender(react_2.default.createElement(TestWrapper, { mcpServers: same },
|
|
306
307
|
react_2.default.createElement(Capture, { onUpdate: (s) => (latest = s) })));
|
|
@@ -321,7 +322,7 @@ describe("TamboMcpProvider server list changes", () => {
|
|
|
321
322
|
baseURL: "https://api.tambo.co",
|
|
322
323
|
});
|
|
323
324
|
// Prepare MCP client to return a tool with maxCalls in its metadata
|
|
324
|
-
|
|
325
|
+
client_1.MCPClient.create = jest.fn().mockResolvedValue({
|
|
325
326
|
listTools: jest.fn().mockResolvedValue([
|
|
326
327
|
{
|
|
327
328
|
name: "mcp-tool",
|
|
@@ -352,9 +353,9 @@ describe("TamboMcpProvider server list changes", () => {
|
|
|
352
353
|
listTools: jest.fn().mockResolvedValue([]),
|
|
353
354
|
close: jest.fn(),
|
|
354
355
|
});
|
|
355
|
-
|
|
356
|
+
client_1.MCPClient.create = createSpy;
|
|
356
357
|
let latest = [];
|
|
357
|
-
const initial = [{ url: "https://a.example", transport:
|
|
358
|
+
const initial = [{ url: "https://a.example", transport: client_1.MCPTransport.SSE }];
|
|
358
359
|
const { rerender } = (0, react_1.render)(react_2.default.createElement(TestWrapper, { mcpServers: initial },
|
|
359
360
|
react_2.default.createElement(Capture, { onUpdate: (s) => (latest = s) })));
|
|
360
361
|
await (0, react_1.waitFor)(() => {
|
|
@@ -364,7 +365,7 @@ describe("TamboMcpProvider server list changes", () => {
|
|
|
364
365
|
expect(createSpy).toHaveBeenCalledTimes(1);
|
|
365
366
|
const firstClient = latest[0].client;
|
|
366
367
|
// Pass a new array with same server
|
|
367
|
-
const same = [{ url: "https://a.example", transport:
|
|
368
|
+
const same = [{ url: "https://a.example", transport: client_1.MCPTransport.SSE }];
|
|
368
369
|
rerender(react_2.default.createElement(TestWrapper, { mcpServers: same },
|
|
369
370
|
react_2.default.createElement(Capture, { onUpdate: (s) => (latest = s) })));
|
|
370
371
|
await (0, react_1.waitFor)(() => {
|
|
@@ -381,7 +382,7 @@ describe("TamboMcpProvider server list changes", () => {
|
|
|
381
382
|
listTools: jest.fn().mockResolvedValue([]),
|
|
382
383
|
close: closeSpy,
|
|
383
384
|
});
|
|
384
|
-
|
|
385
|
+
client_1.MCPClient.create = createSpy;
|
|
385
386
|
let latest = [];
|
|
386
387
|
const { rerender } = (0, react_1.render)(react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
387
388
|
client: (0, tambo_client_provider_1.useTamboClient)(),
|
|
@@ -424,7 +425,7 @@ describe("TamboMcpProvider server list changes", () => {
|
|
|
424
425
|
listTools: jest.fn().mockResolvedValue([]),
|
|
425
426
|
close: closeSpy,
|
|
426
427
|
});
|
|
427
|
-
|
|
428
|
+
client_1.MCPClient.create = createSpy;
|
|
428
429
|
let latest = [];
|
|
429
430
|
const { unmount } = (0, react_1.render)(react_2.default.createElement(tambo_client_provider_1.TamboClientContext.Provider, { value: {
|
|
430
431
|
client: (0, tambo_client_provider_1.useTamboClient)(),
|
|
@@ -458,12 +459,12 @@ describe("TamboMcpProvider server list changes", () => {
|
|
|
458
459
|
close: closeSpy,
|
|
459
460
|
};
|
|
460
461
|
});
|
|
461
|
-
|
|
462
|
+
client_1.MCPClient.create = createSpy;
|
|
462
463
|
let latest = [];
|
|
463
464
|
const { rerender } = (0, react_1.render)(react_2.default.createElement(TestWrapper, { mcpServers: [
|
|
464
465
|
{
|
|
465
466
|
url: "https://a.example",
|
|
466
|
-
transport:
|
|
467
|
+
transport: client_1.MCPTransport.SSE,
|
|
467
468
|
customHeaders: { Authorization: "Bearer token1" },
|
|
468
469
|
},
|
|
469
470
|
] },
|
|
@@ -478,7 +479,7 @@ describe("TamboMcpProvider server list changes", () => {
|
|
|
478
479
|
rerender(react_2.default.createElement(TestWrapper, { mcpServers: [
|
|
479
480
|
{
|
|
480
481
|
url: "https://a.example",
|
|
481
|
-
transport:
|
|
482
|
+
transport: client_1.MCPTransport.SSE,
|
|
482
483
|
customHeaders: { Authorization: "Bearer token2" },
|
|
483
484
|
},
|
|
484
485
|
] },
|
|
@@ -517,7 +518,7 @@ describe("TamboMcpProvider handler support", () => {
|
|
|
517
518
|
};
|
|
518
519
|
// Mock MCPClient.create to return our mock client
|
|
519
520
|
createSpy = jest.fn().mockResolvedValue(mockClient);
|
|
520
|
-
|
|
521
|
+
client_1.MCPClient.create = createSpy;
|
|
521
522
|
});
|
|
522
523
|
const Capture = ({ onUpdate, }) => {
|
|
523
524
|
const servers = (0, tambo_mcp_provider_1.useTamboMcpServers)();
|
|
@@ -540,7 +541,7 @@ describe("TamboMcpProvider handler support", () => {
|
|
|
540
541
|
expect(latest.length).toBe(1);
|
|
541
542
|
});
|
|
542
543
|
// Verify MCPClient.create was called with an HTTP transport and wrapped handler
|
|
543
|
-
expect(createSpy).toHaveBeenCalledWith("https://test.example",
|
|
544
|
+
expect(createSpy).toHaveBeenCalledWith("https://test.example", client_1.MCPTransport.HTTP, undefined, undefined, undefined, expect.objectContaining({
|
|
544
545
|
elicitation: expect.any(Function),
|
|
545
546
|
}));
|
|
546
547
|
// Get the actual handler that was passed
|
|
@@ -575,7 +576,7 @@ describe("TamboMcpProvider handler support", () => {
|
|
|
575
576
|
expect(latest.length).toBe(1);
|
|
576
577
|
});
|
|
577
578
|
// Verify MCPClient.create was called with HTTP transport and sampling handler
|
|
578
|
-
expect(createSpy).toHaveBeenCalledWith("https://test.example",
|
|
579
|
+
expect(createSpy).toHaveBeenCalledWith("https://test.example", client_1.MCPTransport.HTTP, undefined, undefined, undefined, expect.objectContaining({
|
|
579
580
|
sampling: expect.any(Function),
|
|
580
581
|
}));
|
|
581
582
|
// Get the actual handler and verify it receives serverInfo
|
|
@@ -704,7 +705,7 @@ describe("TamboMcpProvider serverKey derivation and tool prefixing", () => {
|
|
|
704
705
|
};
|
|
705
706
|
describe("serverKey derivation", () => {
|
|
706
707
|
it("should derive serverKey from URL when not provided", async () => {
|
|
707
|
-
|
|
708
|
+
client_1.MCPClient.create = jest.fn().mockResolvedValue({
|
|
708
709
|
listTools: jest.fn().mockResolvedValue([]),
|
|
709
710
|
close: jest.fn(),
|
|
710
711
|
});
|
|
@@ -717,7 +718,7 @@ describe("TamboMcpProvider serverKey derivation and tool prefixing", () => {
|
|
|
717
718
|
});
|
|
718
719
|
});
|
|
719
720
|
it("should use provided serverKey when specified", async () => {
|
|
720
|
-
|
|
721
|
+
client_1.MCPClient.create = jest.fn().mockResolvedValue({
|
|
721
722
|
listTools: jest.fn().mockResolvedValue([]),
|
|
722
723
|
close: jest.fn(),
|
|
723
724
|
});
|
|
@@ -735,7 +736,7 @@ describe("TamboMcpProvider serverKey derivation and tool prefixing", () => {
|
|
|
735
736
|
});
|
|
736
737
|
});
|
|
737
738
|
it("should derive serverKey correctly for various URL patterns", async () => {
|
|
738
|
-
|
|
739
|
+
client_1.MCPClient.create = jest.fn().mockResolvedValue({
|
|
739
740
|
listTools: jest.fn().mockResolvedValue([]),
|
|
740
741
|
close: jest.fn(),
|
|
741
742
|
});
|
|
@@ -760,7 +761,7 @@ describe("TamboMcpProvider serverKey derivation and tool prefixing", () => {
|
|
|
760
761
|
});
|
|
761
762
|
describe("tool name prefixing", () => {
|
|
762
763
|
it("should NOT prefix tool names when only one server is present", async () => {
|
|
763
|
-
|
|
764
|
+
client_1.MCPClient.create = jest.fn().mockResolvedValue({
|
|
764
765
|
listTools: jest
|
|
765
766
|
.fn()
|
|
766
767
|
.mockResolvedValue([
|
|
@@ -779,7 +780,7 @@ describe("TamboMcpProvider serverKey derivation and tool prefixing", () => {
|
|
|
779
780
|
});
|
|
780
781
|
});
|
|
781
782
|
it("should prefix tool names when multiple servers are present", async () => {
|
|
782
|
-
|
|
783
|
+
client_1.MCPClient.create = jest.fn().mockResolvedValue({
|
|
783
784
|
listTools: jest
|
|
784
785
|
.fn()
|
|
785
786
|
.mockResolvedValue([
|
|
@@ -804,7 +805,7 @@ describe("TamboMcpProvider serverKey derivation and tool prefixing", () => {
|
|
|
804
805
|
}, { timeout: 5000 });
|
|
805
806
|
});
|
|
806
807
|
it("should use custom serverKey in prefix when provided", async () => {
|
|
807
|
-
|
|
808
|
+
client_1.MCPClient.create = jest.fn().mockResolvedValue({
|
|
808
809
|
listTools: jest
|
|
809
810
|
.fn()
|
|
810
811
|
.mockResolvedValue([
|