integrate-sdk 0.9.58 → 0.9.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/adapters/index.js +1 -1
  2. package/dist/adapters/solid-start.js +1 -1
  3. package/dist/adapters/svelte-kit.js +1 -1
  4. package/dist/ai/index.js +77 -0
  5. package/dist/ai/tool-cache.d.ts +50 -0
  6. package/dist/ai/tool-cache.d.ts.map +1 -0
  7. package/dist/ai/utils.d.ts +5 -0
  8. package/dist/ai/utils.d.ts.map +1 -1
  9. package/dist/ai/vercel-ai.d.ts.map +1 -1
  10. package/dist/ai/vercel-ai.js +77 -0
  11. package/dist/index.js +65 -1
  12. package/dist/integrations.js +65 -1
  13. package/dist/react.d.ts +2 -2
  14. package/dist/react.d.ts.map +1 -1
  15. package/dist/react.js +86 -0
  16. package/dist/server.js +341 -29
  17. package/dist/src/ai/tool-cache.d.ts +50 -0
  18. package/dist/src/ai/tool-cache.d.ts.map +1 -0
  19. package/dist/src/ai/utils.d.ts +5 -0
  20. package/dist/src/ai/utils.d.ts.map +1 -1
  21. package/dist/src/ai/vercel-ai.d.ts.map +1 -1
  22. package/dist/src/client.d.ts +1 -3
  23. package/dist/src/client.d.ts.map +1 -1
  24. package/dist/src/config/types.d.ts +11 -0
  25. package/dist/src/config/types.d.ts.map +1 -1
  26. package/dist/src/index.d.ts +1 -0
  27. package/dist/src/index.d.ts.map +1 -1
  28. package/dist/src/integrations/bundle.d.ts +18 -0
  29. package/dist/src/integrations/bundle.d.ts.map +1 -0
  30. package/dist/src/react/hooks.d.ts +16 -0
  31. package/dist/src/react/hooks.d.ts.map +1 -1
  32. package/dist/src/server.d.ts +12 -0
  33. package/dist/src/server.d.ts.map +1 -1
  34. package/dist/src/utils/normalize-tool-name.d.ts +14 -0
  35. package/dist/src/utils/normalize-tool-name.d.ts.map +1 -0
  36. package/dist/src/utils/parse-tool-result.d.ts +23 -0
  37. package/dist/src/utils/parse-tool-result.d.ts.map +1 -0
  38. package/package.json +1 -1
  39. package/react.ts +10 -2
@@ -4436,7 +4436,7 @@ class MCPClientBase {
4436
4436
  logger7.debug(`Discovered ${totalDiscovered} tools, ${enabledCount} enabled by integrations`);
4437
4437
  }
4438
4438
  async _callToolByName(name, args, options) {
4439
- return await this.callToolWithRetry(name, args, 0, options);
4439
+ return await this.callTool(name, args, options);
4440
4440
  }
