@topolo/mcp 0.11.8 → 0.11.10

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 (2) hide show
  1. package/dist/index.js +65 -46
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1601,7 +1601,7 @@ var TopoloClient = class _TopoloClient {
1601
1601
  }
1602
1602
  const mapped = mapActionInput(entry, input);
1603
1603
  const service = entry.appSlug || entry.appId;
1604
- return this.request({
1604
+ const result = await this.request({
1605
1605
  service,
1606
1606
  ...entry.apiBaseUrl ? { baseUrl: entry.apiBaseUrl } : {},
1607
1607
  method: entry.method,
@@ -1615,6 +1615,7 @@ var TopoloClient = class _TopoloClient {
1615
1615
  },
1616
1616
  confirm: options.confirm === true || entry.readOnly && !entry.destructive && !entry.requiresConfirmation
1617
1617
  });
1618
+ return redactActionResult(result);
1618
1619
  }
1619
1620
  /**
1620
1621
  * Introspect the current credential. Returns the caller's resolved identity,
@@ -1738,6 +1739,18 @@ function readOptionalString(value) {
1738
1739
  function isRecord3(value) {
1739
1740
  return typeof value === "object" && value !== null && !Array.isArray(value);
1740
1741
  }
1742
+ function redactActionResult(value) {
1743
+ if (Array.isArray(value)) return value.map(redactActionResult);
1744
+ if (!isRecord3(value)) return value;
1745
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [
1746
+ key,
1747
+ isSensitiveActionResultKey(key) ? "[REDACTED]" : redactActionResult(item)
1748
+ ]));
1749
+ }
1750
+ function isSensitiveActionResultKey(key) {
1751
+ const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
1752
+ return ["authorization", "cookie", "setcookie", "proxyauthorization", "capability"].includes(normalized) || /(token|secret|password|privatekey|apikey)$/.test(normalized);
1753
+ }
1741
1754
  function resolveConfiguredServiceUrl(slug, serviceUrls) {
1742
1755
  for (const serviceKey of serviceKeyCandidates2(slug)) {
1743
1756
  const configured = serviceUrls?.[serviceKey];
@@ -2805,52 +2818,58 @@ async function refreshCredentialIfNeeded(environment = selectedEnvironment(), op
2805
2818
  if (process.env[`${prefix}_API_KEY`] || process.env[`${prefix}_ACCESS_TOKEN`] || environment === "production" && process.env.TOPOLO_API_KEY || environment === "production" && process.env.TOPOLO_ACCESS_TOKEN) {
2806
2819
  return resolveCredential(environment);
2807
2820
  }
2808
- const config = await readConfig();
2809
- const profile = profileForEnvironment(config, environment);
2810
- const cred = profile.credential;
2811
- if (!cred || cred.kind !== "access_token") return cred ?? null;
2812
- if (!cred.refreshToken || !profile.oauthClientId) return cred;
2813
- const now = Math.floor(Date.now() / 1e3);
2814
- if (!options.force && cred.expiresAt && cred.expiresAt - REFRESH_SKEW_SECONDS > now) return cred;
2815
- const serviceUrls = resolveServiceUrls(profile.serviceUrls, environment);
2816
- if (environment === "local" && !serviceUrls?.auth) {
2817
- throw new TopoloSdkError2(
2818
- "environment_service_url_required",
2819
- "Local Topolo credential refresh requires an explicit local Auth service origin."
2820
- );
2821
- }
2822
- try {
2823
- const oauth = new TopoloOAuth({
2824
- serviceUrls
2825
- });
2826
- const tokens = await oauth.refreshToken({
2827
- clientId: profile.oauthClientId,
2828
- refreshToken: cred.refreshToken
2829
- });
2830
- const refreshed = {
2831
- kind: "access_token",
2832
- accessToken: tokens.access_token,
2833
- ...tokens.refresh_token ? { refreshToken: tokens.refresh_token } : { refreshToken: cred.refreshToken },
2834
- expiresAt: Math.floor(Date.now() / 1e3) + tokens.expires_in
2835
- };
2836
- const activeContext = profile.activeContext;
2837
- const activeEntry = activeContext ? profile.contexts?.[activeContext] : void 0;
2838
- const updated = activeContext && activeEntry ? writeProfileConfig(config, environment, {
2839
- credential: refreshed,
2840
- contexts: {
2841
- ...profile.contexts ?? {},
2842
- [activeContext]: {
2843
- ...activeEntry,
2844
- credential: refreshed,
2845
- oauthClientId: activeEntry.oauthClientId ?? profile.oauthClientId
2821
+ const observed = profileForEnvironment(await readConfig(), environment).credential;
2822
+ return withConfigWriteLock(async () => {
2823
+ const config = await readConfig();
2824
+ const profile = profileForEnvironment(config, environment);
2825
+ const cred = profile.credential;
2826
+ if (!cred || cred.kind !== "access_token") return cred ?? null;
2827
+ if (!cred.refreshToken || !profile.oauthClientId) return cred;
2828
+ if (options.force && observed?.kind === "access_token" && observed.accessToken !== cred.accessToken) {
2829
+ return cred;
2830
+ }
2831
+ const now = Math.floor(Date.now() / 1e3);
2832
+ if (!options.force && cred.expiresAt && cred.expiresAt - REFRESH_SKEW_SECONDS > now) return cred;
2833
+ const serviceUrls = resolveServiceUrls(profile.serviceUrls, environment);
2834
+ if (environment === "local" && !serviceUrls?.auth) {
2835
+ throw new TopoloSdkError2(
2836
+ "environment_service_url_required",
2837
+ "Local Topolo credential refresh requires an explicit local Auth service origin."
2838
+ );
2839
+ }
2840
+ try {
2841
+ const oauth = new TopoloOAuth({
2842
+ serviceUrls
2843
+ });
2844
+ const tokens = await oauth.refreshToken({
2845
+ clientId: profile.oauthClientId,
2846
+ refreshToken: cred.refreshToken
2847
+ });
2848
+ const refreshed = {
2849
+ kind: "access_token",
2850
+ accessToken: tokens.access_token,
2851
+ ...tokens.refresh_token ? { refreshToken: tokens.refresh_token } : { refreshToken: cred.refreshToken },
2852
+ expiresAt: Math.floor(Date.now() / 1e3) + tokens.expires_in
2853
+ };
2854
+ const activeContext = profile.activeContext;
2855
+ const activeEntry = activeContext ? profile.contexts?.[activeContext] : void 0;
2856
+ const updated = activeContext && activeEntry ? writeProfileConfig(config, environment, {
2857
+ credential: refreshed,
2858
+ contexts: {
2859
+ ...profile.contexts ?? {},
2860
+ [activeContext]: {
2861
+ ...activeEntry,
2862
+ credential: refreshed,
2863
+ oauthClientId: activeEntry.oauthClientId ?? profile.oauthClientId
2864
+ }
2846
2865
  }
2847
- }
2848
- }) : environment === "production" && !config.profiles?.production ? { ...config, credential: refreshed } : writeProfileConfig(config, environment, { credential: refreshed });
2849
- await writeConfig(updated);
2850
- return refreshed;
2851
- } catch {
2852
- return cred;
2853
- }
2866
+ }) : environment === "production" && !config.profiles?.production ? { ...config, credential: refreshed } : writeProfileConfig(config, environment, { credential: refreshed });
2867
+ await writeConfig(updated);
2868
+ return refreshed;
2869
+ } catch {
2870
+ return cred;
2871
+ }
2872
+ });
2854
2873
  }
2855
2874
  async function refreshContextCredentialIfNeeded(environment, key, options = {}) {
2856
2875
  return withConfigWriteLock(async () => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@topolo/mcp",
3
- "version": "0.11.8",
4
- "topoloPublishedVersion": "0.11.8",
3
+ "version": "0.11.10",
4
+ "topoloPublishedVersion": "0.11.10",
5
5
  "description": "Model Context Protocol server for the Topolo platform. Exposes scope-gated tools that third-party agents (Claude, Codex, etc.) can call natively.",
6
6
  "license": "UNLICENSED",
7
7
  "author": "Topolo",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@modelcontextprotocol/sdk": "^1.0.0",
38
- "@topolo/sdk": "0.11.8"
38
+ "@topolo/sdk": "0.11.10"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/node": "^20.12.0",