integrate-sdk 0.9.58 → 0.9.62

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 (43) 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 +77 -1
  12. package/dist/integrations.js +77 -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 +353 -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/integrations/granola.d.ts.map +1 -1
  31. package/dist/src/integrations/mercury.d.ts.map +1 -1
  32. package/dist/src/integrations/resend.d.ts.map +1 -1
  33. package/dist/src/integrations/tldraw.d.ts.map +1 -1
  34. package/dist/src/react/hooks.d.ts +16 -0
  35. package/dist/src/react/hooks.d.ts.map +1 -1
  36. package/dist/src/server.d.ts +12 -0
  37. package/dist/src/server.d.ts.map +1 -1
  38. package/dist/src/utils/normalize-tool-name.d.ts +14 -0
  39. package/dist/src/utils/normalize-tool-name.d.ts.map +1 -0
  40. package/dist/src/utils/parse-tool-result.d.ts +23 -0
  41. package/dist/src/utils/parse-tool-result.d.ts.map +1 -0
  42. package/package.json +1 -1
  43. 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);
@@ -12209,6 +12209,9 @@ function tldrawIntegration(options = {}) {
12209
12209
  return {
12210
12210
  id: "tldraw",
12211
12211
  name: "tldraw",
12212
+ logoUrl: "https://wdvtnli2jn3texa6.public.blob.vercel-storage.com/tldraw.png",
12213
+ description: "Create and manage tldraw collaborative whiteboards",
12214
+ category: "Productivity",
12212
12215
  tools: [...TLDRAW_TOOLS],
12213
12216
  authType: apiKey ? "apiKey" : undefined,
12214
12217
  getHeaders: apiKey ? () => ({ Authorization: `Bearer ${apiKey}` }) : undefined
@@ -12275,6 +12278,9 @@ function granolaIntegration(options) {
12275
12278
  return {
12276
12279
  id: "granola",
12277
12280
  name: "Granola",
12281
+ logoUrl: "https://wdvtnli2jn3texa6.public.blob.vercel-storage.com/granola.png",
12282
+ description: "List and read Granola meeting notes and folders",
12283
+ category: "Productivity",
12278
12284
  tools: [...GRANOLA_TOOLS],
12279
12285
  authType: "apiKey",
12280
12286
  getHeaders() {
@@ -12357,6 +12363,9 @@ function mercuryIntegration(options) {
12357
12363
  return {
12358
12364
  id: "mercury",
12359
12365
  name: "Mercury",
12366
+ logoUrl: "https://wdvtnli2jn3texa6.public.blob.vercel-storage.com/mercury.png",
12367
+ description: "Manage Mercury bank accounts, cards, and transactions",
12368
+ category: "Finance",
12360
12369
  tools: [...MERCURY_TOOLS],
12361
12370
  authType: "apiKey",
12362
12371
  getHeaders() {
@@ -13225,6 +13234,9 @@ function resendIntegration(options = {}) {
13225
13234
  return {
13226
13235
  id: "resend",
13227
13236
  name: "Resend",
13237
+ logoUrl: "https://wdvtnli2jn3texa6.public.blob.vercel-storage.com/resend.png",
13238
+ description: "Send email and manage domains with the Resend API",
13239
+ category: "Communication",
13228
13240
  tools: [...RESEND_TOOLS],
13229
13241
  authType: "apiKey",
13230
13242
  getHeaders() {
@@ -14160,6 +14172,68 @@ function createSimpleIntegration(config) {
14160
14172
  onDisconnect: config.onDisconnect
14161
14173
  };
14162
14174
  }
14175
+ // src/utils/parse-tool-result.ts
14176
+ function isRecord(value) {
14177
+ return typeof value === "object" && value !== null && !Array.isArray(value);
14178
+ }
14179
+ function getBooleanProperty(value, key) {
14180
+ const property = value[key];
14181
+ return typeof property === "boolean" ? property : undefined;
14182
+ }
14183
+ function getStringProperty(value, key) {
14184
+ const property = value[key];
14185
+ if (typeof property !== "string") {
14186
+ return;
14187
+ }
14188
+ const trimmed = property.trim();
14189
+ return trimmed.length > 0 ? trimmed : undefined;
14190
+ }
14191
+ function getStructuredContent(result) {
14192
+ const structuredContent = result.structuredContent;
14193
+ return isRecord(structuredContent) ? structuredContent : undefined;
14194
+ }
14195
+ function getContentText(result) {
14196
+ const content = result.content;
14197
+ if (!Array.isArray(content)) {
14198
+ return;
14199
+ }
14200
+ for (const item of content) {
14201
+ if (!isRecord(item)) {
14202
+ continue;
14203
+ }
14204
+ const text = getStringProperty(item, "text");
14205
+ if (text) {
14206
+ return text;
14207
+ }
14208
+ }
14209
+ return;
14210
+ }
14211
+ function isMCPToolError(result) {
14212
+ return parseMCPToolResult(result).ok === false;
14213
+ }
14214
+ function parseMCPToolResult(result) {
14215
+ if (!isRecord(result)) {
14216
+ return {
14217
+ ok: true,
14218
+ data: result,
14219
+ raw: result
14220
+ };
14221
+ }
14222
+ const structuredContent = getStructuredContent(result);
14223
+ const failed = getBooleanProperty(result, "isError") === true || getBooleanProperty(result, "success") === false || getBooleanProperty(structuredContent ?? {}, "isError") === true || getBooleanProperty(structuredContent ?? {}, "success") === false;
14224
+ if (!failed) {
14225
+ return {
14226
+ ok: true,
14227
+ data: structuredContent ?? result,
14228
+ raw: result
14229
+ };
14230
+ }
14231
+ return {
14232
+ ok: false,
14233
+ error: getStringProperty(result, "error") ?? getStringProperty(structuredContent ?? {}, "error") ?? getContentText(result) ?? "Tool returned an error result",
14234
+ raw: result
14235
+ };
14236
+ }
14163
14237
  // index.ts
14164
14238
  var client = createMCPClient({
14165
14239
  integrations: [
@@ -14372,6 +14446,7 @@ export {
14372
14446
  paypalIntegration,
14373
14447
  parseState,
14374
14448
  parseServerError,
14449
+ parseMCPToolResult,
14375
14450
  paperIntegration,
14376
14451
  pandadocIntegration,
14377
14452
  outlookIntegration,
@@ -14406,6 +14481,7 @@ export {
14406
14481
  kickIntegration,
14407
14482
  jiraIntegration,
14408
14483
  isTokenExpiredError,
14484
+ isMCPToolError,
14409
14485
  isAuthorizationError,
14410
14486
  isAuthError,
14411
14487
  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);
@@ -12209,6 +12209,9 @@ function tldrawIntegration(options = {}) {
12209
12209
  return {
12210
12210
  id: "tldraw",
12211
12211
  name: "tldraw",
12212
+ logoUrl: "https://wdvtnli2jn3texa6.public.blob.vercel-storage.com/tldraw.png",
12213
+ description: "Create and manage tldraw collaborative whiteboards",
12214
+ category: "Productivity",
12212
12215
  tools: [...TLDRAW_TOOLS],
12213
12216
  authType: apiKey ? "apiKey" : undefined,
12214
12217
  getHeaders: apiKey ? () => ({ Authorization: `Bearer ${apiKey}` }) : undefined
@@ -12275,6 +12278,9 @@ function granolaIntegration(options) {
12275
12278
  return {
12276
12279
  id: "granola",
12277
12280
  name: "Granola",
12281
+ logoUrl: "https://wdvtnli2jn3texa6.public.blob.vercel-storage.com/granola.png",
12282
+ description: "List and read Granola meeting notes and folders",
12283
+ category: "Productivity",
12278
12284
  tools: [...GRANOLA_TOOLS],
12279
12285
  authType: "apiKey",
12280
12286
  getHeaders() {
@@ -12357,6 +12363,9 @@ function mercuryIntegration(options) {
12357
12363
  return {
12358
12364
  id: "mercury",
12359
12365
  name: "Mercury",
12366
+ logoUrl: "https://wdvtnli2jn3texa6.public.blob.vercel-storage.com/mercury.png",
12367
+ description: "Manage Mercury bank accounts, cards, and transactions",
12368
+ category: "Finance",
12360
12369
  tools: [...MERCURY_TOOLS],
12361
12370
  authType: "apiKey",
12362
12371
  getHeaders() {
@@ -13225,6 +13234,9 @@ function resendIntegration(options = {}) {
13225
13234
  return {
13226
13235
  id: "resend",
13227
13236
  name: "Resend",
13237
+ logoUrl: "https://wdvtnli2jn3texa6.public.blob.vercel-storage.com/resend.png",
13238
+ description: "Send email and manage domains with the Resend API",
13239
+ category: "Communication",
13228
13240
  tools: [...RESEND_TOOLS],
13229
13241
  authType: "apiKey",
13230
13242
  getHeaders() {
@@ -14160,6 +14172,68 @@ function createSimpleIntegration(config) {
14160
14172
  onDisconnect: config.onDisconnect
14161
14173
  };
14162
14174
  }
14175
+ // src/utils/parse-tool-result.ts
14176
+ function isRecord(value) {
14177
+ return typeof value === "object" && value !== null && !Array.isArray(value);
14178
+ }
14179
+ function getBooleanProperty(value, key) {
14180
+ const property = value[key];
14181
+ return typeof property === "boolean" ? property : undefined;
14182
+ }
14183
+ function getStringProperty(value, key) {
14184
+ const property = value[key];
14185
+ if (typeof property !== "string") {
14186
+ return;
14187
+ }
14188
+ const trimmed = property.trim();
14189
+ return trimmed.length > 0 ? trimmed : undefined;
14190
+ }
14191
+ function getStructuredContent(result) {
14192
+ const structuredContent = result.structuredContent;
14193
+ return isRecord(structuredContent) ? structuredContent : undefined;
14194
+ }
14195
+ function getContentText(result) {
14196
+ const content = result.content;
14197
+ if (!Array.isArray(content)) {
14198
+ return;
14199
+ }
14200
+ for (const item of content) {
14201
+ if (!isRecord(item)) {
14202
+ continue;
14203
+ }
14204
+ const text = getStringProperty(item, "text");
14205
+ if (text) {
14206
+ return text;
14207
+ }
14208
+ }
14209
+ return;
14210
+ }
14211
+ function isMCPToolError(result) {
14212
+ return parseMCPToolResult(result).ok === false;
14213
+ }
14214
+ function parseMCPToolResult(result) {
14215
+ if (!isRecord(result)) {
14216
+ return {
14217
+ ok: true,
14218
+ data: result,
14219
+ raw: result
14220
+ };
14221
+ }
14222
+ const structuredContent = getStructuredContent(result);
14223
+ const failed = getBooleanProperty(result, "isError") === true || getBooleanProperty(result, "success") === false || getBooleanProperty(structuredContent ?? {}, "isError") === true || getBooleanProperty(structuredContent ?? {}, "success") === false;
14224
+ if (!failed) {
14225
+ return {
14226
+ ok: true,
14227
+ data: structuredContent ?? result,
14228
+ raw: result
14229
+ };
14230
+ }
14231
+ return {
14232
+ ok: false,
14233
+ error: getStringProperty(result, "error") ?? getStringProperty(structuredContent ?? {}, "error") ?? getContentText(result) ?? "Tool returned an error result",
14234
+ raw: result
14235
+ };
14236
+ }
14163
14237
  export {
14164
14238
  zoomIntegration,
14165
14239
  zohoWriterIntegration,
@@ -14258,6 +14332,7 @@ export {
14258
14332
  paypalIntegration,
14259
14333
  parseState,
14260
14334
  parseServerError,
14335
+ parseMCPToolResult,
14261
14336
  paperIntegration,
14262
14337
  pandadocIntegration,
14263
14338
  outlookIntegration,
@@ -14292,6 +14367,7 @@ export {
14292
14367
  kickIntegration,
14293
14368
  jiraIntegration,
14294
14369
  isTokenExpiredError,
14370
+ isMCPToolError,
14295
14371
  isAuthorizationError,
14296
14372
  isAuthError,
14297
14373
  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
  };