integrate-sdk 0.9.42-dev.0 → 0.9.44-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1671,99 +1671,402 @@ class IndexedDBStorage {
1671
1671
 
1672
1672
  // src/oauth/email-fetcher.ts
1673
1673
  var logger3 = createLogger("EmailFetcher");
1674
+ var EMAIL_FETCHERS = {
1675
+ github: fetchGitHubEmail,
1676
+ gmail: fetchGoogleEmail,
1677
+ google: fetchGoogleEmail,
1678
+ gcal: fetchGoogleEmail,
1679
+ gdrive: fetchGoogleEmail,
1680
+ gdocs: fetchGoogleEmail,
1681
+ gsheets: fetchGoogleEmail,
1682
+ gslides: fetchGoogleEmail,
1683
+ gcontacts: fetchGoogleEmail,
1684
+ gmeet: fetchGoogleEmail,
1685
+ gchat: fetchGoogleEmail,
1686
+ gtasks: fetchGoogleEmail,
1687
+ ga4: fetchGoogleEmail,
1688
+ youtube: fetchGoogleEmail,
1689
+ notion: fetchNotionEmail,
1690
+ linear: fetchLinearEmail,
1691
+ hubspot: fetchHubSpotEmail,
1692
+ polar: fetchPolarEmail,
1693
+ todoist: fetchTodoistEmail,
1694
+ vercel: fetchVercelEmail,
1695
+ slack: fetchSlackEmail,
1696
+ intercom: fetchIntercomEmail,
1697
+ jira: fetchAtlassianEmail,
1698
+ zendesk: fetchZendeskEmail,
1699
+ airtable: fetchAirtableEmail,
1700
+ discord: fetchDiscordEmail,
1701
+ dropbox: fetchDropboxEmail,
1702
+ gitlab: fetchGitLabEmail,
1703
+ reddit: fetchRedditEmail,
1704
+ outlook: fetchMicrosoftEmail,
1705
+ teams: fetchMicrosoftEmail,
1706
+ onedrive: fetchMicrosoftEmail,
1707
+ sharepoint: fetchMicrosoftEmail,
1708
+ excel: fetchMicrosoftEmail,
1709
+ word: fetchMicrosoftEmail,
1710
+ powerpoint: fetchMicrosoftEmail,
1711
+ planner: fetchMicrosoftEmail
1712
+ };
1674
1713
  async function fetchUserEmail(provider, tokenData) {
1714
+ const fetcher = EMAIL_FETCHERS[provider.toLowerCase()];
1715
+ if (!fetcher) {
1716
+ return tokenData.email;
1717
+ }
1675
1718
  try {
1676
- switch (provider.toLowerCase()) {
1677
- case "github":
1678
- return await fetchGitHubEmail(tokenData.accessToken);
1679
- case "gmail":
1680
- case "google":
1681
- return await fetchGoogleEmail(tokenData.accessToken);
1682
- case "notion":
1683
- return await fetchNotionEmail(tokenData.accessToken);
1684
- default:
1685
- return tokenData.email;
1686
- }
1719
+ const email = await fetcher(tokenData);
1720
+ return email ?? tokenData.email;
1687
1721
  } catch (error) {
1688
1722
  logger3.error(`Failed to fetch email for ${provider}:`, error);
1689
- return;
1723
+ return tokenData.email;
1690
1724
  }
1691
1725
  }
1692
- async function fetchGitHubEmail(accessToken) {
1693
- try {
1694
- const userResponse = await fetch("https://api.github.com/user", {
1695
- headers: {
1696
- Authorization: `Bearer ${accessToken}`,
1697
- Accept: "application/vnd.github.v3+json"
1698
- }
1699
- });
1700
- if (!userResponse.ok) {
1701
- return;
1702
- }
1703
- const user = await userResponse.json();
1704
- if (user.email) {
1705
- return user.email;
1706
- }
1707
- const emailsResponse = await fetch("https://api.github.com/user/emails", {
1708
- headers: {
1709
- Authorization: `Bearer ${accessToken}`,
1710
- Accept: "application/vnd.github.v3+json"
1711
- }
1712
- });
1713
- if (!emailsResponse.ok) {
1714
- return;
1726
+ async function fetchGitHubEmail(token) {
1727
+ const headers = {
1728
+ Authorization: `Bearer ${token.accessToken}`,
1729
+ Accept: "application/vnd.github.v3+json"
1730
+ };
1731
+ const userResponse = await fetch("https://api.github.com/user", { headers });
1732
+ if (!userResponse.ok)
1733
+ return;
1734
+ const user = await userResponse.json();
1735
+ if (user.email)
1736
+ return user.email;
1737
+ const emailsResponse = await fetch("https://api.github.com/user/emails", { headers });
1738
+ if (!emailsResponse.ok)
1739
+ return;
1740
+ const emails = await emailsResponse.json();
1741
+ const primary = emails.find((e) => e.primary && e.verified);
1742
+ if (primary)
1743
+ return primary.email;
1744
+ const verified = emails.find((e) => e.verified);
1745
+ if (verified)
1746
+ return verified.email;
1747
+ return emails[0]?.email;
1748
+ }
1749
+ async function fetchGoogleEmail(token) {
1750
+ const response = await fetch("https://www.googleapis.com/oauth2/v2/userinfo", {
1751
+ headers: { Authorization: `Bearer ${token.accessToken}` }
1752
+ });
1753
+ if (!response.ok)
1754
+ return;
1755
+ const user = await response.json();
1756
+ return user.email;
1757
+ }
1758
+ async function fetchNotionEmail(token) {
1759
+ const response = await fetch("https://api.notion.com/v1/users/me", {
1760
+ headers: {
1761
+ Authorization: `Bearer ${token.accessToken}`,
1762
+ "Notion-Version": "2022-06-28"
1715
1763
  }
1716
- const emails = await emailsResponse.json();
1717
- const primaryEmail = emails.find((e) => e.primary && e.verified);
1718
- if (primaryEmail) {
1719
- return primaryEmail.email;
1764
+ });
1765
+ if (!response.ok)
1766
+ return;
1767
+ const user = await response.json();
1768
+ return user.person?.email ?? user.bot?.owner?.user?.person?.email;
1769
+ }
1770
+ async function fetchLinearEmail(token) {
1771
+ const response = await fetch("https://api.linear.app/graphql", {
1772
+ method: "POST",
1773
+ headers: {
1774
+ Authorization: `Bearer ${token.accessToken}`,
1775
+ "Content-Type": "application/json"
1776
+ },
1777
+ body: JSON.stringify({ query: "{ viewer { email } }" })
1778
+ });
1779
+ if (!response.ok)
1780
+ return;
1781
+ const body = await response.json();
1782
+ return body.data?.viewer?.email;
1783
+ }
1784
+ async function fetchHubSpotEmail(token) {
1785
+ const url = `https://api.hubapi.com/oauth/v1/access-tokens/${encodeURIComponent(token.accessToken)}`;
1786
+ const response = await fetch(url);
1787
+ if (!response.ok)
1788
+ return;
1789
+ const body = await response.json();
1790
+ return body.user;
1791
+ }
1792
+ async function fetchPolarEmail(token) {
1793
+ const response = await fetch("https://api.polar.sh/v1/oauth2/userinfo", {
1794
+ headers: { Authorization: `Bearer ${token.accessToken}` }
1795
+ });
1796
+ if (!response.ok)
1797
+ return;
1798
+ const body = await response.json();
1799
+ return body.email;
1800
+ }
1801
+ async function fetchTodoistEmail(token) {
1802
+ const response = await fetch("https://api.todoist.com/sync/v9/sync", {
1803
+ method: "POST",
1804
+ headers: {
1805
+ Authorization: `Bearer ${token.accessToken}`,
1806
+ "Content-Type": "application/x-www-form-urlencoded"
1807
+ },
1808
+ body: 'sync_token=*&resource_types=["user"]'
1809
+ });
1810
+ if (!response.ok)
1811
+ return;
1812
+ const body = await response.json();
1813
+ return body.user?.email;
1814
+ }
1815
+ async function fetchVercelEmail(token) {
1816
+ const response = await fetch("https://api.vercel.com/v2/user", {
1817
+ headers: { Authorization: `Bearer ${token.accessToken}` }
1818
+ });
1819
+ if (!response.ok)
1820
+ return;
1821
+ const body = await response.json();
1822
+ return body.user?.email ?? body.email;
1823
+ }
1824
+ async function fetchSlackEmail(token) {
1825
+ const response = await fetch("https://slack.com/api/users.identity", {
1826
+ headers: { Authorization: `Bearer ${token.accessToken}` }
1827
+ });
1828
+ if (!response.ok)
1829
+ return;
1830
+ const body = await response.json();
1831
+ if (!body.ok)
1832
+ return;
1833
+ return body.user?.email;
1834
+ }
1835
+ async function fetchIntercomEmail(token) {
1836
+ const response = await fetch("https://api.intercom.io/me", {
1837
+ headers: {
1838
+ Authorization: `Bearer ${token.accessToken}`,
1839
+ Accept: "application/json"
1720
1840
  }
1721
- const verifiedEmail = emails.find((e) => e.verified);
1722
- if (verifiedEmail) {
1723
- return verifiedEmail.email;
1841
+ });
1842
+ if (!response.ok)
1843
+ return;
1844
+ const body = await response.json();
1845
+ return body.email;
1846
+ }
1847
+ async function fetchAtlassianEmail(token) {
1848
+ const response = await fetch("https://api.atlassian.com/me", {
1849
+ headers: {
1850
+ Authorization: `Bearer ${token.accessToken}`,
1851
+ Accept: "application/json"
1724
1852
  }
1725
- if (emails.length > 0 && emails[0]?.email) {
1726
- return emails[0].email;
1853
+ });
1854
+ if (!response.ok)
1855
+ return;
1856
+ const body = await response.json();
1857
+ return body.email;
1858
+ }
1859
+ async function fetchZendeskEmail(token) {
1860
+ const subdomain = token.providerConfig?.subdomain?.trim();
1861
+ if (!subdomain)
1862
+ return;
1863
+ const response = await fetch(`https://${subdomain}.zendesk.com/api/v2/users/me.json`, {
1864
+ headers: { Authorization: `Bearer ${token.accessToken}` }
1865
+ });
1866
+ if (!response.ok)
1867
+ return;
1868
+ const body = await response.json();
1869
+ return body.user?.email;
1870
+ }
1871
+ async function fetchAirtableEmail(token) {
1872
+ const response = await fetch("https://api.airtable.com/v0/meta/whoami", {
1873
+ headers: { Authorization: `Bearer ${token.accessToken}` }
1874
+ });
1875
+ if (!response.ok)
1876
+ return;
1877
+ const body = await response.json();
1878
+ return body.email;
1879
+ }
1880
+ async function fetchDiscordEmail(token) {
1881
+ const response = await fetch("https://discord.com/api/users/@me", {
1882
+ headers: { Authorization: `Bearer ${token.accessToken}` }
1883
+ });
1884
+ if (!response.ok)
1885
+ return;
1886
+ const body = await response.json();
1887
+ return body.email;
1888
+ }
1889
+ async function fetchDropboxEmail(token) {
1890
+ const response = await fetch("https://api.dropboxapi.com/2/users/get_current_account", {
1891
+ method: "POST",
1892
+ headers: {
1893
+ Authorization: `Bearer ${token.accessToken}`
1894
+ },
1895
+ body: "null"
1896
+ });
1897
+ if (!response.ok)
1898
+ return;
1899
+ const body = await response.json();
1900
+ return body.email;
1901
+ }
1902
+ async function fetchGitLabEmail(token) {
1903
+ const response = await fetch("https://gitlab.com/api/v4/user", {
1904
+ headers: { Authorization: `Bearer ${token.accessToken}` }
1905
+ });
1906
+ if (!response.ok)
1907
+ return;
1908
+ const body = await response.json();
1909
+ return body.email;
1910
+ }
1911
+ async function fetchRedditEmail(token) {
1912
+ const response = await fetch("https://oauth.reddit.com/api/v1/me", {
1913
+ headers: {
1914
+ Authorization: `Bearer ${token.accessToken}`,
1915
+ "User-Agent": "integrate-sdk"
1727
1916
  }
1917
+ });
1918
+ if (!response.ok)
1728
1919
  return;
1729
- } catch (error) {
1730
- logger3.error("Failed to fetch GitHub email:", error);
1920
+ const body = await response.json();
1921
+ return body.name;
1922
+ }
1923
+ async function fetchMicrosoftEmail(token) {
1924
+ const response = await fetch("https://graph.microsoft.com/v1.0/me", {
1925
+ headers: { Authorization: `Bearer ${token.accessToken}` }
1926
+ });
1927
+ if (!response.ok)
1731
1928
  return;
1929
+ const body = await response.json();
1930
+ return body.mail ?? body.userPrincipalName;
1931
+ }
1932
+
1933
+ // src/oauth/refresh.ts
1934
+ class RefreshRejectedError extends Error {
1935
+ provider;
1936
+ constructor(provider, message) {
1937
+ super(message ?? `OAuth refresh rejected (invalid_grant) for ${provider}`);
1938
+ this.name = "RefreshRejectedError";
1939
+ this.provider = provider;
1732
1940
  }
1733
1941
  }
1734
- async function fetchGoogleEmail(accessToken) {
1735
- try {
1736
- const response = await fetch("https://www.googleapis.com/oauth2/v2/userinfo", {
1737
- headers: {
1738
- Authorization: `Bearer ${accessToken}`
1942
+
1943
+ class RefreshTransientError extends Error {
1944
+ provider;
1945
+ constructor(provider, message) {
1946
+ super(message);
1947
+ this.name = "RefreshTransientError";
1948
+ this.provider = provider;
1949
+ }
1950
+ }
1951
+ var DEFAULT_REFRESH_WINDOW_MS = 2 * 60 * 1000;
1952
+ function shouldRefreshToken(tokenData, windowMs = DEFAULT_REFRESH_WINDOW_MS) {
1953
+ if (!tokenData || !tokenData.refreshToken || !tokenData.expiresAt) {
1954
+ return false;
1955
+ }
1956
+ const expiresAtMs = Date.parse(tokenData.expiresAt);
1957
+ if (Number.isNaN(expiresAtMs)) {
1958
+ return false;
1959
+ }
1960
+ return expiresAtMs - Date.now() <= windowMs;
1961
+ }
1962
+ async function refreshViaMcp(opts) {
1963
+ const url = new URL("/oauth/refresh", opts.serverUrl);
1964
+ const body = {
1965
+ provider: opts.provider,
1966
+ refresh_token: opts.refreshToken,
1967
+ client_id: opts.clientId
1968
+ };
1969
+ if (opts.clientSecret) {
1970
+ body.client_secret = opts.clientSecret;
1971
+ }
1972
+ if (opts.subdomain) {
1973
+ body.subdomain = opts.subdomain;
1974
+ }
1975
+ if (opts.extraConfig) {
1976
+ for (const [key, value] of Object.entries(opts.extraConfig)) {
1977
+ if (body[key] === undefined) {
1978
+ body[key] = value;
1739
1979
  }
1980
+ }
1981
+ }
1982
+ const headers = { "Content-Type": "application/json" };
1983
+ if (opts.apiKey) {
1984
+ headers["X-API-KEY"] = opts.apiKey;
1985
+ }
1986
+ let response;
1987
+ try {
1988
+ response = await fetch(url.toString(), {
1989
+ method: "POST",
1990
+ headers,
1991
+ body: JSON.stringify(body),
1992
+ signal: opts.signal
1740
1993
  });
1741
- if (!response.ok) {
1742
- return;
1994
+ } catch (err) {
1995
+ throw new RefreshTransientError(opts.provider, `Network error refreshing ${opts.provider} token: ${err.message}`);
1996
+ }
1997
+ if (response.status === 401) {
1998
+ let parsed = {};
1999
+ try {
2000
+ parsed = await response.json();
2001
+ } catch {}
2002
+ if (parsed.error === "invalid_grant") {
2003
+ throw new RefreshRejectedError(opts.provider);
1743
2004
  }
1744
- const user = await response.json();
1745
- return user.email;
1746
- } catch (error) {
1747
- logger3.error("Failed to fetch Google email:", error);
1748
- return;
2005
+ throw new RefreshTransientError(opts.provider, `Refresh endpoint returned 401`);
1749
2006
  }
2007
+ if (!response.ok) {
2008
+ let text = "";
2009
+ try {
2010
+ text = await response.text();
2011
+ } catch {}
2012
+ throw new RefreshTransientError(opts.provider, `Refresh endpoint returned ${response.status}: ${text || "<no body>"}`);
2013
+ }
2014
+ let result;
2015
+ try {
2016
+ result = await response.json();
2017
+ } catch (err) {
2018
+ throw new RefreshTransientError(opts.provider, `Malformed refresh response: ${err.message}`);
2019
+ }
2020
+ if (!result.accessToken) {
2021
+ throw new RefreshTransientError(opts.provider, `Refresh response missing access_token`);
2022
+ }
2023
+ if (!result.refreshToken) {
2024
+ result.refreshToken = opts.refreshToken;
2025
+ }
2026
+ return result;
1750
2027
  }
1751
- async function fetchNotionEmail(accessToken) {
2028
+ async function resolveAccessToken(opts) {
2029
+ const { provider, currentTokens, force = false } = opts;
2030
+ const needsRefresh = force || shouldRefreshToken(currentTokens, opts.windowMs);
2031
+ if (!needsRefresh || !currentTokens.refreshToken) {
2032
+ return currentTokens.accessToken;
2033
+ }
1752
2034
  try {
1753
- const response = await fetch("https://api.notion.com/v1/users/me", {
1754
- headers: {
1755
- Authorization: `Bearer ${accessToken}`,
1756
- "Notion-Version": "2022-06-28"
1757
- }
2035
+ const refreshed = await refreshViaMcp({
2036
+ provider,
2037
+ refreshToken: currentTokens.refreshToken,
2038
+ clientId: opts.providerOAuth.clientId,
2039
+ clientSecret: opts.providerOAuth.clientSecret,
2040
+ subdomain: opts.providerOAuth.subdomain,
2041
+ extraConfig: opts.providerOAuth.extraConfig,
2042
+ serverUrl: opts.serverUrl,
2043
+ apiKey: opts.apiKey
1758
2044
  });
1759
- if (!response.ok) {
1760
- return;
2045
+ const updated = {
2046
+ ...currentTokens,
2047
+ accessToken: refreshed.accessToken,
2048
+ refreshToken: refreshed.refreshToken ?? currentTokens.refreshToken,
2049
+ tokenType: refreshed.tokenType || currentTokens.tokenType,
2050
+ expiresIn: refreshed.expiresIn ?? currentTokens.expiresIn,
2051
+ expiresAt: refreshed.expiresAt ?? currentTokens.expiresAt,
2052
+ scopes: refreshed.scopes && refreshed.scopes.length > 0 ? refreshed.scopes : currentTokens.scopes
2053
+ };
2054
+ if (opts.setProviderToken) {
2055
+ try {
2056
+ await opts.setProviderToken(provider, updated, updated.email, opts.context);
2057
+ } catch {}
1761
2058
  }
1762
- const user = await response.json();
1763
- return user.person?.email;
1764
- } catch (error) {
1765
- logger3.error("Failed to fetch Notion email:", error);
1766
- return;
2059
+ return updated.accessToken;
2060
+ } catch (err) {
2061
+ if (err instanceof RefreshRejectedError) {
2062
+ if (opts.setProviderToken) {
2063
+ try {
2064
+ await opts.setProviderToken(provider, null, currentTokens.email, opts.context);
2065
+ } catch {}
2066
+ }
2067
+ throw err;
2068
+ }
2069
+ return currentTokens.accessToken;
1767
2070
  }
1768
2071
  }
1769
2072
 
@@ -1782,7 +2085,10 @@ class OAuthManager {
1782
2085
  removeTokenCallback;
1783
2086
  indexedDBStorage;
1784
2087
  skipLocalStorage = false;
1785
- constructor(oauthApiBase, flowConfig, apiBaseUrl, tokenCallbacks) {
2088
+ providerOAuth = {};
2089
+ mcpServerUrl;
2090
+ mcpApiKey;
2091
+ constructor(oauthApiBase, flowConfig, apiBaseUrl, tokenCallbacks, refreshConfig) {
1786
2092
  this.oauthApiBase = oauthApiBase;
1787
2093
  this.apiBaseUrl = apiBaseUrl;
1788
2094
  this.windowManager = new OAuthWindowManager;
@@ -1794,6 +2100,9 @@ class OAuthManager {
1794
2100
  this.getTokenCallback = tokenCallbacks?.getProviderToken;
1795
2101
  this.setTokenCallback = tokenCallbacks?.setProviderToken;
1796
2102
  this.removeTokenCallback = tokenCallbacks?.removeProviderToken;
2103
+ this.providerOAuth = refreshConfig?.providers ?? {};
2104
+ this.mcpServerUrl = refreshConfig?.mcpServerUrl;
2105
+ this.mcpApiKey = refreshConfig?.apiKey;
1797
2106
  this.indexedDBStorage = new IndexedDBStorage;
1798
2107
  this.cleanupExpiredPendingAuths();
1799
2108
  }
@@ -2003,7 +2312,9 @@ class OAuthManager {
2003
2312
  try {
2004
2313
  const tokenData = await this.getTokenCallback(provider, email, context);
2005
2314
  if (tokenData) {
2006
- this.providerTokens.set(provider, tokenData);
2315
+ const refreshed = await this.maybeRefreshTokenData(provider, tokenData, context);
2316
+ this.providerTokens.set(provider, refreshed);
2317
+ return refreshed;
2007
2318
  }
2008
2319
  return tokenData;
2009
2320
  } catch (error) {
@@ -2043,6 +2354,59 @@ class OAuthManager {
2043
2354
  }
2044
2355
  await this.saveProviderToken(provider, tokenData, tokenEmail, context);
2045
2356
  }
2357
+ configureTokenRefresh(refreshConfig) {
2358
+ if (refreshConfig.providers) {
2359
+ this.providerOAuth = refreshConfig.providers;
2360
+ }
2361
+ if (refreshConfig.mcpServerUrl !== undefined) {
2362
+ this.mcpServerUrl = refreshConfig.mcpServerUrl;
2363
+ }
2364
+ if (refreshConfig.apiKey !== undefined) {
2365
+ this.mcpApiKey = refreshConfig.apiKey;
2366
+ }
2367
+ }
2368
+ async maybeRefreshTokenData(provider, tokenData, context) {
2369
+ const credentials = this.providerOAuth[provider];
2370
+ const serverUrl = this.mcpServerUrl;
2371
+ if (!credentials || !serverUrl) {
2372
+ return tokenData;
2373
+ }
2374
+ if (!shouldRefreshToken(tokenData)) {
2375
+ return tokenData;
2376
+ }
2377
+ try {
2378
+ const newAccessToken = await resolveAccessToken({
2379
+ provider,
2380
+ currentTokens: tokenData,
2381
+ providerOAuth: {
2382
+ clientId: credentials.clientId,
2383
+ clientSecret: credentials.clientSecret,
2384
+ subdomain: credentials.config?.subdomain
2385
+ },
2386
+ serverUrl,
2387
+ apiKey: this.mcpApiKey,
2388
+ setProviderToken: this.setTokenCallback,
2389
+ context
2390
+ });
2391
+ if (newAccessToken === tokenData.accessToken) {
2392
+ return tokenData;
2393
+ }
2394
+ if (this.getTokenCallback) {
2395
+ try {
2396
+ const reloaded = await this.getTokenCallback(provider, tokenData.email, context);
2397
+ if (reloaded) {
2398
+ return reloaded;
2399
+ }
2400
+ } catch {}
2401
+ }
2402
+ return { ...tokenData, accessToken: newAccessToken };
2403
+ } catch (err) {
2404
+ if (err instanceof RefreshRejectedError) {
2405
+ throw err;
2406
+ }
2407
+ return tokenData;
2408
+ }
2409
+ }
2046
2410
  clearProviderToken(provider) {
2047
2411
  this.providerTokens.delete(provider);
2048
2412
  if (!this.setTokenCallback && !this.removeTokenCallback && !this.skipLocalStorage) {
@@ -2501,10 +2865,26 @@ class MCPClientBase {
2501
2865
  };
2502
2866
  this.onReauthRequired = config.onReauthRequired;
2503
2867
  this.maxReauthRetries = config.maxReauthRetries ?? 1;
2868
+ const refreshProviders = {};
2869
+ for (const integration of this.integrations) {
2870
+ const oauth = integration?.oauth;
2871
+ if (oauth?.clientId && oauth?.provider) {
2872
+ refreshProviders[oauth.provider] = {
2873
+ clientId: oauth.clientId,
2874
+ clientSecret: oauth.clientSecret,
2875
+ config: oauth.config
2876
+ };
2877
+ }
2878
+ }
2879
+ const mcpServerUrl = config.serverUrl;
2504
2880
  this.oauthManager = new OAuthManager(oauthApiBase, config.oauthFlow, this.apiBaseUrl, {
2505
2881
  getProviderToken: config.getProviderToken,
2506
2882
  setProviderToken: config.setProviderToken,
2507
2883
  removeProviderToken: config.removeProviderToken
2884
+ }, {
2885
+ providers: refreshProviders,
2886
+ mcpServerUrl,
2887
+ apiKey: config.apiKey
2508
2888
  });
2509
2889
  this.setSessionToken(config.sessionToken || this.loadSessionTokenFromStorage());
2510
2890
  for (const integration of this.integrations) {
@@ -9041,12 +9421,15 @@ export {
9041
9421
  supabaseIntegration,
9042
9422
  stripeIntegration,
9043
9423
  slackIntegration,
9424
+ shouldRefreshToken,
9044
9425
  shopifyIntegration,
9045
9426
  sharepointIntegration,
9046
9427
  sentryIntegration,
9047
9428
  sendCallbackToOpener,
9048
9429
  salesforceIntegration,
9430
+ resolveAccessToken,
9049
9431
  resendIntegration,
9432
+ refreshViaMcp,
9050
9433
  redisIntegration,
9051
9434
  redditIntegration,
9052
9435
  rampIntegration,
@@ -9135,6 +9518,8 @@ export {
9135
9518
  TriggerClient,
9136
9519
  ToolCallError,
9137
9520
  TokenExpiredError,
9521
+ RefreshTransientError,
9522
+ RefreshRejectedError,
9138
9523
  OAuthWindowManager,
9139
9524
  OAuthManager,
9140
9525
  OAuthHandler,
@@ -9144,6 +9529,7 @@ export {
9144
9529
  IntegrateSDKError,
9145
9530
  INTEGRATION_CATEGORY_ORDER,
9146
9531
  HttpSessionTransport,
9532
+ DEFAULT_REFRESH_WINDOW_MS,
9147
9533
  ConnectionError,
9148
9534
  AuthorizationError,
9149
9535
  AuthenticationError