4441
4441
  async callTool(name, args, options) {
4442
4442
  return await this.callToolWithRetry(name, args, 0, options);
@@ -4436,7 +4436,7 @@ class MCPClientBase {
4436
4436
  logger7.debug(`Discovered ${totalDiscovered} tools, ${enabledCount} enabled by integrations`);
4437
4437
  }
4438
4438
  async _callToolByName(name, args, options) {
4439
- return await this.callToolWithRetry(name, args, 0, options);
4439
+ return await this.callTool(name, args, options);
4440
4440
  }
4441
4441
  async callTool(name, args, options) {
4442
4442
  return await this.callToolWithRetry(name, args, 0, options);
@@ -4436,7 +4436,7 @@ class MCPClientBase {
4436
4436
  logger7.debug(`Discovered ${totalDiscovered} tools, ${enabledCount} enabled by integrations`);
4437
4437
  }
4438
4438
  async _callToolByName(name, args, options) {
4439
- return await this.callToolWithRetry(name, args, 0, options);
4439
+ return await this.callTool(name, args, options);
4440
4440
  }
4441
4441
  async callTool(name, args, options) {
4442
4442
  return await this.callToolWithRetry(name, args, 0, options);
package/dist/ai/index.js CHANGED
@@ -5534,6 +5534,69 @@ function convertJsonSchemaToGoogleSchema(jsonSchema, TypeEnum) {
5534
5534
  return result;
5535
5535
  }
5536
5536
 
5537
+ // ../database/token-store.ts
5538
+ var USABLE_ACCESS_TOKEN_BUFFER_MS = 30 * 1000;
5539
+ var MIN_MEANINGFUL_EXPIRY_MS = Date.UTC(2000, 0, 1);
5540
+ async function listConnectedProviders(configuredIntegrationIds, getProviderToken, context) {
5541
+ if (!context.userId || configuredIntegrationIds.length === 0) {
5542
+ return [];
5543
+ }
5544
+ const connected = [];
5545
+ await Promise.all(configuredIntegrationIds.map(async (provider) => {
5546
+ try {
5547
+ const token = await getProviderToken(provider, undefined, context);
5548
+ if (token?.accessToken || typeof token?.refreshToken === "string" && token.refreshToken.length > 0) {
5549
+ connected.push(provider);
5550
+ }
5551
+ } catch {}
5552
+ }));
5553
+ return connected.sort();
5554
+ }
5555
+
5556
+ // tool-cache.ts
5557
+ function buildToolDiscoveryCacheKey(userId, connectedIntegrationIds) {
5558
+ const sorted = [...connectedIntegrationIds].sort().join(",");
5559
+ return `${userId}:${sorted}`;
5560
+ }
5561
+ async function resolveToolDiscoveryCacheKey(client, context, options) {
5562
+ const userId = context.userId;
5563
+ if (!userId)
5564
+ return;
5565
+ const configuredIds = (client.integrations ?? []).map((i) => i.id);
5566
+ let targetIds;
5567
+ if (options?.integrationIds?.length) {
5568
+ targetIds = options.integrationIds;
5569
+ } else if (options?.connectedOnly) {
5570
+ targetIds = await listConnectedProviders(configuredIds, (provider, email, ctx) => client.getProviderToken(provider, email, ctx), context);
5571
+ } else {
5572
+ targetIds = configuredIds;
5573
+ }
5574
+ return buildToolDiscoveryCacheKey(userId, targetIds);
5575
+ }
5576
+ function stubsFromTools(tools) {
5577
+ return tools.map((t) => ({
5578
+ name: t.name,
5579
+ description: t.description,
5580
+ inputSchema: t.inputSchema
5581
+ }));
5582
+ }
5583
+ function applyToolDiscoveryCache(client, stubs) {
5584
+ client.hydrateToolCache(stubs);
5585
+ }
5586
+ async function persistToolDiscoveryCache(client, cache, cacheKey, ttlMs) {
5587
+ const tools = client.getAvailableTools();
5588
+ if (tools.length === 0)
5589
+ return;
5590
+ await cache.set(cacheKey, stubsFromTools(tools), ttlMs);
5591
+ }
5592
+ async function warmToolDiscoveryFromCache(client, cache, cacheKey) {
5593
+ const stubs = await cache.get(cacheKey);
5594
+ if (!stubs || stubs.length === 0)
5595
+ return false;
5596
+ applyToolDiscoveryCache(client, stubs);
5597
+ return true;
5598
+ }
5599
+
5537
5600
  // vercel-ai.ts
5538
5601
  function convertMCPToolToVercelAI(mcpTool, client, options) {
5539
5602
  return {
@@ -5556,7 +5619,21 @@ async function getVercelAITools(client, options) {
5556
5619
  }
5557
5620
  const finalOptions = providerTokens ? { ...options, providerTokens } : options;
5558
5621
  await ensureClientConnected(client);
5622
+ const cacheConfig = options?.cache;
5623
+ let cacheKey;
5624
+ if (cacheConfig?.cache && options?.context) {
5625
+ cacheKey = await resolveToolDiscoveryCacheKey(client, options.context, {
5626
+ integrationIds: options.integrationIds,
5627
+ connectedOnly: options.connectedOnly
5628
+ });
5629
+ if (cacheKey) {
5630
+ await warmToolDiscoveryFromCache(client, cacheConfig.cache, cacheKey);
5631
+ }
5632
+ }
5559
5633
  const mcpTools = await client.getEnabledToolsAsync(toEnabledToolsAsyncOptions(options));
5634
+ if (cacheConfig?.cache && cacheKey) {
5635
+ await persistToolDiscoveryCache(client, cacheConfig.cache, cacheKey, cacheConfig.ttlMs);
5636
+ }
5560
5637
  const vercelTools = {};
5561
5638
  let effectiveMode;
5562
5639
  if (options?.mode !== undefined) {
@@ -0,0 +1,50 @@
1
+ import type { MCPClient } from "../client.js";
2
+ import type { MCPTool } from "../protocol/messages.js";
3
+ import type { MCPContext } from "../config/types.js";
4
+ /** Serializable MCP tool metadata for cross-request / Redis caching. */
5
+ export type ToolMetadataStub = Pick<MCPTool, "name" | "description" | "inputSchema">;
6
+ export interface ToolDiscoveryCacheAdapter {
7
+ get(key: string): Promise<ToolMetadataStub[] | null>;
8
+ set(key: string, stubs: ToolMetadataStub[], ttlMs?: number): Promise<void>;
9
+ /** Invalidate all keys for a user (prefix match) or a single key when exact. */
10
+ invalidate(userIdOrKey: string): Promise<void>;
11
+ }
12
+ export interface ToolDiscoveryCacheOptions {
13
+ cache: ToolDiscoveryCacheAdapter;
14
+ /** @default 5 minutes */
15
+ ttlMs?: number;
16
+ }
17
+ /**
18
+ * Build a cache key from user id and connected integration ids.
19
+ * Include connected providers so reconnecting OAuth invalidates stale tool lists.
20
+ */
21
+ export declare function buildToolDiscoveryCacheKey(userId: string, connectedIntegrationIds: readonly string[]): string;
22
+ /**
23
+ * In-memory tool discovery cache (single process). Use Redis in production serverless.
24
+ */
25
+ export declare function createMemoryToolDiscoveryCache(): ToolDiscoveryCacheAdapter;
26
+ /**
27
+ * Hook for database adapter `onTokenChange` — invalidates cached tool metadata for the user.
28
+ */
29
+ export declare function createToolDiscoveryCacheInvalidator(cache: ToolDiscoveryCacheAdapter): (event: {
30
+ userId: string;
31
+ }) => void;
32
+ export declare function resolveToolDiscoveryCacheKey(client: MCPClient<any>, context: MCPContext, options?: {
33
+ integrationIds?: string[];
34
+ connectedOnly?: boolean;
35
+ }): Promise<string | undefined>;
36
+ export declare function stubsFromTools(tools: readonly MCPTool[]): ToolMetadataStub[];
37
+ /**
38
+ * Hydrate the client tool cache from persisted stubs (serverless cold start).
39
+ */
40
+ export declare function applyToolDiscoveryCache(client: MCPClient<any>, stubs: readonly ToolMetadataStub[]): void;
41
+ /**
42
+ * Persist current client tool metadata to a cache adapter.
43
+ */
44
+ export declare function persistToolDiscoveryCache(client: MCPClient<any>, cache: ToolDiscoveryCacheAdapter, cacheKey: string, ttlMs?: number): Promise<void>;
45
+ /**
46
+ * Load stubs from cache into the client before tool discovery.
47
+ * @returns true when cache was hydrated
48
+ */
49
+ export declare function warmToolDiscoveryFromCache(client: MCPClient<any>, cache: ToolDiscoveryCacheAdapter, cacheKey: string): Promise<boolean>;
50
+ //# sourceMappingURL=tool-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-cache.d.ts","sourceRoot":"","sources":["../../../src/ai/tool-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,wEAAwE;AACxE,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,aAAa,CAAC,CAAC;AAErF,MAAM,WAAW,yBAAyB;IACxC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,CAAC;IACrD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,gFAAgF;IAChF,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,yBAAyB,CAAC;IACjC,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,EACd,uBAAuB,EAAE,SAAS,MAAM,EAAE,GACzC,MAAM,CAGR;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,yBAAyB,CAwB1E;AAED;;GAEG;AACH,wBAAgB,mCAAmC,CACjD,KAAK,EAAE,yBAAyB,GAC/B,CAAC,KAAK,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAIrC;AAED,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,OAAO,EAAE,UAAU,EACnB,OAAO,CAAC,EAAE;IACR,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GACA,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAuB7B;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,GAAG,gBAAgB,EAAE,CAM5E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,KAAK,EAAE,SAAS,gBAAgB,EAAE,GACjC,IAAI,CAEN;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,KAAK,EAAE,yBAAyB,EAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,KAAK,EAAE,yBAAyB,EAChC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAKlB"}
@@ -57,6 +57,11 @@ export interface AIToolsOptions {
57
57
  * @default 8
58
58
  */
59
59
  fetchConcurrency?: number;
60
+ /**
61
+ * Optional cache for tool metadata (serverless cold-start optimization).
62
+ * Pair with {@link createToolDiscoveryCacheInvalidator} on `onTokenChange`.
63
+ */
64
+ cache?: import("./tool-cache.js").ToolDiscoveryCacheOptions;
60
65
  }
61
66
  /** Map AI helper options to client tool-discovery options */
62
67
  export declare function toEnabledToolsAsyncOptions(options?: Pick<AIToolsOptions, "integrationIds" | "connectedOnly" | "context" | "fetchConcurrency">): EnabledToolsAsyncOptions | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/ai/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,6DAA6D;AAC7D,wBAAgB,0BAA0B,CACxC,OAAO,CAAC,EAAE,IAAI,CACZ,cAAc,EACd,gBAAgB,GAAG,eAAe,GAAG,SAAS,GAAG,kBAAkB,CACpE,GACA,wBAAwB,GAAG,SAAS,CAYtC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG/F;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAqFvE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAoD7D;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,GAAG,CAAC,CAuCd;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjF;AAED;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/ai/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,iBAAiB,EAAE,yBAAyB,CAAC;CAC7D;AAED,6DAA6D;AAC7D,wBAAgB,0BAA0B,CACxC,OAAO,CAAC,EAAE,IAAI,CACZ,cAAc,EACd,gBAAgB,GAAG,eAAe,GAAG,SAAS,GAAG,kBAAkB,CACpE,GACA,wBAAwB,GAAG,SAAS,CAYtC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG/F;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAqFvE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAoD7D;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,GAAG,CAAC,CAuCd;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjF;AAED;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"vercel-ai.d.ts","sourceRoot":"","sources":["../../../src/ai/vercel-ai.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAUpB;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5B,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,kDAAkD;IAClD,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACzB;AA+BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,OAAO,CAAC,EAAE,oBAAoB,gCAyE/B"}
1
+ {"version":3,"file":"vercel-ai.d.ts","sourceRoot":"","sources":["../../../src/ai/vercel-ai.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAepB;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5B,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,kDAAkD;IAClD,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACzB;AA+BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EACtB,OAAO,CAAC,EAAE,oBAAoB,gCA+F/B"}
@@ -5129,6 +5129,69 @@ ${generated.compact}`;
5129
5129
  return { codeTool, typesTool };
5130
5130
  }
5131
5131
 
5132
+ // ../database/token-store.ts
5133
+ var USABLE_ACCESS_TOKEN_BUFFER_MS = 30 * 1000;
5134
+ var MIN_MEANINGFUL_EXPIRY_MS = Date.UTC(2000, 0, 1);
5135
+ async function listConnectedProviders(configuredIntegrationIds, getProviderToken, context) {
5136
+ if (!context.userId || configuredIntegrationIds.length === 0) {
5137
+ return [];
5138
+ }
5139
+ const connected = [];
5140
+ await Promise.all(configuredIntegrationIds.map(async (provider) => {
5141
+ try {
5142
+ const token = await getProviderToken(provider, undefined, context);
5143
+ if (token?.accessToken || typeof token?.refreshToken === "string" && token.refreshToken.length > 0) {
5144
+ connected.push(provider);
5145
+ }
5146
+ } catch {}
5147
+ }));
5148
+ return connected.sort();
5149
+ }
5150
+
5151
+ // tool-cache.ts
5152
+ function buildToolDiscoveryCacheKey(userId, connectedIntegrationIds) {
5153
+ const sorted = [...connectedIntegrationIds].sort().join(",");
5154
+ return `${userId}:${sorted}`;
5155
+ }
5156
+ async function resolveToolDiscoveryCacheKey(client, context, options) {
5157
+ const userId = context.userId;
5158
+ if (!userId)
5159
+ return;
5160
+ const configuredIds = (client.integrations ?? []).map((i) => i.id);
5161
+ let targetIds;
5162
+ if (options?.integrationIds?.length) {
5163
+ targetIds = options.integrationIds;
5164
+ } else if (options?.connectedOnly) {
5165
+ targetIds = await listConnectedProviders(configuredIds, (provider, email, ctx) => client.getProviderToken(provider, email, ctx), context);
5166
+ } else {
5167
+ targetIds = configuredIds;
5168
+ }
5169
+ return buildToolDiscoveryCacheKey(userId, targetIds);
5170
+ }
5171
+ function stubsFromTools(tools) {
5172
+ return tools.map((t) => ({
5173
+ name: t.name,
5174
+ description: t.description,
5175
+ inputSchema: t.inputSchema
5176
+ }));
5177
+ }
5178
+ function applyToolDiscoveryCache(client, stubs) {
5179
+ client.hydrateToolCache(stubs);
5180
+ }
5181
+ async function persistToolDiscoveryCache(client, cache, cacheKey, ttlMs) {
5182
+ const tools = client.getAvailableTools();
5183
+ if (tools.length === 0)
5184
+ return;
5185
+ await cache.set(cacheKey, stubsFromTools(tools), ttlMs);
5186
+ }
5187
+ async function warmToolDiscoveryFromCache(client, cache, cacheKey) {
5188
+ const stubs = await cache.get(cacheKey);
5189
+ if (!stubs || stubs.length === 0)
5190
+ return false;
5191
+ applyToolDiscoveryCache(client, stubs);
5192
+ return true;
5193
+ }
5194
+
5132
5195
  // vercel-ai.ts
5133
5196
  function convertMCPToolToVercelAI(mcpTool, client, options) {
5134
5197
  return {
@@ -5151,7 +5214,21 @@ async function getVercelAITools(client, options) {
5151
5214
  }
5152
5215
  const finalOptions = providerTokens ? { ...options, providerTokens } : options;
5153
5216
  await ensureClientConnected(client);
5217
+ const cacheConfig = options?.cache;
5218
+ let cacheKey;
5219
+ if (cacheConfig?.cache && options?.context) {
5220
+ cacheKey = await resolveToolDiscoveryCacheKey(client, options.context, {
5221
+ integrationIds: options.integrationIds,
5222
+ connectedOnly: options.connectedOnly
5223
+ });
5224
+ if (cacheKey) {
5225
+ await warmToolDiscoveryFromCache(client, cacheConfig.cache, cacheKey);
5226
+ }
5227
+ }
5154
5228
  const mcpTools = await client.getEnabledToolsAsync(toEnabledToolsAsyncOptions(options));
5229
+ if (cacheConfig?.cache && cacheKey) {
5230
+ await persistToolDiscoveryCache(client, cacheConfig.cache, cacheKey, cacheConfig.ttlMs);
5231
+ }
5155
5232
  const vercelTools = {};
5156
5233
  let effectiveMode;
5157
5234
  if (options?.mode !== undefined) {
package/dist/index.js CHANGED
@@ -3664,7 +3664,7 @@ class MCPClientBase {
3664
3664
  logger5.debug(`Discovered ${totalDiscovered} tools, ${enabledCount} enabled by integrations`);
3665
3665
  }
3666
3666
  async _callToolByName(name, args, options) {
3667
- return await this.callToolWithRetry(name, args, 0, options);
3667
+ return await this.callTool(name, args, options);
3668
3668
  }
3669
3669
  async callTool(name, args, options) {
3670
3670
  return await this.callToolWithRetry(name, args, 0, options);
@@ -14160,6 +14160,68 @@ function createSimpleIntegration(config) {
14160
14160
  onDisconnect: config.onDisconnect
14161
14161
  };
14162
14162
  }
14163
+ // src/utils/parse-tool-result.ts
14164
+ function isRecord(value) {
14165
+ return typeof value === "object" && value !== null && !Array.isArray(value);
14166
+ }
14167
+ function getBooleanProperty(value, key) {
14168
+ const property = value[key];
14169
+ return typeof property === "boolean" ? property : undefined;
14170
+ }
14171
+ function getStringProperty(value, key) {
14172
+ const property = value[key];
14173
+ if (typeof property !== "string") {
14174
+ return;
14175
+ }
14176
+ const trimmed = property.trim();
14177
+ return trimmed.length > 0 ? trimmed : undefined;
14178
+ }
14179
+ function getStructuredContent(result) {
14180
+ const structuredContent = result.structuredContent;
14181
+ return isRecord(structuredContent) ? structuredContent : undefined;
14182
+ }
14183
+ function getContentText(result) {
14184
+ const content = result.content;
14185
+ if (!Array.isArray(content)) {
14186
+ return;
14187
+ }
14188
+ for (const item of content) {
14189
+ if (!isRecord(item)) {
14190
+ continue;
14191
+ }
14192
+ const text = getStringProperty(item, "text");
14193
+ if (text) {
14194
+ return text;
14195
+ }
14196
+ }
14197
+ return;
14198
+ }
14199
+ function isMCPToolError(result) {
14200
+ return parseMCPToolResult(result).ok === false;
14201
+ }
14202
+ function parseMCPToolResult(result) {
14203
+ if (!isRecord(result)) {
14204
+ return {
14205
+ ok: true,
14206
+ data: result,
14207
+ raw: result
14208
+ };
14209
+ }
14210
+ const structuredContent = getStructuredContent(result);
14211
+ const failed = getBooleanProperty(result, "isError") === true || getBooleanProperty(result, "success") === false || getBooleanProperty(structuredContent ?? {}, "isError") === true || getBooleanProperty(structuredContent ?? {}, "success") === false;
14212
+ if (!failed) {
14213
+ return {
14214
+ ok: true,
14215
+ data: structuredContent ?? result,
14216
+ raw: result
14217
+ };
14218
+ }
14219
+ return {
14220
+ ok: false,
14221
+ error: getStringProperty(result, "error") ?? getStringProperty(structuredContent ?? {}, "error") ?? getContentText(result) ?? "Tool returned an error result",
14222
+ raw: result
14223
+ };
14224
+ }
14163
14225
  // index.ts
14164
14226
  var client = createMCPClient({
14165
14227
  integrations: [
@@ -14372,6 +14434,7 @@ export {
14372
14434
  paypalIntegration,
14373
14435
  parseState,
14374
14436
  parseServerError,
14437
+ parseMCPToolResult,
14375
14438
  paperIntegration,
14376
14439
  pandadocIntegration,
14377
14440
  outlookIntegration,
@@ -14406,6 +14469,7 @@ export {
14406
14469
  kickIntegration,
14407
14470
  jiraIntegration,
14408
14471
  isTokenExpiredError,
14472
+ isMCPToolError,
14409
14473
  isAuthorizationError,
14410
14474
  isAuthError,
14411
14475
  intercomIntegration,
@@ -3664,7 +3664,7 @@ class MCPClientBase {
3664
3664
  logger5.debug(`Discovered ${totalDiscovered} tools, ${enabledCount} enabled by integrations`);
3665
3665
  }
3666
3666
  async _callToolByName(name, args, options) {
3667
- return await this.callToolWithRetry(name, args, 0, options);
3667
+ return await this.callTool(name, args, options);
3668
3668
  }
3669
3669
  async callTool(name, args, options) {
3670
3670
  return await this.callToolWithRetry(name, args, 0, options);
@@ -14160,6 +14160,68 @@ function createSimpleIntegration(config) {
14160
14160
  onDisconnect: config.onDisconnect
14161
14161
  };
14162
14162
  }
14163
+ // src/utils/parse-tool-result.ts
14164
+ function isRecord(value) {
14165
+ return typeof value === "object" && value !== null && !Array.isArray(value);
14166
+ }
14167
+ function getBooleanProperty(value, key) {
14168
+ const property = value[key];
14169
+ return typeof property === "boolean" ? property : undefined;
14170
+ }
14171
+ function getStringProperty(value, key) {
14172
+ const property = value[key];
14173
+ if (typeof property !== "string") {
14174
+ return;
14175
+ }
14176
+ const trimmed = property.trim();
14177
+ return trimmed.length > 0 ? trimmed : undefined;
14178
+ }
14179
+ function getStructuredContent(result) {
14180
+ const structuredContent = result.structuredContent;
14181
+ return isRecord(structuredContent) ? structuredContent : undefined;
14182
+ }
14183
+ function getContentText(result) {
14184
+ const content = result.content;
14185
+ if (!Array.isArray(content)) {
14186
+ return;
14187
+ }
14188
+ for (const item of content) {
14189
+ if (!isRecord(item)) {
14190
+ continue;
14191
+ }
14192
+ const text = getStringProperty(item, "text");
14193
+ if (text) {
14194
+ return text;
14195
+ }
14196
+ }
14197
+ return;
14198
+ }
14199
+ function isMCPToolError(result) {
14200
+ return parseMCPToolResult(result).ok === false;
14201
+ }
14202
+ function parseMCPToolResult(result) {
14203
+ if (!isRecord(result)) {
14204
+ return {
14205
+ ok: true,
14206
+ data: result,
14207
+ raw: result
14208
+ };
14209
+ }
14210
+ const structuredContent = getStructuredContent(result);
14211
+ const failed = getBooleanProperty(result, "isError") === true || getBooleanProperty(result, "success") === false || getBooleanProperty(structuredContent ?? {}, "isError") === true || getBooleanProperty(structuredContent ?? {}, "success") === false;
14212
+ if (!failed) {
14213
+ return {
14214
+ ok: true,
14215
+ data: structuredContent ?? result,
14216
+ raw: result
14217
+ };
14218
+ }
14219
+ return {
14220
+ ok: false,
14221
+ error: getStringProperty(result, "error") ?? getStringProperty(structuredContent ?? {}, "error") ?? getContentText(result) ?? "Tool returned an error result",
14222
+ raw: result
14223
+ };
14224
+ }
14163
14225
  export {
14164
14226
  zoomIntegration,
14165
14227
  zohoWriterIntegration,
@@ -14258,6 +14320,7 @@ export {
14258
14320
  paypalIntegration,
14259
14321
  parseState,
14260
14322
  parseServerError,
14323
+ parseMCPToolResult,
14261
14324
  paperIntegration,
14262
14325
  pandadocIntegration,
14263
14326
  outlookIntegration,
@@ -14292,6 +14355,7 @@ export {
14292
14355
  kickIntegration,
14293
14356
  jiraIntegration,
14294
14357
  isTokenExpiredError,
14358
+ isMCPToolError,
14295
14359
  isAuthorizationError,
14296
14360
  isAuthError,
14297
14361
  intercomIntegration,
package/dist/react.d.ts CHANGED
@@ -3,6 +3,6 @@
3
3
  *
4
4
  * @packageDocumentation
5
5
  */
6
- export { useIntegrateTokens, useIntegrateAI } from "./src/react/hooks.js";
7
- export type { UseIntegrateTokensResult, UseIntegrateAIOptions } from "./src/react/hooks.js";
6
+ export { useIntegrateTokens, useIntegrateAI, useIntegrateAuth, } from "./src/react/hooks.js";
7
+ export type { UseIntegrateTokensResult, UseIntegrateAIOptions, UseIntegrateAuthResult, } from "./src/react/hooks.js";
8
8
  //# sourceMappingURL=react.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../react.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC1E,YAAY,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../react.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC"}
package/dist/react.js CHANGED
@@ -202,7 +202,93 @@ function useIntegrateAI(client, options = {}) {
202
202
  };
203
203
  }, [client, apiPattern, debug]);
204
204
  }
205
+ function useIntegrateAuth(client, provider, options) {
206
+ const [isAuthorized, setIsAuthorized] = useState(false);
207
+ const [isLoading, setIsLoading] = useState(true);
208
+ const [error, setError] = useState(null);
209
+ const refresh = async () => {
210
+ if (!client) {
211
+ setIsAuthorized(false);
212
+ setIsLoading(false);
213
+ return;
214
+ }
215
+ try {
216
+ const authorized = await client.isAuthorized(provider, options?.email);
217
+ setIsAuthorized(authorized);
218
+ setError(null);
219
+ } catch (err) {
220
+ setError(err instanceof Error ? err.message : String(err));
221
+ } finally {
222
+ setIsLoading(false);
223
+ }
224
+ };
225
+ useEffect(() => {
226
+ if (!client || !isReactHooksAvailable()) {
227
+ setIsLoading(false);
228
+ return;
229
+ }
230
+ refresh();
231
+ const onChange = () => {
232
+ refresh();
233
+ };
234
+ const onError = (event) => {
235
+ const payload = event;
236
+ if (payload.provider === provider) {
237
+ setError(payload.error ?? "Authorization failed");
238
+ }
239
+ };
240
+ client.on("auth:complete", onChange);
241
+ client.on("auth:disconnect", onChange);
242
+ client.on("auth:logout", onChange);
243
+ client.on("auth:error", onError);
244
+ return () => {
245
+ client.off("auth:complete", onChange);
246
+ client.off("auth:disconnect", onChange);
247
+ client.off("auth:logout", onChange);
248
+ client.off("auth:error", onError);
249
+ };
250
+ }, [client, provider, options?.email]);
251
+ const authorize = async () => {
252
+ if (!client)
253
+ return;
254
+ setError(null);
255
+ setIsLoading(true);
256
+ try {
257
+ await client.authorize(provider, options?.returnUrl ? { returnUrl: options.returnUrl } : undefined);
258
+ await refresh();
259
+ } catch (err) {
260
+ setError(err instanceof Error ? err.message : String(err));
261
+ setIsLoading(false);
262
+ }
263
+ };
264
+ const disconnect = async (email) => {
265
+ if (!client)
266
+ return;
267
+ setError(null);
268
+ setIsLoading(true);
269
+ try {
270
+ if (email) {
271
+ await client.disconnectAccount(provider, email);
272
+ } else {
273
+ await client.disconnectProvider(provider);
274
+ }
275
+ await refresh();
276
+ } catch (err) {
277
+ setError(err instanceof Error ? err.message : String(err));
278
+ setIsLoading(false);
279
+ }
280
+ };
281
+ return {
282
+ isAuthorized,
283
+ isLoading,
284
+ error,
285
+ authorize,
286
+ disconnect,
287
+ refresh
288
+ };
289
+ }
205
290
  export {
206
291
  useIntegrateTokens,
292
+ useIntegrateAuth,
207
293
  useIntegrateAI
208
294
  };