@tambo-ai/react 0.67.1 → 0.69.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/README.md +3 -5
- package/dist/context-helpers/context-helpers.test.js +16 -4
- package/dist/context-helpers/context-helpers.test.js.map +1 -1
- package/dist/context-helpers/current-interactables-context-helper.d.ts +2 -2
- package/dist/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
- package/dist/context-helpers/current-interactables-context-helper.js +31 -12
- package/dist/context-helpers/current-interactables-context-helper.js.map +1 -1
- package/dist/context-helpers/registry.d.ts +2 -2
- package/dist/context-helpers/registry.d.ts.map +1 -1
- package/dist/context-helpers/registry.js.map +1 -1
- package/dist/context-helpers/types.d.ts +2 -2
- package/dist/context-helpers/types.d.ts.map +1 -1
- package/dist/context-helpers/types.js.map +1 -1
- package/dist/hoc/with-tambo-interactable.d.ts +50 -4
- package/dist/hoc/with-tambo-interactable.d.ts.map +1 -1
- package/dist/hoc/with-tambo-interactable.js +20 -5
- package/dist/hoc/with-tambo-interactable.js.map +1 -1
- package/dist/hooks/use-component-state.d.ts +3 -8
- package/dist/hooks/use-component-state.d.ts.map +1 -1
- package/dist/hooks/use-component-state.js +8 -0
- package/dist/hooks/use-component-state.js.map +1 -1
- package/dist/hooks/use-component-state.test.js +37 -0
- package/dist/hooks/use-component-state.test.js.map +1 -1
- package/dist/hooks/use-message-images.test.js +174 -37
- package/dist/hooks/use-message-images.test.js.map +1 -1
- package/dist/hooks/use-tambo-threads.js +1 -1
- package/dist/hooks/use-tambo-threads.js.map +1 -1
- package/dist/hooks/use-tambo-voice.d.ts +1 -1
- package/dist/hooks/use-tambo-voice.js +1 -1
- package/dist/hooks/use-tambo-voice.js.map +1 -1
- package/dist/hooks/use-tambo-voice.test.d.ts +2 -0
- package/dist/hooks/use-tambo-voice.test.d.ts.map +1 -0
- package/dist/hooks/use-tambo-voice.test.js +239 -0
- package/dist/hooks/use-tambo-voice.test.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/elicitation.d.ts.map +1 -1
- package/dist/mcp/elicitation.js +12 -0
- package/dist/mcp/elicitation.js.map +1 -1
- package/dist/mcp/elicitation.test.js +8 -1
- package/dist/mcp/elicitation.test.js.map +1 -1
- package/dist/mcp/mcp-client.d.ts +6 -10
- package/dist/mcp/mcp-client.d.ts.map +1 -1
- package/dist/mcp/mcp-client.js.map +1 -1
- package/dist/mcp/mcp-constants.d.ts +19 -0
- package/dist/mcp/mcp-constants.d.ts.map +1 -0
- package/dist/mcp/mcp-constants.js +21 -0
- package/dist/mcp/mcp-constants.js.map +1 -0
- package/dist/mcp/mcp-hooks.d.ts +21 -40
- package/dist/mcp/mcp-hooks.d.ts.map +1 -1
- package/dist/mcp/mcp-hooks.js +130 -39
- package/dist/mcp/mcp-hooks.js.map +1 -1
- package/dist/mcp/mcp-hooks.test.js +431 -5
- package/dist/mcp/mcp-hooks.test.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.d.ts +7 -0
- package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/dist/mcp/tambo-mcp-provider.js +205 -155
- package/dist/mcp/tambo-mcp-provider.js.map +1 -1
- package/dist/mcp/tambo-mcp-provider.test.js +37 -0
- package/dist/mcp/tambo-mcp-provider.test.js.map +1 -1
- package/dist/model/component-metadata.d.ts +54 -21
- package/dist/model/component-metadata.d.ts.map +1 -1
- package/dist/model/component-metadata.js.map +1 -1
- package/dist/model/tambo-interactable.d.ts +13 -5
- package/dist/model/tambo-interactable.d.ts.map +1 -1
- package/dist/model/tambo-interactable.js.map +1 -1
- package/dist/providers/__tests__/thread-input-resource-resolution.test.d.ts +2 -0
- package/dist/providers/__tests__/thread-input-resource-resolution.test.d.ts.map +1 -0
- package/dist/providers/__tests__/thread-input-resource-resolution.test.js +592 -0
- package/dist/providers/__tests__/thread-input-resource-resolution.test.js.map +1 -0
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/tambo-client-provider.d.ts +8 -0
- package/dist/providers/tambo-client-provider.d.ts.map +1 -1
- package/dist/providers/tambo-client-provider.js +10 -11
- package/dist/providers/tambo-client-provider.js.map +1 -1
- package/dist/providers/tambo-client-provider.test.d.ts +2 -0
- package/dist/providers/tambo-client-provider.test.d.ts.map +1 -0
- package/dist/providers/tambo-client-provider.test.js +208 -0
- package/dist/providers/tambo-client-provider.test.js.map +1 -0
- package/dist/providers/tambo-context-attachment-provider.d.ts +34 -92
- package/dist/providers/tambo-context-attachment-provider.d.ts.map +1 -1
- package/dist/providers/tambo-context-attachment-provider.js +62 -105
- package/dist/providers/tambo-context-attachment-provider.js.map +1 -1
- package/dist/providers/tambo-context-attachment-provider.test.js +229 -463
- package/dist/providers/tambo-context-attachment-provider.test.js.map +1 -1
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js +22 -21
- package/dist/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.d.ts +5 -2
- package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/dist/providers/tambo-interactable-provider.js +126 -17
- package/dist/providers/tambo-interactable-provider.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.test.js +242 -0
- package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
- package/dist/providers/tambo-interactables-additional-context.test.js +2 -5
- package/dist/providers/tambo-interactables-additional-context.test.js.map +1 -1
- package/dist/providers/tambo-provider.d.ts +2 -3
- package/dist/providers/tambo-provider.d.ts.map +1 -1
- package/dist/providers/tambo-provider.js +6 -5
- package/dist/providers/tambo-provider.js.map +1 -1
- package/dist/providers/tambo-registry-provider.test.js +16 -0
- package/dist/providers/tambo-registry-provider.test.js.map +1 -1
- package/dist/providers/tambo-registry-schema-compat.test.js +31 -0
- package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -1
- package/dist/providers/tambo-thread-input-provider.d.ts +1 -1
- package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-input-provider.js +26 -4
- package/dist/providers/tambo-thread-input-provider.js.map +1 -1
- package/dist/providers/tambo-thread-provider-initial-messages.test.js +84 -2
- package/dist/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
- package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
- package/dist/providers/tambo-thread-provider.js +53 -42
- package/dist/providers/tambo-thread-provider.js.map +1 -1
- package/dist/providers/tambo-thread-provider.test.js +368 -262
- package/dist/providers/tambo-thread-provider.test.js.map +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +2 -1
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/json-schema.d.ts +7 -0
- package/dist/schema/json-schema.d.ts.map +1 -1
- package/dist/schema/json-schema.js +40 -29
- package/dist/schema/json-schema.js.map +1 -1
- package/dist/schema/json-schema.test.d.ts +2 -0
- package/dist/schema/json-schema.test.d.ts.map +1 -0
- package/dist/schema/json-schema.test.js +204 -0
- package/dist/schema/json-schema.test.js.map +1 -0
- package/dist/schema/schema.test.js +237 -0
- package/dist/schema/schema.test.js.map +1 -1
- package/dist/schema/standard-schema.d.ts +1 -0
- package/dist/schema/standard-schema.d.ts.map +1 -1
- package/dist/schema/standard-schema.js +18 -13
- package/dist/schema/standard-schema.js.map +1 -1
- package/dist/schema/standard-schema.test.d.ts +2 -0
- package/dist/schema/standard-schema.test.d.ts.map +1 -0
- package/dist/schema/standard-schema.test.js +165 -0
- package/dist/schema/standard-schema.test.js.map +1 -0
- package/dist/schema/validate.test.js +149 -0
- package/dist/schema/validate.test.js.map +1 -1
- package/dist/schema/zod.d.ts +7 -4
- package/dist/schema/zod.d.ts.map +1 -1
- package/dist/schema/zod.js +65 -22
- package/dist/schema/zod.js.map +1 -1
- package/dist/schema/zod.test.js +112 -0
- package/dist/schema/zod.test.js.map +1 -1
- package/dist/setupTests.js +3 -0
- package/dist/setupTests.js.map +1 -1
- package/dist/testing/tools.d.ts +4 -1
- package/dist/testing/tools.d.ts.map +1 -1
- package/dist/testing/tools.js +6 -1
- package/dist/testing/tools.js.map +1 -1
- package/dist/util/generate-component.d.ts.map +1 -1
- package/dist/util/generate-component.js +18 -3
- package/dist/util/generate-component.js.map +1 -1
- package/dist/util/generate-component.test.d.ts +2 -0
- package/dist/util/generate-component.test.d.ts.map +1 -0
- package/dist/util/generate-component.test.js +340 -0
- package/dist/util/generate-component.test.js.map +1 -0
- package/dist/util/is-promise.d.ts +9 -0
- package/dist/util/is-promise.d.ts.map +1 -0
- package/dist/util/is-promise.js +20 -0
- package/dist/util/is-promise.js.map +1 -0
- package/dist/util/is-promise.test.d.ts +2 -0
- package/dist/util/is-promise.test.d.ts.map +1 -0
- package/dist/util/is-promise.test.js +48 -0
- package/dist/util/is-promise.test.js.map +1 -0
- package/dist/util/message-builder.d.ts +3 -1
- package/dist/util/message-builder.d.ts.map +1 -1
- package/dist/util/message-builder.js +20 -3
- package/dist/util/message-builder.js.map +1 -1
- package/dist/util/message-builder.test.js +269 -0
- package/dist/util/message-builder.test.js.map +1 -1
- package/dist/util/query-utils.test.d.ts +2 -0
- package/dist/util/query-utils.test.d.ts.map +1 -0
- package/dist/util/query-utils.test.js +382 -0
- package/dist/util/query-utils.test.js.map +1 -0
- package/dist/util/registry-validators.d.ts.map +1 -1
- package/dist/util/registry-validators.js +7 -0
- package/dist/util/registry-validators.js.map +1 -1
- package/dist/util/registry-validators.test.js +57 -0
- package/dist/util/registry-validators.test.js.map +1 -1
- package/dist/util/registry.d.ts.map +1 -1
- package/dist/util/registry.js +9 -0
- package/dist/util/registry.js.map +1 -1
- package/dist/util/registry.test.js +323 -1
- package/dist/util/registry.test.js.map +1 -1
- package/dist/util/resource-content-resolver.d.ts +20 -0
- package/dist/util/resource-content-resolver.d.ts.map +1 -0
- package/dist/util/resource-content-resolver.js +93 -0
- package/dist/util/resource-content-resolver.js.map +1 -0
- package/dist/util/resource-content-resolver.test.d.ts +2 -0
- package/dist/util/resource-content-resolver.test.d.ts.map +1 -0
- package/dist/util/resource-content-resolver.test.js +254 -0
- package/dist/util/resource-content-resolver.test.js.map +1 -0
- package/dist/util/resource-validators.test.d.ts +2 -0
- package/dist/util/resource-validators.test.d.ts.map +1 -0
- package/dist/util/resource-validators.test.js +90 -0
- package/dist/util/resource-validators.test.js.map +1 -0
- package/dist/util/tool-caller.d.ts +2 -2
- package/dist/util/tool-caller.d.ts.map +1 -1
- package/dist/util/tool-caller.js +8 -8
- package/dist/util/tool-caller.js.map +1 -1
- package/dist/util/validate-component-name.test.d.ts +2 -0
- package/dist/util/validate-component-name.test.d.ts.map +1 -0
- package/dist/util/validate-component-name.test.js +35 -0
- package/dist/util/validate-component-name.test.js.map +1 -0
- package/esm/context-helpers/context-helpers.test.js +16 -4
- package/esm/context-helpers/context-helpers.test.js.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.d.ts +2 -2
- package/esm/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
- package/esm/context-helpers/current-interactables-context-helper.js +31 -12
- package/esm/context-helpers/current-interactables-context-helper.js.map +1 -1
- package/esm/context-helpers/registry.d.ts +2 -2
- package/esm/context-helpers/registry.d.ts.map +1 -1
- package/esm/context-helpers/registry.js.map +1 -1
- package/esm/context-helpers/types.d.ts +2 -2
- package/esm/context-helpers/types.d.ts.map +1 -1
- package/esm/context-helpers/types.js.map +1 -1
- package/esm/hoc/with-tambo-interactable.d.ts +50 -4
- package/esm/hoc/with-tambo-interactable.d.ts.map +1 -1
- package/esm/hoc/with-tambo-interactable.js +20 -5
- package/esm/hoc/with-tambo-interactable.js.map +1 -1
- package/esm/hooks/use-component-state.d.ts +3 -8
- package/esm/hooks/use-component-state.d.ts.map +1 -1
- package/esm/hooks/use-component-state.js +8 -0
- package/esm/hooks/use-component-state.js.map +1 -1
- package/esm/hooks/use-component-state.test.js +37 -0
- package/esm/hooks/use-component-state.test.js.map +1 -1
- package/esm/hooks/use-message-images.test.js +174 -37
- package/esm/hooks/use-message-images.test.js.map +1 -1
- package/esm/hooks/use-tambo-threads.js +1 -1
- package/esm/hooks/use-tambo-threads.js.map +1 -1
- package/esm/hooks/use-tambo-voice.d.ts +1 -1
- package/esm/hooks/use-tambo-voice.js +1 -1
- package/esm/hooks/use-tambo-voice.js.map +1 -1
- package/esm/hooks/use-tambo-voice.test.d.ts +2 -0
- package/esm/hooks/use-tambo-voice.test.d.ts.map +1 -0
- package/esm/hooks/use-tambo-voice.test.js +234 -0
- package/esm/hooks/use-tambo-voice.test.js.map +1 -0
- package/esm/index.d.ts +2 -2
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js.map +1 -1
- package/esm/mcp/elicitation.d.ts.map +1 -1
- package/esm/mcp/elicitation.js +12 -0
- package/esm/mcp/elicitation.js.map +1 -1
- package/esm/mcp/elicitation.test.js +8 -1
- package/esm/mcp/elicitation.test.js.map +1 -1
- package/esm/mcp/mcp-client.d.ts +6 -10
- package/esm/mcp/mcp-client.d.ts.map +1 -1
- package/esm/mcp/mcp-client.js.map +1 -1
- package/esm/mcp/mcp-constants.d.ts +19 -0
- package/esm/mcp/mcp-constants.d.ts.map +1 -0
- package/esm/mcp/mcp-constants.js +18 -0
- package/esm/mcp/mcp-constants.js.map +1 -0
- package/esm/mcp/mcp-hooks.d.ts +21 -40
- package/esm/mcp/mcp-hooks.d.ts.map +1 -1
- package/esm/mcp/mcp-hooks.js +97 -40
- package/esm/mcp/mcp-hooks.js.map +1 -1
- package/esm/mcp/mcp-hooks.test.js +431 -5
- package/esm/mcp/mcp-hooks.test.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.d.ts +7 -0
- package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
- package/esm/mcp/tambo-mcp-provider.js +204 -154
- package/esm/mcp/tambo-mcp-provider.js.map +1 -1
- package/esm/mcp/tambo-mcp-provider.test.js +37 -0
- package/esm/mcp/tambo-mcp-provider.test.js.map +1 -1
- package/esm/model/component-metadata.d.ts +54 -21
- package/esm/model/component-metadata.d.ts.map +1 -1
- package/esm/model/component-metadata.js.map +1 -1
- package/esm/model/tambo-interactable.d.ts +13 -5
- package/esm/model/tambo-interactable.d.ts.map +1 -1
- package/esm/model/tambo-interactable.js.map +1 -1
- package/esm/providers/__tests__/thread-input-resource-resolution.test.d.ts +2 -0
- package/esm/providers/__tests__/thread-input-resource-resolution.test.d.ts.map +1 -0
- package/esm/providers/__tests__/thread-input-resource-resolution.test.js +587 -0
- package/esm/providers/__tests__/thread-input-resource-resolution.test.js.map +1 -0
- package/esm/providers/index.d.ts +1 -1
- package/esm/providers/index.d.ts.map +1 -1
- package/esm/providers/index.js.map +1 -1
- package/esm/providers/tambo-client-provider.d.ts +8 -0
- package/esm/providers/tambo-client-provider.d.ts.map +1 -1
- package/esm/providers/tambo-client-provider.js +11 -12
- package/esm/providers/tambo-client-provider.js.map +1 -1
- package/esm/providers/tambo-client-provider.test.d.ts +2 -0
- package/esm/providers/tambo-client-provider.test.d.ts.map +1 -0
- package/esm/providers/tambo-client-provider.test.js +203 -0
- package/esm/providers/tambo-client-provider.test.js.map +1 -0
- package/esm/providers/tambo-context-attachment-provider.d.ts +34 -92
- package/esm/providers/tambo-context-attachment-provider.d.ts.map +1 -1
- package/esm/providers/tambo-context-attachment-provider.js +63 -106
- package/esm/providers/tambo-context-attachment-provider.js.map +1 -1
- package/esm/providers/tambo-context-attachment-provider.test.js +230 -464
- package/esm/providers/tambo-context-attachment-provider.test.js.map +1 -1
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js +22 -21
- package/esm/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +5 -2
- package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
- package/esm/providers/tambo-interactable-provider.js +126 -17
- package/esm/providers/tambo-interactable-provider.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.test.js +242 -0
- package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
- package/esm/providers/tambo-interactables-additional-context.test.js +2 -5
- package/esm/providers/tambo-interactables-additional-context.test.js.map +1 -1
- package/esm/providers/tambo-provider.d.ts +2 -3
- package/esm/providers/tambo-provider.d.ts.map +1 -1
- package/esm/providers/tambo-provider.js +6 -5
- package/esm/providers/tambo-provider.js.map +1 -1
- package/esm/providers/tambo-registry-provider.test.js +16 -0
- package/esm/providers/tambo-registry-provider.test.js.map +1 -1
- package/esm/providers/tambo-registry-schema-compat.test.js +31 -0
- package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -1
- package/esm/providers/tambo-thread-input-provider.d.ts +1 -1
- package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-input-provider.js +26 -4
- package/esm/providers/tambo-thread-input-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider-initial-messages.test.js +84 -2
- package/esm/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
- package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
- package/esm/providers/tambo-thread-provider.js +53 -42
- package/esm/providers/tambo-thread-provider.js.map +1 -1
- package/esm/providers/tambo-thread-provider.test.js +368 -262
- package/esm/providers/tambo-thread-provider.test.js.map +1 -1
- package/esm/schema/index.d.ts +1 -1
- package/esm/schema/index.d.ts.map +1 -1
- package/esm/schema/index.js +1 -1
- package/esm/schema/index.js.map +1 -1
- package/esm/schema/json-schema.d.ts +7 -0
- package/esm/schema/json-schema.d.ts.map +1 -1
- package/esm/schema/json-schema.js +11 -1
- package/esm/schema/json-schema.js.map +1 -1
- package/esm/schema/json-schema.test.d.ts +2 -0
- package/esm/schema/json-schema.test.d.ts.map +1 -0
- package/esm/schema/json-schema.test.js +202 -0
- package/esm/schema/json-schema.test.js.map +1 -0
- package/esm/schema/schema.test.js +238 -1
- package/esm/schema/schema.test.js.map +1 -1
- package/esm/schema/standard-schema.d.ts +1 -0
- package/esm/schema/standard-schema.d.ts.map +1 -1
- package/esm/schema/standard-schema.js +18 -13
- package/esm/schema/standard-schema.js.map +1 -1
- package/esm/schema/standard-schema.test.d.ts +2 -0
- package/esm/schema/standard-schema.test.d.ts.map +1 -0
- package/esm/schema/standard-schema.test.js +130 -0
- package/esm/schema/standard-schema.test.js.map +1 -0
- package/esm/schema/validate.test.js +149 -0
- package/esm/schema/validate.test.js.map +1 -1
- package/esm/schema/zod.d.ts +7 -4
- package/esm/schema/zod.d.ts.map +1 -1
- package/esm/schema/zod.js +65 -22
- package/esm/schema/zod.js.map +1 -1
- package/esm/schema/zod.test.js +113 -1
- package/esm/schema/zod.test.js.map +1 -1
- package/esm/setupTests.js +3 -0
- package/esm/setupTests.js.map +1 -1
- package/esm/testing/tools.d.ts +4 -1
- package/esm/testing/tools.d.ts.map +1 -1
- package/esm/testing/tools.js +6 -1
- package/esm/testing/tools.js.map +1 -1
- package/esm/util/generate-component.d.ts.map +1 -1
- package/esm/util/generate-component.js +18 -3
- package/esm/util/generate-component.js.map +1 -1
- package/esm/util/generate-component.test.d.ts +2 -0
- package/esm/util/generate-component.test.d.ts.map +1 -0
- package/esm/util/generate-component.test.js +302 -0
- package/esm/util/generate-component.test.js.map +1 -0
- package/esm/util/is-promise.d.ts +9 -0
- package/esm/util/is-promise.d.ts.map +1 -0
- package/esm/util/is-promise.js +17 -0
- package/esm/util/is-promise.js.map +1 -0
- package/esm/util/is-promise.test.d.ts +2 -0
- package/esm/util/is-promise.test.d.ts.map +1 -0
- package/esm/util/is-promise.test.js +46 -0
- package/esm/util/is-promise.test.js.map +1 -0
- package/esm/util/message-builder.d.ts +3 -1
- package/esm/util/message-builder.d.ts.map +1 -1
- package/esm/util/message-builder.js +20 -3
- package/esm/util/message-builder.js.map +1 -1
- package/esm/util/message-builder.test.js +269 -0
- package/esm/util/message-builder.test.js.map +1 -1
- package/esm/util/query-utils.test.d.ts +2 -0
- package/esm/util/query-utils.test.d.ts.map +1 -0
- package/esm/util/query-utils.test.js +380 -0
- package/esm/util/query-utils.test.js.map +1 -0
- package/esm/util/registry-validators.d.ts.map +1 -1
- package/esm/util/registry-validators.js +7 -0
- package/esm/util/registry-validators.js.map +1 -1
- package/esm/util/registry-validators.test.js +57 -0
- package/esm/util/registry-validators.test.js.map +1 -1
- package/esm/util/registry.d.ts.map +1 -1
- package/esm/util/registry.js +9 -0
- package/esm/util/registry.js.map +1 -1
- package/esm/util/registry.test.js +324 -2
- package/esm/util/registry.test.js.map +1 -1
- package/esm/util/resource-content-resolver.d.ts +20 -0
- package/esm/util/resource-content-resolver.d.ts.map +1 -0
- package/esm/util/resource-content-resolver.js +89 -0
- package/esm/util/resource-content-resolver.js.map +1 -0
- package/esm/util/resource-content-resolver.test.d.ts +2 -0
- package/esm/util/resource-content-resolver.test.d.ts.map +1 -0
- package/esm/util/resource-content-resolver.test.js +252 -0
- package/esm/util/resource-content-resolver.test.js.map +1 -0
- package/esm/util/resource-validators.test.d.ts +2 -0
- package/esm/util/resource-validators.test.d.ts.map +1 -0
- package/esm/util/resource-validators.test.js +88 -0
- package/esm/util/resource-validators.test.js.map +1 -0
- package/esm/util/tool-caller.d.ts +2 -2
- package/esm/util/tool-caller.d.ts.map +1 -1
- package/esm/util/tool-caller.js +8 -8
- package/esm/util/tool-caller.js.map +1 -1
- package/esm/util/validate-component-name.test.d.ts +2 -0
- package/esm/util/validate-component-name.test.d.ts.map +1 -0
- package/esm/util/validate-component-name.test.js +33 -0
- package/esm/util/validate-component-name.test.js.map +1 -0
- package/package.json +15 -23
- package/dist/schema/alias.d.ts +0 -3
- package/dist/schema/alias.d.ts.map +0 -1
- package/dist/schema/alias.js +0 -6
- package/dist/schema/alias.js.map +0 -1
- package/esm/schema/alias.d.ts +0 -3
- package/esm/schema/alias.d.ts.map +0 -1
- package/esm/schema/alias.js +0 -13
- package/esm/schema/alias.js.map +0 -1
package/esm/mcp/mcp-hooks.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ListPromptsResult, type ListResourcesResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import { UseQueryResult } from "@tanstack/react-query";
|
|
3
|
-
import { type ConnectedMcpServer } from "./tambo-mcp-provider";
|
|
3
|
+
import { type ConnectedMcpServer, type McpServer } from "./tambo-mcp-provider";
|
|
4
4
|
export type ListPromptItem = ListPromptsResult["prompts"][number];
|
|
5
5
|
export interface ListPromptEntry {
|
|
6
6
|
server: ConnectedMcpServer;
|
|
@@ -10,9 +10,7 @@ export type ListResourceItem = ListResourcesResult["resources"][number];
|
|
|
10
10
|
/**
|
|
11
11
|
* Registry resource entry - resources from the local registry (not MCP servers).
|
|
12
12
|
*
|
|
13
|
-
* These entries always have `server === null
|
|
14
|
-
* are registered locally via `TamboRegistryProvider` (static `resources`
|
|
15
|
-
* props or dynamic `ResourceSource` functions).
|
|
13
|
+
* These entries always have `server === null`.
|
|
16
14
|
*/
|
|
17
15
|
export interface RegistryResourceEntry {
|
|
18
16
|
server: null;
|
|
@@ -20,9 +18,6 @@ export interface RegistryResourceEntry {
|
|
|
20
18
|
}
|
|
21
19
|
/**
|
|
22
20
|
* MCP server resource entry - resources from connected MCP servers.
|
|
23
|
-
*
|
|
24
|
-
* These entries always have a non-null `server` with connection metadata and
|
|
25
|
-
* are produced by the active MCP clients managed by `TamboMcpProvider`.
|
|
26
21
|
*/
|
|
27
22
|
export interface McpResourceEntry {
|
|
28
23
|
server: ConnectedMcpServer;
|
|
@@ -30,21 +25,18 @@ export interface McpResourceEntry {
|
|
|
30
25
|
}
|
|
31
26
|
/**
|
|
32
27
|
* Union type for all resource entries returned by `useTamboMcpResourceList`.
|
|
33
|
-
*
|
|
34
|
-
* - Registry resources have `server === null`.
|
|
35
|
-
* - MCP-backed resources have a non-null `server` with connection metadata.
|
|
36
28
|
*/
|
|
37
29
|
export type ListResourceEntry = RegistryResourceEntry | McpResourceEntry;
|
|
38
30
|
/**
|
|
39
|
-
* Type guard for narrowing a `ListResourceEntry` to an MCP-backed resource
|
|
40
|
-
* (entries where `server` is non-null).
|
|
31
|
+
* Type guard for narrowing a `ListResourceEntry` to an MCP-backed resource.
|
|
41
32
|
*/
|
|
42
33
|
export declare function isMcpResourceEntry(entry: ListResourceEntry): entry is McpResourceEntry;
|
|
43
34
|
/**
|
|
44
35
|
* Hook to get the prompts for all the registered MCP servers.
|
|
36
|
+
* @param search - Optional search string to filter prompts by name (case-insensitive).
|
|
45
37
|
* @returns The prompts for the MCP servers, including the server that the prompt was found on.
|
|
46
38
|
*/
|
|
47
|
-
export declare function useTamboMcpPromptList(): {
|
|
39
|
+
export declare function useTamboMcpPromptList(search?: string): {
|
|
48
40
|
data: {
|
|
49
41
|
prompt: {
|
|
50
42
|
name: string;
|
|
@@ -61,6 +53,7 @@ export declare function useTamboMcpPromptList(): {
|
|
|
61
53
|
src: string;
|
|
62
54
|
mimeType?: string | undefined;
|
|
63
55
|
sizes?: string[] | undefined;
|
|
56
|
+
theme?: "light" | "dark" | undefined;
|
|
64
57
|
}[] | undefined;
|
|
65
58
|
title?: string | undefined;
|
|
66
59
|
};
|
|
@@ -77,6 +70,11 @@ export declare function useTamboMcpPromptList(): {
|
|
|
77
70
|
isLoading: boolean;
|
|
78
71
|
refetch: () => Promise<void>;
|
|
79
72
|
};
|
|
73
|
+
/**
|
|
74
|
+
* Type guard for narrowing McpServer to ConnectedMcpServer.
|
|
75
|
+
* A connected server has a non-null client.
|
|
76
|
+
*/
|
|
77
|
+
export declare function isConnectedMcpServer(server: McpServer): server is ConnectedMcpServer;
|
|
80
78
|
/**
|
|
81
79
|
* Hook to get the prompt for the specified name.
|
|
82
80
|
* @param promptName - The name of the prompt to get. Can be prefixed with serverKey (e.g., "linear:issue") or unprefixed.
|
|
@@ -140,6 +138,7 @@ export declare function useTamboMcpPrompt(promptName: string | undefined, args?:
|
|
|
140
138
|
src: string;
|
|
141
139
|
mimeType?: string | undefined;
|
|
142
140
|
sizes?: string[] | undefined;
|
|
141
|
+
theme?: "light" | "dark" | undefined;
|
|
143
142
|
}[] | undefined;
|
|
144
143
|
title?: string | undefined;
|
|
145
144
|
} | {
|
|
@@ -171,8 +170,8 @@ export declare function useTamboMcpPrompt(promptName: string | undefined, args?:
|
|
|
171
170
|
}[];
|
|
172
171
|
_meta?: {
|
|
173
172
|
[x: string]: unknown;
|
|
173
|
+
progressToken?: string | number | undefined;
|
|
174
174
|
"io.modelcontextprotocol/related-task"?: {
|
|
175
|
-
[x: string]: unknown;
|
|
176
175
|
taskId: string;
|
|
177
176
|
} | undefined;
|
|
178
177
|
} | undefined;
|
|
@@ -180,32 +179,12 @@ export declare function useTamboMcpPrompt(promptName: string | undefined, args?:
|
|
|
180
179
|
} | null, Error>;
|
|
181
180
|
/**
|
|
182
181
|
* Hook to get the resources for all the registered MCP servers and registry.
|
|
182
|
+
* @param search - Optional search string. For MCP servers, results are filtered locally after fetching.
|
|
183
|
+
* For registry dynamic sources, the search is passed to listResources(search) for dynamic generation.
|
|
183
184
|
* @returns The resources from MCP servers and the local registry, including the server that the resource was found on (null for registry resources).
|
|
184
185
|
*/
|
|
185
|
-
export declare function useTamboMcpResourceList(): {
|
|
186
|
-
data:
|
|
187
|
-
resource: {
|
|
188
|
-
uri: string;
|
|
189
|
-
name: string;
|
|
190
|
-
description?: string | undefined;
|
|
191
|
-
mimeType?: string | undefined;
|
|
192
|
-
annotations?: {
|
|
193
|
-
audience?: ("user" | "assistant")[] | undefined;
|
|
194
|
-
priority?: number | undefined;
|
|
195
|
-
lastModified?: string | undefined;
|
|
196
|
-
} | undefined;
|
|
197
|
-
_meta?: {
|
|
198
|
-
[x: string]: unknown;
|
|
199
|
-
} | undefined;
|
|
200
|
-
icons?: {
|
|
201
|
-
src: string;
|
|
202
|
-
mimeType?: string | undefined;
|
|
203
|
-
sizes?: string[] | undefined;
|
|
204
|
-
}[] | undefined;
|
|
205
|
-
title?: string | undefined;
|
|
206
|
-
};
|
|
207
|
-
server: ConnectedMcpServer;
|
|
208
|
-
})[];
|
|
186
|
+
export declare function useTamboMcpResourceList(search?: string): {
|
|
187
|
+
data: ListResourceEntry[];
|
|
209
188
|
error: Error | null;
|
|
210
189
|
errors: Error[];
|
|
211
190
|
isPending: boolean;
|
|
@@ -219,7 +198,9 @@ export declare function useTamboMcpResourceList(): {
|
|
|
219
198
|
};
|
|
220
199
|
/**
|
|
221
200
|
* Hook to get the resource for the specified URI.
|
|
222
|
-
* @param resourceUri - The URI of the resource to get.
|
|
201
|
+
* @param resourceUri - The URI of the resource to get. Must be prefixed:
|
|
202
|
+
* - MCP resources: prefixed with serverKey (e.g., "linear:file://foo")
|
|
203
|
+
* - Registry resources: prefixed with "registry:" (e.g., "registry:file://bar")
|
|
223
204
|
* @returns The resource for the specified URI.
|
|
224
205
|
*/
|
|
225
206
|
export declare function useTamboMcpResource(resourceUri: string | undefined): UseQueryResult<{
|
|
@@ -241,8 +222,8 @@ export declare function useTamboMcpResource(resourceUri: string | undefined): Us
|
|
|
241
222
|
})[];
|
|
242
223
|
_meta?: {
|
|
243
224
|
[x: string]: unknown;
|
|
225
|
+
progressToken?: string | number | undefined;
|
|
244
226
|
"io.modelcontextprotocol/related-task"?: {
|
|
245
|
-
[x: string]: unknown;
|
|
246
227
|
taskId: string;
|
|
247
228
|
} | undefined;
|
|
248
229
|
} | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-hooks.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EAEzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-hooks.d.ts","sourceRoot":"","sources":["../../src/mcp/mcp-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EAEzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAKvD,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,SAAS,EAEf,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,cAAc,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAClE,MAAM,WAAW,eAAe;IAE9B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,IAAI,CAAC;IACb,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,GAAG,gBAAgB,CAAC;AAoBzE;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,iBAAiB,GACvB,KAAK,IAAI,gBAAgB,CAE3B;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;gBA7D3C,kBAAkB;;WAyHnB,KAAK,GAAG,IAAI;YACX,KAAK,EAAE;eACJ,OAAO;eACP,OAAO;aACT,OAAO;cACN,OAAO;kBACH,OAAO;gBACT,OAAO;eACR,OAAO;aACT,MAAM,OAAO,CAAC,IAAI,CAAC;EAb7B;AAmDD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,GAChB,MAAM,IAAI,kBAAkB,CAE9B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0ClC;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,MAAM;;WAnH9C,KAAK,GAAG,IAAI;YACX,KAAK,EAAE;eACJ,OAAO;eACP,OAAO;aACT,OAAO;cACN,OAAO;kBACH,OAAO;gBACT,OAAO;eACR,OAAO;aACT,MAAM,OAAO,CAAC,IAAI,CAAC;EAsO7B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;iBAoElE"}
|
package/esm/mcp/mcp-hooks.js
CHANGED
|
@@ -1,21 +1,31 @@
|
|
|
1
|
+
import * as React from "react";
|
|
1
2
|
import { useTamboQueries, useTamboQuery } from "../hooks";
|
|
2
3
|
import { useTamboRegistry } from "../providers/tambo-registry-provider";
|
|
4
|
+
import { REGISTRY_SERVER_KEY } from "./mcp-constants";
|
|
3
5
|
import { useTamboMcpServers, } from "./tambo-mcp-provider";
|
|
6
|
+
function toPublicResourceEntry(entry) {
|
|
7
|
+
if (entry.server === null) {
|
|
8
|
+
const { isDynamic: _isDynamic, ...publicEntry } = entry;
|
|
9
|
+
return publicEntry;
|
|
10
|
+
}
|
|
11
|
+
return entry;
|
|
12
|
+
}
|
|
4
13
|
/**
|
|
5
|
-
* Type guard for narrowing a `ListResourceEntry` to an MCP-backed resource
|
|
6
|
-
* (entries where `server` is non-null).
|
|
14
|
+
* Type guard for narrowing a `ListResourceEntry` to an MCP-backed resource.
|
|
7
15
|
*/
|
|
8
16
|
export function isMcpResourceEntry(entry) {
|
|
9
17
|
return entry.server !== null && isConnectedMcpServer(entry.server);
|
|
10
18
|
}
|
|
11
19
|
/**
|
|
12
20
|
* Hook to get the prompts for all the registered MCP servers.
|
|
21
|
+
* @param search - Optional search string to filter prompts by name (case-insensitive).
|
|
13
22
|
* @returns The prompts for the MCP servers, including the server that the prompt was found on.
|
|
14
23
|
*/
|
|
15
|
-
export function useTamboMcpPromptList() {
|
|
24
|
+
export function useTamboMcpPromptList(search) {
|
|
16
25
|
const mcpServers = useTamboMcpServers();
|
|
17
26
|
const queries = useTamboQueries({
|
|
18
27
|
queries: mcpServers.map((mcpServer) => ({
|
|
28
|
+
// search is NOT in queryKey - we filter locally after fetching
|
|
19
29
|
queryKey: ["mcp-prompts", mcpServer.key],
|
|
20
30
|
// Only run for connected servers that have a client
|
|
21
31
|
enabled: isConnectedMcpServer(mcpServer),
|
|
@@ -49,7 +59,20 @@ export function useTamboMcpPromptList() {
|
|
|
49
59
|
};
|
|
50
60
|
},
|
|
51
61
|
});
|
|
52
|
-
|
|
62
|
+
// Filter results by search string - runs on every search change (not just query completion)
|
|
63
|
+
const filteredData = React.useMemo(() => {
|
|
64
|
+
if (!search)
|
|
65
|
+
return queries.data;
|
|
66
|
+
const normalizedSearch = search.toLowerCase();
|
|
67
|
+
return queries.data.filter((entry) => {
|
|
68
|
+
const name = entry.prompt.name?.toLowerCase() ?? "";
|
|
69
|
+
return name.includes(normalizedSearch);
|
|
70
|
+
});
|
|
71
|
+
}, [queries.data, search]);
|
|
72
|
+
return {
|
|
73
|
+
...queries,
|
|
74
|
+
data: filteredData,
|
|
75
|
+
};
|
|
53
76
|
}
|
|
54
77
|
// TODO: find a more general place for this
|
|
55
78
|
function combineArrayResults(results) {
|
|
@@ -79,8 +102,11 @@ function combineArrayResults(results) {
|
|
|
79
102
|
},
|
|
80
103
|
};
|
|
81
104
|
}
|
|
82
|
-
|
|
83
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Type guard for narrowing McpServer to ConnectedMcpServer.
|
|
107
|
+
* A connected server has a non-null client.
|
|
108
|
+
*/
|
|
109
|
+
export function isConnectedMcpServer(server) {
|
|
84
110
|
return "client" in server && server.client != null;
|
|
85
111
|
}
|
|
86
112
|
/**
|
|
@@ -125,14 +151,16 @@ export function useTamboMcpPrompt(promptName, args = {}) {
|
|
|
125
151
|
}
|
|
126
152
|
/**
|
|
127
153
|
* Hook to get the resources for all the registered MCP servers and registry.
|
|
154
|
+
* @param search - Optional search string. For MCP servers, results are filtered locally after fetching.
|
|
155
|
+
* For registry dynamic sources, the search is passed to listResources(search) for dynamic generation.
|
|
128
156
|
* @returns The resources from MCP servers and the local registry, including the server that the resource was found on (null for registry resources).
|
|
129
157
|
*/
|
|
130
|
-
export function useTamboMcpResourceList() {
|
|
158
|
+
export function useTamboMcpResourceList(search) {
|
|
131
159
|
const mcpServers = useTamboMcpServers();
|
|
132
160
|
const { resources: staticResources, resourceSource } = useTamboRegistry();
|
|
133
161
|
// Build list of queries: MCP servers + optional dynamic resource source
|
|
134
162
|
const queriesToRun = [
|
|
135
|
-
// MCP server queries
|
|
163
|
+
// MCP server queries - search is NOT in queryKey so queries don't re-run on search change
|
|
136
164
|
...mcpServers.map((mcpServer) => ({
|
|
137
165
|
queryKey: ["mcp-resources", mcpServer.key],
|
|
138
166
|
// Only run for connected servers that have a client
|
|
@@ -151,19 +179,20 @@ export function useTamboMcpResourceList() {
|
|
|
151
179
|
return resourceEntries;
|
|
152
180
|
},
|
|
153
181
|
})),
|
|
154
|
-
// Dynamic resource source query (if exists)
|
|
182
|
+
// Dynamic resource source query (if exists) - search IS in queryKey to allow dynamic generation
|
|
155
183
|
...(resourceSource
|
|
156
184
|
? [
|
|
157
185
|
{
|
|
158
|
-
queryKey: ["registry-resources", "dynamic"],
|
|
186
|
+
queryKey: ["registry-resources", "dynamic", search],
|
|
159
187
|
enabled: true,
|
|
160
188
|
queryFn: async () => {
|
|
161
189
|
if (!resourceSource)
|
|
162
190
|
return [];
|
|
163
|
-
const resources = await resourceSource.listResources();
|
|
191
|
+
const resources = await resourceSource.listResources(search);
|
|
164
192
|
return resources.map((resource) => ({
|
|
165
193
|
server: null,
|
|
166
194
|
resource,
|
|
195
|
+
isDynamic: true,
|
|
167
196
|
}));
|
|
168
197
|
},
|
|
169
198
|
},
|
|
@@ -179,15 +208,22 @@ export function useTamboMcpResourceList() {
|
|
|
179
208
|
const staticEntries = staticResources.map((resource) => ({
|
|
180
209
|
server: null,
|
|
181
210
|
resource,
|
|
211
|
+
isDynamic: false,
|
|
182
212
|
}));
|
|
183
213
|
// Merge static resources with query results (registry resources first)
|
|
184
214
|
const allData = [...staticEntries, ...combined.data];
|
|
185
|
-
// Apply serverKey prefix to ALL
|
|
186
|
-
// Registry resources
|
|
215
|
+
// Apply serverKey prefix to ALL resources for unified @serverKey:uri format
|
|
216
|
+
// Registry resources get REGISTRY_SERVER_KEY prefix, MCP resources get their serverKey
|
|
187
217
|
const prefixedData = allData.map((entry) => {
|
|
188
218
|
if (entry.server === null) {
|
|
189
|
-
// Registry resource -
|
|
190
|
-
return
|
|
219
|
+
// Registry resource - prefix with REGISTRY_SERVER_KEY
|
|
220
|
+
return {
|
|
221
|
+
...entry,
|
|
222
|
+
resource: {
|
|
223
|
+
...entry.resource,
|
|
224
|
+
uri: `${REGISTRY_SERVER_KEY}:${entry.resource.uri}`,
|
|
225
|
+
},
|
|
226
|
+
};
|
|
191
227
|
}
|
|
192
228
|
// MCP resource - always prefix with serverKey
|
|
193
229
|
return {
|
|
@@ -204,11 +240,34 @@ export function useTamboMcpResourceList() {
|
|
|
204
240
|
};
|
|
205
241
|
},
|
|
206
242
|
});
|
|
207
|
-
|
|
243
|
+
// Filter results by search string - runs on every search change (not just query completion)
|
|
244
|
+
// - MCP resources are filtered locally
|
|
245
|
+
// - Static registry resources are filtered locally
|
|
246
|
+
// - Dynamic registry resources are already filtered by listResources(search)
|
|
247
|
+
const filteredData = React.useMemo(() => {
|
|
248
|
+
if (!search)
|
|
249
|
+
return queries.data;
|
|
250
|
+
const normalizedSearch = search.toLowerCase();
|
|
251
|
+
return queries.data.filter((entry) => {
|
|
252
|
+
if (entry.server === null && entry.isDynamic) {
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
const name = entry.resource.name?.toLowerCase() ?? "";
|
|
256
|
+
const uri = entry.resource.uri.toLowerCase();
|
|
257
|
+
return name.includes(normalizedSearch) || uri.includes(normalizedSearch);
|
|
258
|
+
});
|
|
259
|
+
}, [queries.data, search]);
|
|
260
|
+
const publicData = React.useMemo(() => filteredData.map(toPublicResourceEntry), [filteredData]);
|
|
261
|
+
return {
|
|
262
|
+
...queries,
|
|
263
|
+
data: publicData,
|
|
264
|
+
};
|
|
208
265
|
}
|
|
209
266
|
/**
|
|
210
267
|
* Hook to get the resource for the specified URI.
|
|
211
|
-
* @param resourceUri - The URI of the resource to get.
|
|
268
|
+
* @param resourceUri - The URI of the resource to get. Must be prefixed:
|
|
269
|
+
* - MCP resources: prefixed with serverKey (e.g., "linear:file://foo")
|
|
270
|
+
* - Registry resources: prefixed with "registry:" (e.g., "registry:file://bar")
|
|
212
271
|
* @returns The resource for the specified URI.
|
|
213
272
|
*/
|
|
214
273
|
export function useTamboMcpResource(resourceUri) {
|
|
@@ -216,30 +275,30 @@ export function useTamboMcpResource(resourceUri) {
|
|
|
216
275
|
const { data: resourceEntries } = useTamboMcpResourceList();
|
|
217
276
|
// Find which server/source has the resource
|
|
218
277
|
const resourceEntry = resourceEntries?.find((entry) => entry.resource.uri === resourceUri);
|
|
219
|
-
// Determine if this is a
|
|
220
|
-
const
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
//
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
// fetched when a resourceSource exists, even if they haven't appeared in a
|
|
230
|
-
// previous listResources result.
|
|
231
|
-
const hasRegistrySource = resourceSource != null;
|
|
232
|
-
const hasConnectedMcpServer = isKnownEntry && mcpServer != null && isConnectedMcpServer(mcpServer);
|
|
233
|
-
const canFetchResource = Boolean(resourceUri && (hasRegistrySource || hasConnectedMcpServer));
|
|
234
|
-
let locationKey;
|
|
235
|
-
if (isRegistryResource || (!isKnownEntry && hasRegistrySource)) {
|
|
236
|
-
locationKey = "registry";
|
|
278
|
+
// Determine if this is a registry resource or MCP resource
|
|
279
|
+
const isRegistryResource = resourceEntry?.server === null;
|
|
280
|
+
const mcpServer = resourceEntry?.server ?? null;
|
|
281
|
+
// Check if the URI has the registry prefix
|
|
282
|
+
const hasRegistryPrefix = Boolean(resourceUri?.startsWith(`${REGISTRY_SERVER_KEY}:`));
|
|
283
|
+
// Strip the prefix to get the original resource URI for fetching
|
|
284
|
+
let originalResourceUri;
|
|
285
|
+
if (isRegistryResource || hasRegistryPrefix) {
|
|
286
|
+
const prefixLen = REGISTRY_SERVER_KEY.length + 1; // +1 for the colon
|
|
287
|
+
originalResourceUri = resourceUri?.slice(prefixLen);
|
|
237
288
|
}
|
|
238
289
|
else if (mcpServer) {
|
|
239
|
-
|
|
290
|
+
const prefixLen = mcpServer.serverKey.length + 1; // +1 for the colon
|
|
291
|
+
originalResourceUri = resourceUri?.slice(prefixLen);
|
|
240
292
|
}
|
|
293
|
+
// Check if we can fetch this resource
|
|
294
|
+
const hasRegistrySource = resourceSource != null;
|
|
295
|
+
const hasConnectedMcpServer = mcpServer != null && isConnectedMcpServer(mcpServer);
|
|
296
|
+
const canFetchFromRegistry = hasRegistrySource && (isRegistryResource || hasRegistryPrefix);
|
|
297
|
+
const canFetchResource = Boolean(resourceUri && (canFetchFromRegistry || hasConnectedMcpServer));
|
|
298
|
+
const locationKey = isRegistryResource || hasRegistryPrefix
|
|
299
|
+
? REGISTRY_SERVER_KEY
|
|
300
|
+
: mcpServer?.key;
|
|
241
301
|
return useTamboQuery({
|
|
242
|
-
// Include server identity or "registry" to prevent stale cache hits
|
|
243
302
|
queryKey: ["resource", resourceUri, locationKey],
|
|
244
303
|
enabled: canFetchResource,
|
|
245
304
|
queryFn: async () => {
|
|
@@ -247,9 +306,7 @@ export function useTamboMcpResource(resourceUri) {
|
|
|
247
306
|
return null;
|
|
248
307
|
}
|
|
249
308
|
// Registry resource: use resourceSource.getResource
|
|
250
|
-
|
|
251
|
-
// a registry resource by default.
|
|
252
|
-
if (resourceSource && (!isKnownEntry || isRegistryResource)) {
|
|
309
|
+
if (resourceSource && (isRegistryResource || hasRegistryPrefix)) {
|
|
253
310
|
const result = await resourceSource.getResource(originalResourceUri);
|
|
254
311
|
return result ?? null;
|
|
255
312
|
}
|
package/esm/mcp/mcp-hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-hooks.js","sourceRoot":"","sources":["../../src/mcp/mcp-hooks.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n GetPromptResult,\n type ListPromptsResult,\n type ListResourcesResult,\n type ReadResourceResult,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { UseQueryResult } from \"@tanstack/react-query\";\nimport { useTamboQueries, useTamboQuery } from \"../hooks\";\nimport { useTamboRegistry } from \"../providers/tambo-registry-provider\";\nimport {\n type ConnectedMcpServer,\n type McpServer,\n useTamboMcpServers,\n} from \"./tambo-mcp-provider\";\n\nexport type ListPromptItem = ListPromptsResult[\"prompts\"][number];\nexport interface ListPromptEntry {\n // Only connected servers produce prompt entries, so expose the connected type\n server: ConnectedMcpServer;\n prompt: ListPromptItem;\n}\n\nexport type ListResourceItem = ListResourcesResult[\"resources\"][number];\n\n/**\n * Registry resource entry - resources from the local registry (not MCP servers).\n *\n * These entries always have `server === null` and represent resources that\n * are registered locally via `TamboRegistryProvider` (static `resources`\n * props or dynamic `ResourceSource` functions).\n */\nexport interface RegistryResourceEntry {\n server: null;\n resource: ListResourceItem;\n}\n\n/**\n * MCP server resource entry - resources from connected MCP servers.\n *\n * These entries always have a non-null `server` with connection metadata and\n * are produced by the active MCP clients managed by `TamboMcpProvider`.\n */\nexport interface McpResourceEntry {\n server: ConnectedMcpServer;\n resource: ListResourceItem;\n}\n\n/**\n * Union type for all resource entries returned by `useTamboMcpResourceList`.\n *\n * - Registry resources have `server === null`.\n * - MCP-backed resources have a non-null `server` with connection metadata.\n */\nexport type ListResourceEntry = RegistryResourceEntry | McpResourceEntry;\n\n/**\n * Type guard for narrowing a `ListResourceEntry` to an MCP-backed resource\n * (entries where `server` is non-null).\n */\nexport function isMcpResourceEntry(\n entry: ListResourceEntry,\n): entry is McpResourceEntry {\n return entry.server !== null && isConnectedMcpServer(entry.server);\n}\n\n/**\n * Hook to get the prompts for all the registered MCP servers.\n * @returns The prompts for the MCP servers, including the server that the prompt was found on.\n */\nexport function useTamboMcpPromptList() {\n const mcpServers = useTamboMcpServers();\n\n const queries = useTamboQueries({\n queries: mcpServers.map((mcpServer) => ({\n queryKey: [\"mcp-prompts\", mcpServer.key],\n // Only run for connected servers that have a client\n enabled: isConnectedMcpServer(mcpServer),\n queryFn: async (): Promise<ListPromptEntry[]> => {\n // Fast path: if this server doesn't have a client, skip work\n if (!isConnectedMcpServer(mcpServer)) return [];\n\n const result = await mcpServer.client.client.listPrompts();\n const prompts: ListPromptItem[] = result?.prompts ?? [];\n // Return prompts without prefixes - we'll apply prefixing in combine\n const promptsEntries = prompts.map((prompt) => ({\n server: mcpServer,\n prompt,\n }));\n return promptsEntries;\n },\n })),\n combine: (results) => {\n const combined = combineArrayResults(results);\n\n // Always apply serverKey prefix to MCP prompts (breaking change for consistency with resources)\n // This ensures clear separation between local and remote prompts\n return {\n ...combined,\n data: combined.data.map((entry) => ({\n ...entry,\n prompt: {\n ...entry.prompt,\n name: `${entry.server.serverKey}:${entry.prompt.name}`,\n },\n })),\n };\n },\n });\n\n return queries;\n}\n// TODO: find a more general place for this\nfunction combineArrayResults<T>(results: UseQueryResult<T[]>[]): {\n data: T[];\n error: Error | null;\n errors: Error[];\n isPending: boolean;\n isSuccess: boolean;\n isError: boolean;\n isPaused: boolean;\n isRefetching: boolean;\n isFetching: boolean;\n isLoading: boolean;\n refetch: () => Promise<void>;\n} {\n const errors = results\n .filter((result) => result.isError)\n .map((result) => result.error);\n\n // Treat queries that are idle (disabled) as non-blocking for aggregate status\n const enabledish = results.filter(\n (r) => r.fetchStatus !== \"idle\" || r.isSuccess || r.isError,\n );\n\n return {\n // Prefer flatMap to avoid extra intermediate arrays\n data: results.flatMap((result) =>\n result.isSuccess && Array.isArray(result.data) ? result.data : [],\n ),\n // Preserve a single error for compatibility and expose the full list for diagnostics\n error: errors[0] ?? null,\n errors,\n isPending: enabledish.some((result) => result.isPending),\n isSuccess:\n enabledish.length > 0 && enabledish.every((result) => result.isSuccess),\n isError: errors.length > 0,\n isPaused: enabledish.some((result) => result.isPaused),\n isRefetching: enabledish.some((result) => result.isRefetching),\n isFetching: enabledish.some((result) => result.isFetching),\n isLoading: enabledish.some((result) => result.isLoading),\n // Aggregate refetch to trigger all underlying queries\n refetch: async () => {\n await Promise.all(\n results.map(async (r) => {\n await r.refetch();\n }),\n );\n },\n };\n}\n\n// Type guard for narrowing to connected servers\nfunction isConnectedMcpServer(server: McpServer): server is ConnectedMcpServer {\n return \"client\" in server && server.client != null;\n}\n\n/**\n * Hook to get the prompt for the specified name.\n * @param promptName - The name of the prompt to get. Can be prefixed with serverKey (e.g., \"linear:issue\") or unprefixed.\n * @param args - The arguments to pass to the prompt.\n * @returns The prompt for the specified name.\n */\nexport function useTamboMcpPrompt(\n promptName: string | undefined,\n args: Record<string, string> = {},\n) {\n // figure out which server has the prompt\n const { data: promptEntries } = useTamboMcpPromptList();\n const promptEntry = promptEntries?.find(\n (prompt) => prompt.prompt.name === promptName,\n );\n // Use the stable server key (and the server instance itself) instead of brittle\n // name/url/transport matching.\n const mcpServer = promptEntry?.server;\n\n // Strip the prefix to get the original prompt name for the MCP server call\n const originalPromptName = promptName?.includes(\":\")\n ? promptName.split(\":\").slice(1).join(\":\")\n : promptName;\n\n // Canonicalize args to avoid unstable cache keys from object identity/order\n const sortedArgsEntries = Object.keys(args)\n .sort()\n .map((k) => [k, args[k]] as const);\n return useTamboQuery({\n // Include server identity and sorted args to prevent stale cache hits\n queryKey: [\"mcp-prompt\", promptName, mcpServer?.key, sortedArgsEntries],\n // Only run when we have a prompt name and a connected server\n enabled: Boolean(\n promptName && mcpServer && isConnectedMcpServer(mcpServer),\n ),\n queryFn: async (): Promise<GetPromptResult | null> => {\n if (\n !originalPromptName ||\n !mcpServer ||\n !isConnectedMcpServer(mcpServer)\n ) {\n return null;\n }\n const result = await mcpServer.client.client.getPrompt({\n name: originalPromptName,\n arguments: args,\n });\n return result ?? null; // return null because react-query doesn't like undefined results\n },\n });\n}\n\n/**\n * Hook to get the resources for all the registered MCP servers and registry.\n * @returns The resources from MCP servers and the local registry, including the server that the resource was found on (null for registry resources).\n */\nexport function useTamboMcpResourceList() {\n const mcpServers = useTamboMcpServers();\n const { resources: staticResources, resourceSource } = useTamboRegistry();\n\n // Build list of queries: MCP servers + optional dynamic resource source\n const queriesToRun = [\n // MCP server queries\n ...mcpServers.map((mcpServer) => ({\n queryKey: [\"mcp-resources\", mcpServer.key],\n // Only run for connected servers that have a client\n enabled: isConnectedMcpServer(mcpServer),\n queryFn: async (): Promise<McpResourceEntry[]> => {\n // Fast path: if this server doesn't have a client, skip work\n if (!isConnectedMcpServer(mcpServer)) return [];\n\n const result = await mcpServer.client.client.listResources();\n const resources: ListResourceItem[] = result?.resources ?? [];\n // Return resources without prefixes - we'll apply prefixing in combine\n const resourceEntries: McpResourceEntry[] = resources.map(\n (resource) => ({\n server: mcpServer,\n resource,\n }),\n );\n return resourceEntries;\n },\n })),\n // Dynamic resource source query (if exists)\n ...(resourceSource\n ? [\n {\n queryKey: [\"registry-resources\", \"dynamic\"],\n enabled: true,\n queryFn: async (): Promise<RegistryResourceEntry[]> => {\n if (!resourceSource) return [];\n const resources = await resourceSource.listResources();\n return resources.map((resource) => ({\n server: null,\n resource,\n }));\n },\n },\n ]\n : []),\n ];\n\n const queries = useTamboQueries({\n queries: queriesToRun,\n combine: (results) => {\n // Type assertion needed because queries can return different entry types\n const combined = combineArrayResults(\n results as UseQueryResult<ListResourceEntry[]>[],\n );\n\n // Add static registry resources (no query needed)\n const staticEntries: RegistryResourceEntry[] = staticResources.map(\n (resource) => ({\n server: null,\n resource,\n }),\n );\n\n // Merge static resources with query results (registry resources first)\n const allData = [...staticEntries, ...combined.data];\n\n // Apply serverKey prefix to ALL MCP resources (breaking change)\n // Registry resources (server: null) are never prefixed\n const prefixedData = allData.map((entry) => {\n if (entry.server === null) {\n // Registry resource - no prefix\n return entry;\n }\n // MCP resource - always prefix with serverKey\n return {\n ...entry,\n resource: {\n ...entry.resource,\n uri: `${entry.server.serverKey}:${entry.resource.uri}`,\n },\n };\n });\n\n return {\n ...combined,\n data: prefixedData,\n };\n },\n });\n\n return queries;\n}\n\n/**\n * Hook to get the resource for the specified URI.\n * @param resourceUri - The URI of the resource to get. Can be prefixed with serverKey (e.g., \"linear:file://foo\") for MCP resources, or unprefixed for registry resources.\n * @returns The resource for the specified URI.\n */\nexport function useTamboMcpResource(resourceUri: string | undefined) {\n const { resourceSource } = useTamboRegistry();\n const { data: resourceEntries } = useTamboMcpResourceList();\n\n // Find which server/source has the resource\n const resourceEntry = resourceEntries?.find(\n (entry) => entry.resource.uri === resourceUri,\n );\n\n // Determine if this is a known registry resource or MCP resource\n const isKnownEntry = resourceEntry != null;\n const isRegistryResource = isKnownEntry && resourceEntry.server === null;\n const mcpServer =\n isKnownEntry && resourceEntry.server != null ? resourceEntry.server : null;\n\n // Strip the prefix to get the original resource URI for the MCP server call\n // Only strip if we found a matching resource entry with an MCP server\n const originalResourceUri =\n isKnownEntry && mcpServer\n ? resourceUri?.replace(`${mcpServer.serverKey}:`, \"\")\n : resourceUri;\n\n // Check if we can fetch this resource. Registry resources can always be\n // fetched when a resourceSource exists, even if they haven't appeared in a\n // previous listResources result.\n const hasRegistrySource = resourceSource != null;\n const hasConnectedMcpServer =\n isKnownEntry && mcpServer != null && isConnectedMcpServer(mcpServer);\n const canFetchResource = Boolean(\n resourceUri && (hasRegistrySource || hasConnectedMcpServer),\n );\n\n let locationKey: string | undefined;\n if (isRegistryResource || (!isKnownEntry && hasRegistrySource)) {\n locationKey = \"registry\";\n } else if (mcpServer) {\n locationKey = mcpServer.key;\n }\n\n return useTamboQuery({\n // Include server identity or \"registry\" to prevent stale cache hits\n queryKey: [\"resource\", resourceUri, locationKey],\n enabled: canFetchResource,\n queryFn: async (): Promise<ReadResourceResult | null> => {\n if (!originalResourceUri) {\n return null;\n }\n\n // Registry resource: use resourceSource.getResource\n // If this is not a known entry but we have a resourceSource, treat it as\n // a registry resource by default.\n if (resourceSource && (!isKnownEntry || isRegistryResource)) {\n const result = await resourceSource.getResource(originalResourceUri);\n return result ?? null;\n }\n\n // MCP resource: use MCP client\n if (mcpServer && isConnectedMcpServer(mcpServer)) {\n const result = await mcpServer.client.client.readResource({\n uri: originalResourceUri,\n });\n return result ?? null;\n }\n\n return null;\n },\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mcp-hooks.js","sourceRoot":"","sources":["../../src/mcp/mcp-hooks.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n GetPromptResult,\n type ListPromptsResult,\n type ListResourcesResult,\n type ReadResourceResult,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { UseQueryResult } from \"@tanstack/react-query\";\nimport * as React from \"react\";\nimport { useTamboQueries, useTamboQuery } from \"../hooks\";\nimport { useTamboRegistry } from \"../providers/tambo-registry-provider\";\nimport { REGISTRY_SERVER_KEY } from \"./mcp-constants\";\nimport {\n type ConnectedMcpServer,\n type McpServer,\n useTamboMcpServers,\n} from \"./tambo-mcp-provider\";\n\nexport type ListPromptItem = ListPromptsResult[\"prompts\"][number];\nexport interface ListPromptEntry {\n // Only connected servers produce prompt entries, so expose the connected type\n server: ConnectedMcpServer;\n prompt: ListPromptItem;\n}\n\nexport type ListResourceItem = ListResourcesResult[\"resources\"][number];\n\n/**\n * Registry resource entry - resources from the local registry (not MCP servers).\n *\n * These entries always have `server === null`.\n */\nexport interface RegistryResourceEntry {\n server: null;\n resource: ListResourceItem;\n}\n\n/**\n * MCP server resource entry - resources from connected MCP servers.\n */\nexport interface McpResourceEntry {\n server: ConnectedMcpServer;\n resource: ListResourceItem;\n}\n\n/**\n * Union type for all resource entries returned by `useTamboMcpResourceList`.\n */\nexport type ListResourceEntry = RegistryResourceEntry | McpResourceEntry;\n\ntype InternalRegistryResourceEntry = RegistryResourceEntry & {\n isDynamic: boolean;\n};\n\ntype InternalListResourceEntry =\n | McpResourceEntry\n | InternalRegistryResourceEntry;\n\nfunction toPublicResourceEntry(\n entry: InternalListResourceEntry,\n): ListResourceEntry {\n if (entry.server === null) {\n const { isDynamic: _isDynamic, ...publicEntry } = entry;\n return publicEntry;\n }\n return entry;\n}\n\n/**\n * Type guard for narrowing a `ListResourceEntry` to an MCP-backed resource.\n */\nexport function isMcpResourceEntry(\n entry: ListResourceEntry,\n): entry is McpResourceEntry {\n return entry.server !== null && isConnectedMcpServer(entry.server);\n}\n\n/**\n * Hook to get the prompts for all the registered MCP servers.\n * @param search - Optional search string to filter prompts by name (case-insensitive).\n * @returns The prompts for the MCP servers, including the server that the prompt was found on.\n */\nexport function useTamboMcpPromptList(search?: string) {\n const mcpServers = useTamboMcpServers();\n\n const queries = useTamboQueries({\n queries: mcpServers.map((mcpServer) => ({\n // search is NOT in queryKey - we filter locally after fetching\n queryKey: [\"mcp-prompts\", mcpServer.key],\n // Only run for connected servers that have a client\n enabled: isConnectedMcpServer(mcpServer),\n queryFn: async (): Promise<ListPromptEntry[]> => {\n // Fast path: if this server doesn't have a client, skip work\n if (!isConnectedMcpServer(mcpServer)) return [];\n\n const result = await mcpServer.client.client.listPrompts();\n const prompts: ListPromptItem[] = result?.prompts ?? [];\n // Return prompts without prefixes - we'll apply prefixing in combine\n const promptsEntries = prompts.map((prompt) => ({\n server: mcpServer,\n prompt,\n }));\n return promptsEntries;\n },\n })),\n combine: (results) => {\n const combined = combineArrayResults(results);\n\n // Always apply serverKey prefix to MCP prompts (breaking change for consistency with resources)\n // This ensures clear separation between local and remote prompts\n return {\n ...combined,\n data: combined.data.map((entry) => ({\n ...entry,\n prompt: {\n ...entry.prompt,\n name: `${entry.server.serverKey}:${entry.prompt.name}`,\n },\n })),\n };\n },\n });\n\n // Filter results by search string - runs on every search change (not just query completion)\n const filteredData = React.useMemo(() => {\n if (!search) return queries.data;\n\n const normalizedSearch = search.toLowerCase();\n return queries.data.filter((entry) => {\n const name = entry.prompt.name?.toLowerCase() ?? \"\";\n return name.includes(normalizedSearch);\n });\n }, [queries.data, search]);\n\n return {\n ...queries,\n data: filteredData,\n };\n}\n// TODO: find a more general place for this\nfunction combineArrayResults<T>(results: UseQueryResult<T[]>[]): {\n data: T[];\n error: Error | null;\n errors: Error[];\n isPending: boolean;\n isSuccess: boolean;\n isError: boolean;\n isPaused: boolean;\n isRefetching: boolean;\n isFetching: boolean;\n isLoading: boolean;\n refetch: () => Promise<void>;\n} {\n const errors = results\n .filter((result) => result.isError)\n .map((result) => result.error);\n\n // Treat queries that are idle (disabled) as non-blocking for aggregate status\n const enabledish = results.filter(\n (r) => r.fetchStatus !== \"idle\" || r.isSuccess || r.isError,\n );\n\n return {\n // Prefer flatMap to avoid extra intermediate arrays\n data: results.flatMap((result) =>\n result.isSuccess && Array.isArray(result.data) ? result.data : [],\n ),\n // Preserve a single error for compatibility and expose the full list for diagnostics\n error: errors[0] ?? null,\n errors,\n isPending: enabledish.some((result) => result.isPending),\n isSuccess:\n enabledish.length > 0 && enabledish.every((result) => result.isSuccess),\n isError: errors.length > 0,\n isPaused: enabledish.some((result) => result.isPaused),\n isRefetching: enabledish.some((result) => result.isRefetching),\n isFetching: enabledish.some((result) => result.isFetching),\n isLoading: enabledish.some((result) => result.isLoading),\n // Aggregate refetch to trigger all underlying queries\n refetch: async () => {\n await Promise.all(\n results.map(async (r) => {\n await r.refetch();\n }),\n );\n },\n };\n}\n\n/**\n * Type guard for narrowing McpServer to ConnectedMcpServer.\n * A connected server has a non-null client.\n */\nexport function isConnectedMcpServer(\n server: McpServer,\n): server is ConnectedMcpServer {\n return \"client\" in server && server.client != null;\n}\n\n/**\n * Hook to get the prompt for the specified name.\n * @param promptName - The name of the prompt to get. Can be prefixed with serverKey (e.g., \"linear:issue\") or unprefixed.\n * @param args - The arguments to pass to the prompt.\n * @returns The prompt for the specified name.\n */\nexport function useTamboMcpPrompt(\n promptName: string | undefined,\n args: Record<string, string> = {},\n) {\n // figure out which server has the prompt\n const { data: promptEntries } = useTamboMcpPromptList();\n const promptEntry = promptEntries?.find(\n (prompt) => prompt.prompt.name === promptName,\n );\n // Use the stable server key (and the server instance itself) instead of brittle\n // name/url/transport matching.\n const mcpServer = promptEntry?.server;\n\n // Strip the prefix to get the original prompt name for the MCP server call\n const originalPromptName = promptName?.includes(\":\")\n ? promptName.split(\":\").slice(1).join(\":\")\n : promptName;\n\n // Canonicalize args to avoid unstable cache keys from object identity/order\n const sortedArgsEntries = Object.keys(args)\n .sort()\n .map((k) => [k, args[k]] as const);\n return useTamboQuery({\n // Include server identity and sorted args to prevent stale cache hits\n queryKey: [\"mcp-prompt\", promptName, mcpServer?.key, sortedArgsEntries],\n // Only run when we have a prompt name and a connected server\n enabled: Boolean(\n promptName && mcpServer && isConnectedMcpServer(mcpServer),\n ),\n queryFn: async (): Promise<GetPromptResult | null> => {\n if (\n !originalPromptName ||\n !mcpServer ||\n !isConnectedMcpServer(mcpServer)\n ) {\n return null;\n }\n const result = await mcpServer.client.client.getPrompt({\n name: originalPromptName,\n arguments: args,\n });\n return result ?? null; // return null because react-query doesn't like undefined results\n },\n });\n}\n\n/**\n * Hook to get the resources for all the registered MCP servers and registry.\n * @param search - Optional search string. For MCP servers, results are filtered locally after fetching.\n * For registry dynamic sources, the search is passed to listResources(search) for dynamic generation.\n * @returns The resources from MCP servers and the local registry, including the server that the resource was found on (null for registry resources).\n */\nexport function useTamboMcpResourceList(search?: string) {\n const mcpServers = useTamboMcpServers();\n const { resources: staticResources, resourceSource } = useTamboRegistry();\n\n // Build list of queries: MCP servers + optional dynamic resource source\n const queriesToRun = [\n // MCP server queries - search is NOT in queryKey so queries don't re-run on search change\n ...mcpServers.map((mcpServer) => ({\n queryKey: [\"mcp-resources\", mcpServer.key],\n // Only run for connected servers that have a client\n enabled: isConnectedMcpServer(mcpServer),\n queryFn: async (): Promise<McpResourceEntry[]> => {\n // Fast path: if this server doesn't have a client, skip work\n if (!isConnectedMcpServer(mcpServer)) return [];\n\n const result = await mcpServer.client.client.listResources();\n const resources: ListResourceItem[] = result?.resources ?? [];\n // Return resources without prefixes - we'll apply prefixing in combine\n const resourceEntries: McpResourceEntry[] = resources.map(\n (resource) => ({\n server: mcpServer,\n resource,\n }),\n );\n return resourceEntries;\n },\n })),\n // Dynamic resource source query (if exists) - search IS in queryKey to allow dynamic generation\n ...(resourceSource\n ? [\n {\n queryKey: [\"registry-resources\", \"dynamic\", search],\n enabled: true,\n queryFn: async (): Promise<InternalRegistryResourceEntry[]> => {\n if (!resourceSource) return [];\n const resources = await resourceSource.listResources(search);\n return resources.map((resource) => ({\n server: null,\n resource,\n isDynamic: true,\n }));\n },\n },\n ]\n : []),\n ];\n\n const queries = useTamboQueries({\n queries: queriesToRun,\n combine: (results) => {\n // Type assertion needed because queries can return different entry types\n const combined = combineArrayResults(\n results as UseQueryResult<InternalListResourceEntry[]>[],\n );\n\n // Add static registry resources (no query needed)\n const staticEntries: InternalRegistryResourceEntry[] =\n staticResources.map((resource) => ({\n server: null,\n resource,\n isDynamic: false,\n }));\n\n // Merge static resources with query results (registry resources first)\n const allData = [...staticEntries, ...combined.data];\n\n // Apply serverKey prefix to ALL resources for unified @serverKey:uri format\n // Registry resources get REGISTRY_SERVER_KEY prefix, MCP resources get their serverKey\n const prefixedData = allData.map((entry) => {\n if (entry.server === null) {\n // Registry resource - prefix with REGISTRY_SERVER_KEY\n return {\n ...entry,\n resource: {\n ...entry.resource,\n uri: `${REGISTRY_SERVER_KEY}:${entry.resource.uri}`,\n },\n };\n }\n // MCP resource - always prefix with serverKey\n return {\n ...entry,\n resource: {\n ...entry.resource,\n uri: `${entry.server.serverKey}:${entry.resource.uri}`,\n },\n };\n });\n\n return {\n ...combined,\n data: prefixedData,\n };\n },\n });\n\n // Filter results by search string - runs on every search change (not just query completion)\n // - MCP resources are filtered locally\n // - Static registry resources are filtered locally\n // - Dynamic registry resources are already filtered by listResources(search)\n const filteredData = React.useMemo((): InternalListResourceEntry[] => {\n if (!search) return queries.data;\n\n const normalizedSearch = search.toLowerCase();\n return queries.data.filter((entry) => {\n if (entry.server === null && entry.isDynamic) {\n return true;\n }\n\n const name = entry.resource.name?.toLowerCase() ?? \"\";\n const uri = entry.resource.uri.toLowerCase();\n return name.includes(normalizedSearch) || uri.includes(normalizedSearch);\n });\n }, [queries.data, search]);\n\n const publicData = React.useMemo(\n () => filteredData.map(toPublicResourceEntry),\n [filteredData],\n );\n\n return {\n ...queries,\n data: publicData,\n };\n}\n\n/**\n * Hook to get the resource for the specified URI.\n * @param resourceUri - The URI of the resource to get. Must be prefixed:\n * - MCP resources: prefixed with serverKey (e.g., \"linear:file://foo\")\n * - Registry resources: prefixed with \"registry:\" (e.g., \"registry:file://bar\")\n * @returns The resource for the specified URI.\n */\nexport function useTamboMcpResource(resourceUri: string | undefined) {\n const { resourceSource } = useTamboRegistry();\n const { data: resourceEntries } = useTamboMcpResourceList();\n\n // Find which server/source has the resource\n const resourceEntry = resourceEntries?.find(\n (entry) => entry.resource.uri === resourceUri,\n );\n\n // Determine if this is a registry resource or MCP resource\n const isRegistryResource = resourceEntry?.server === null;\n const mcpServer = resourceEntry?.server ?? null;\n\n // Check if the URI has the registry prefix\n const hasRegistryPrefix = Boolean(\n resourceUri?.startsWith(`${REGISTRY_SERVER_KEY}:`),\n );\n\n // Strip the prefix to get the original resource URI for fetching\n let originalResourceUri: string | undefined;\n if (isRegistryResource || hasRegistryPrefix) {\n const prefixLen = REGISTRY_SERVER_KEY.length + 1; // +1 for the colon\n originalResourceUri = resourceUri?.slice(prefixLen);\n } else if (mcpServer) {\n const prefixLen = mcpServer.serverKey.length + 1; // +1 for the colon\n originalResourceUri = resourceUri?.slice(prefixLen);\n }\n\n // Check if we can fetch this resource\n const hasRegistrySource = resourceSource != null;\n const hasConnectedMcpServer =\n mcpServer != null && isConnectedMcpServer(mcpServer);\n const canFetchFromRegistry =\n hasRegistrySource && (isRegistryResource || hasRegistryPrefix);\n const canFetchResource = Boolean(\n resourceUri && (canFetchFromRegistry || hasConnectedMcpServer),\n );\n\n const locationKey =\n isRegistryResource || hasRegistryPrefix\n ? REGISTRY_SERVER_KEY\n : mcpServer?.key;\n\n return useTamboQuery({\n queryKey: [\"resource\", resourceUri, locationKey],\n enabled: canFetchResource,\n queryFn: async (): Promise<ReadResourceResult | null> => {\n if (!originalResourceUri) {\n return null;\n }\n\n // Registry resource: use resourceSource.getResource\n if (resourceSource && (isRegistryResource || hasRegistryPrefix)) {\n const result = await resourceSource.getResource(originalResourceUri);\n return result ?? null;\n }\n\n // MCP resource: use MCP client\n if (mcpServer && isConnectedMcpServer(mcpServer)) {\n const result = await mcpServer.client.client.readResource({\n uri: originalResourceUri,\n });\n return result ?? null;\n }\n\n return null;\n },\n });\n}\n"]}
|