@ai-ecoverse/mcpcat 0.14.5 → 0.14.7

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.
@@ -52,7 +52,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
52
52
  // src/config/lock.ts
53
53
  var lock_exports = {};
54
54
  __export(lock_exports, {
55
- acquireLock: () => acquireLock
55
+ acquireLock: () => acquireLock,
56
+ releaseAllLocks: () => releaseAllLocks,
57
+ releaseAllLocksSync: () => releaseAllLocksSync
56
58
  });
57
59
  function isEexist(err) {
58
60
  if (err instanceof Error && "code" in err)
@@ -88,6 +90,35 @@ async function removeStaleLockFile(fs, lockPath) {
88
90
  }
89
91
  return false;
90
92
  }
93
+ function releaseAllLocksSync() {
94
+ for (const lock of heldLocks) {
95
+ try {
96
+ if (lock.useFile && lock.fs.unlink) {
97
+ void lock.fs.unlink(lock.path).catch(() => {
98
+ });
99
+ } else {
100
+ void lock.fs.rmdir(lock.path).catch(() => {
101
+ });
102
+ }
103
+ } catch {
104
+ }
105
+ }
106
+ heldLocks.clear();
107
+ }
108
+ async function releaseAllLocks() {
109
+ const locks = [...heldLocks];
110
+ heldLocks.clear();
111
+ for (const lock of locks) {
112
+ try {
113
+ if (lock.useFile && lock.fs.unlink) {
114
+ await lock.fs.unlink(lock.path);
115
+ } else {
116
+ await lock.fs.rmdir(lock.path);
117
+ }
118
+ } catch {
119
+ }
120
+ }
121
+ }
91
122
  async function acquireLock(fs, configPath) {
92
123
  const useFile = typeof fs.createExclusive === "function";
93
124
  const lockPath = `${configPath}.lock`;
@@ -120,10 +151,13 @@ async function acquireLock(fs, configPath) {
120
151
  }
121
152
  await new Promise((r) => setTimeout(r, LOCK_POLL_MS));
122
153
  }
154
+ const entry = { path: lockPath, useFile, fs };
155
+ heldLocks.add(entry);
123
156
  let released = false;
124
157
  return async () => {
125
158
  if (released) return;
126
159
  released = true;
160
+ heldLocks.delete(entry);
127
161
  try {
128
162
  if (useFile && fs.unlink) {
129
163
  await fs.unlink(lockPath);
@@ -134,13 +168,14 @@ async function acquireLock(fs, configPath) {
134
168
  }
135
169
  };
136
170
  }
137
- var LOCK_STALE_MS, LOCK_POLL_MS, LOCK_MAX_WAIT_MS;
171
+ var LOCK_STALE_MS, LOCK_POLL_MS, LOCK_MAX_WAIT_MS, heldLocks;
138
172
  var init_lock = __esm({
139
173
  "src/config/lock.ts"() {
140
174
  "use strict";
141
175
  LOCK_STALE_MS = 1e4;
142
176
  LOCK_POLL_MS = 50;
143
177
  LOCK_MAX_WAIT_MS = 5e3;
178
+ heldLocks = /* @__PURE__ */ new Set();
144
179
  }
145
180
  });
146
181
 
@@ -6758,7 +6793,13 @@ var CLIENT_NAME = "mcpcat";
6758
6793
  var CALLBACK_HOST = "127.0.0.1";
6759
6794
  var CALLBACK_PATH = "/callback";
6760
6795
  var REQUEST_TIMEOUT_MS = 15e3;
6761
- var REFRESH_SKEW_MS = 3e4;
6796
+ var MAX_REFRESH_SKEW_MS = 3e4;
6797
+ function computeSkew(state) {
6798
+ const expiresIn = state?.tokens?.expires_in;
6799
+ if (typeof expiresIn !== "number" || expiresIn <= 0) return MAX_REFRESH_SKEW_MS;
6800
+ const ttlMs = expiresIn * 1e3;
6801
+ return Math.min(MAX_REFRESH_SKEW_MS, Math.floor(ttlMs / 2));
6802
+ }
6762
6803
  var FALLBACK_REDIRECT_URL = `http://${CALLBACK_HOST}${CALLBACK_PATH}`;
6763
6804
  function timedFetch(fetchImpl) {
6764
6805
  return (input, init) => {
@@ -6825,7 +6866,9 @@ function createMcpAuthProvider(options) {
6825
6866
  function createJerkAuthProvider(options) {
6826
6867
  const { name, serverUrl, source } = options;
6827
6868
  let currentToken;
6828
- const _fetched = false;
6869
+ function registerCredential(token) {
6870
+ if (token && options.onCredentialObtained) options.onCredentialObtained(token);
6871
+ }
6829
6872
  return {
6830
6873
  async token() {
6831
6874
  return currentToken;
@@ -6837,6 +6880,7 @@ function createJerkAuthProvider(options) {
6837
6880
  const result2 = await source.getToken(name, serverUrl, challenge.scope);
6838
6881
  if (result2) {
6839
6882
  currentToken = result2.accessToken;
6883
+ registerCredential(currentToken);
6840
6884
  return;
6841
6885
  }
6842
6886
  } catch (err) {
@@ -6850,6 +6894,7 @@ function createJerkAuthProvider(options) {
6850
6894
  const result = await source.getToken(name, serverUrl);
6851
6895
  if (result) {
6852
6896
  currentToken = result.accessToken;
6897
+ registerCredential(currentToken);
6853
6898
  return;
6854
6899
  }
6855
6900
  throw new McpOAuthAuthorizationRequiredError();
@@ -6860,6 +6905,9 @@ function createPiAuthProvider(options) {
6860
6905
  const { name, serverUrl, source, oauth, platform: platform2 } = options;
6861
6906
  const store = new SourceBackedStore(source, name, serverUrl, platform2);
6862
6907
  let refreshing;
6908
+ function registerCredential(token) {
6909
+ if (token && options.onCredentialObtained) options.onCredentialObtained(token);
6910
+ }
6863
6911
  const refresh = async (staleToken) => {
6864
6912
  refreshing ??= store.withRefreshLock(async () => {
6865
6913
  const state = await store.load();
@@ -6889,15 +6937,28 @@ function createPiAuthProvider(options) {
6889
6937
  });
6890
6938
  return refreshing;
6891
6939
  };
6940
+ let cachedToken;
6941
+ let tokenLoaded = false;
6892
6942
  return {
6893
6943
  async token() {
6894
6944
  await refreshing?.catch(() => void 0);
6945
+ if (tokenLoaded) return cachedToken;
6895
6946
  const state = await store.load();
6896
- const token = state?.tokens?.access_token;
6897
- const expired = state?.tokensExpireAt !== void 0 && state.tokensExpireAt - REFRESH_SKEW_MS <= Date.now();
6898
- if (!expired || !state?.tokens?.refresh_token) return token;
6899
- await refresh(token).catch(() => void 0);
6900
- return (await store.load())?.tokens?.access_token;
6947
+ cachedToken = state?.tokens?.access_token;
6948
+ registerCredential(cachedToken);
6949
+ if (state?.tokens?.refresh_token) registerCredential(state.tokens.refresh_token);
6950
+ const skew = computeSkew(state);
6951
+ const expired = state?.tokensExpireAt !== void 0 && state.tokensExpireAt - skew <= Date.now();
6952
+ if (expired && state?.tokens?.refresh_token) {
6953
+ await refresh(cachedToken).catch(() => void 0);
6954
+ const refreshedState = await store.load();
6955
+ cachedToken = refreshedState?.tokens?.access_token;
6956
+ registerCredential(cachedToken);
6957
+ if (refreshedState?.tokens?.refresh_token)
6958
+ registerCredential(refreshedState.tokens.refresh_token);
6959
+ }
6960
+ tokenLoaded = true;
6961
+ return cachedToken;
6901
6962
  },
6902
6963
  async onUnauthorized(context) {
6903
6964
  const challenge = parseWwwAuthenticate(context.response.headers.get("www-authenticate"));
@@ -6905,6 +6966,11 @@ function createPiAuthProvider(options) {
6905
6966
  throw new AuthStepUpError(challenge.scope, options.name);
6906
6967
  }
6907
6968
  await refresh(context.token);
6969
+ const state = await store.load();
6970
+ cachedToken = state?.tokens?.access_token;
6971
+ tokenLoaded = true;
6972
+ registerCredential(cachedToken);
6973
+ if (state?.tokens?.refresh_token) registerCredential(state.tokens.refresh_token);
6908
6974
  }
6909
6975
  };
6910
6976
  }
@@ -9972,6 +10038,9 @@ var MergedConfigSource = class _MergedConfigSource {
9972
10038
  }
9973
10039
  };
9974
10040
 
10041
+ // src/cli/main.ts
10042
+ init_lock();
10043
+
9975
10044
  // src/config/edit.ts
9976
10045
  init_lock();
9977
10046
  function isRecord2(value) {
@@ -15343,6 +15412,8 @@ async function dispatchMultiTarget(platform2, parsed, version) {
15343
15412
  await Promise.race([killAllStdio(), new Promise((r) => setTimeout(r, 3e3))]);
15344
15413
  } catch {
15345
15414
  }
15415
+ await releaseAllLocks().catch(() => {
15416
+ });
15346
15417
  platform2.exit(exitCode);
15347
15418
  }
15348
15419
  platform2.onSignal?.("SIGTERM", () => void killTreeAndExit(143));
@@ -15575,25 +15646,28 @@ function classifyError(err) {
15575
15646
  }
15576
15647
  return { code: EXIT_RPC_ERROR, kind: "rpc_error", msg };
15577
15648
  }
15578
- async function resolveAuthProvider(platform2, hasAuthHeader, url, target, config) {
15649
+ async function resolveAuthProvider(platform2, hasAuthHeader, url, target, config, onCredentialObtained) {
15579
15650
  if (hasAuthHeader || !url) return void 0;
15580
- const piSource = new PiFileTokenSource(platform2);
15651
+ const source = await createTokenSource(platform2);
15581
15652
  const entry = config.entry(target);
15582
15653
  const oauth = entry && "url" in entry.config ? entry.config.oauth : void 0;
15583
15654
  const name = entry ? target : `url:${new URL(url).origin}${new URL(url).pathname}`;
15584
15655
  const provider = createMcpAuthProvider({
15585
15656
  name,
15586
15657
  serverUrl: url,
15587
- source: piSource,
15658
+ source,
15588
15659
  oauth,
15589
- platform: platform2
15660
+ platform: platform2,
15661
+ onCredentialObtained
15590
15662
  });
15591
15663
  const credentialSecrets = [];
15592
- const state = await piSource.loadWithoutLock(name, url);
15593
- if (state?.tokens?.access_token) credentialSecrets.push(state.tokens.access_token);
15594
- if (state?.tokens?.refresh_token) credentialSecrets.push(state.tokens.refresh_token);
15595
- if (state?.clientInformation && "client_secret" in state.clientInformation && state.clientInformation.client_secret) {
15596
- credentialSecrets.push(state.clientInformation.client_secret);
15664
+ if (source instanceof PiFileTokenSource) {
15665
+ const state = await source.loadWithoutLock(name, url);
15666
+ if (state?.tokens?.access_token) credentialSecrets.push(state.tokens.access_token);
15667
+ if (state?.tokens?.refresh_token) credentialSecrets.push(state.tokens.refresh_token);
15668
+ if (state?.clientInformation && "client_secret" in state.clientInformation && state.clientInformation.client_secret) {
15669
+ credentialSecrets.push(state.clientInformation.client_secret);
15670
+ }
15597
15671
  }
15598
15672
  return { provider, credentialSecrets };
15599
15673
  }
@@ -15641,7 +15715,7 @@ async function handleInputRequired(platform2, conn, err, respondData, json) {
15641
15715
  `);
15642
15716
  return EXIT_INPUT_REQUIRED;
15643
15717
  }
15644
- const isTty = platform2.isatty(0) && platform2.isatty(2);
15718
+ const isTty = platform2.kind === "host" && platform2.isatty(0) && platform2.isatty(2);
15645
15719
  const elicitResult = await handleElicitation(platform2, inputReq, isTty, respondData);
15646
15720
  if ("exitCode" in elicitResult) {
15647
15721
  await platform2.write(2, `${err.requestJson}
@@ -15691,6 +15765,8 @@ async function runClientVerb(platform2, version, parsed) {
15691
15765
  await Promise.race([killAllStdio(), new Promise((r) => setTimeout(r, 3e3))]);
15692
15766
  } catch {
15693
15767
  }
15768
+ await releaseAllLocks().catch(() => {
15769
+ });
15694
15770
  platform2.exit(exitCode);
15695
15771
  }
15696
15772
  platform2.onSignal?.("SIGINT", () => {
@@ -15743,7 +15819,11 @@ async function runClientVerb(platform2, version, parsed) {
15743
15819
  hasAuthHeader,
15744
15820
  resolved.url,
15745
15821
  target,
15746
- config
15822
+ config,
15823
+ (secret) => {
15824
+ allSecrets.add(secret);
15825
+ verbose.secrets.add(secret);
15826
+ }
15747
15827
  );
15748
15828
  const authProvider = authResolved?.provider;
15749
15829
  if (authResolved?.credentialSecrets) {
@@ -15823,6 +15903,8 @@ async function closeAndKillStdio(conn) {
15823
15903
  await killAllStdio();
15824
15904
  } catch {
15825
15905
  }
15906
+ await releaseAllLocks().catch(() => {
15907
+ });
15826
15908
  }
15827
15909
  async function writeErr(p, json, kind, msg) {
15828
15910
  if (json) await renderErrorJson(p, kind, msg);
@@ -16095,5 +16177,5 @@ try {
16095
16177
  });
16096
16178
  } catch {
16097
16179
  }
16098
- var code = await run(platform, "0.14.5", args);
16180
+ var code = await run(platform, "0.14.7", args);
16099
16181
  process.exit(code);
@@ -170,7 +170,9 @@ var init_node_stub = __esm({
170
170
  // src/config/lock.ts
171
171
  var lock_exports = {};
172
172
  __export(lock_exports, {
173
- acquireLock: () => acquireLock
173
+ acquireLock: () => acquireLock,
174
+ releaseAllLocks: () => releaseAllLocks,
175
+ releaseAllLocksSync: () => releaseAllLocksSync
174
176
  });
175
177
  function isEexist(err) {
176
178
  if (err instanceof Error && "code" in err)
@@ -206,6 +208,35 @@ async function removeStaleLockFile(fs, lockPath) {
206
208
  }
207
209
  return false;
208
210
  }
211
+ function releaseAllLocksSync() {
212
+ for (const lock of heldLocks) {
213
+ try {
214
+ if (lock.useFile && lock.fs.unlink) {
215
+ void lock.fs.unlink(lock.path).catch(() => {
216
+ });
217
+ } else {
218
+ void lock.fs.rmdir(lock.path).catch(() => {
219
+ });
220
+ }
221
+ } catch {
222
+ }
223
+ }
224
+ heldLocks.clear();
225
+ }
226
+ async function releaseAllLocks() {
227
+ const locks = [...heldLocks];
228
+ heldLocks.clear();
229
+ for (const lock of locks) {
230
+ try {
231
+ if (lock.useFile && lock.fs.unlink) {
232
+ await lock.fs.unlink(lock.path);
233
+ } else {
234
+ await lock.fs.rmdir(lock.path);
235
+ }
236
+ } catch {
237
+ }
238
+ }
239
+ }
209
240
  async function acquireLock(fs, configPath) {
210
241
  const useFile = typeof fs.createExclusive === "function";
211
242
  const lockPath = `${configPath}.lock`;
@@ -238,10 +269,13 @@ async function acquireLock(fs, configPath) {
238
269
  }
239
270
  await new Promise((r) => setTimeout(r, LOCK_POLL_MS));
240
271
  }
272
+ const entry = { path: lockPath, useFile, fs };
273
+ heldLocks.add(entry);
241
274
  let released = false;
242
275
  return async () => {
243
276
  if (released) return;
244
277
  released = true;
278
+ heldLocks.delete(entry);
245
279
  try {
246
280
  if (useFile && fs.unlink) {
247
281
  await fs.unlink(lockPath);
@@ -252,13 +286,14 @@ async function acquireLock(fs, configPath) {
252
286
  }
253
287
  };
254
288
  }
255
- var LOCK_STALE_MS, LOCK_POLL_MS, LOCK_MAX_WAIT_MS;
289
+ var LOCK_STALE_MS, LOCK_POLL_MS, LOCK_MAX_WAIT_MS, heldLocks;
256
290
  var init_lock = __esm({
257
291
  "src/config/lock.ts"() {
258
292
  "use strict";
259
293
  LOCK_STALE_MS = 1e4;
260
294
  LOCK_POLL_MS = 50;
261
295
  LOCK_MAX_WAIT_MS = 5e3;
296
+ heldLocks = /* @__PURE__ */ new Set();
262
297
  }
263
298
  });
264
299
 
@@ -6379,7 +6414,13 @@ var CLIENT_NAME = "mcpcat";
6379
6414
  var CALLBACK_HOST = "127.0.0.1";
6380
6415
  var CALLBACK_PATH = "/callback";
6381
6416
  var REQUEST_TIMEOUT_MS = 15e3;
6382
- var REFRESH_SKEW_MS = 3e4;
6417
+ var MAX_REFRESH_SKEW_MS = 3e4;
6418
+ function computeSkew(state) {
6419
+ const expiresIn = state?.tokens?.expires_in;
6420
+ if (typeof expiresIn !== "number" || expiresIn <= 0) return MAX_REFRESH_SKEW_MS;
6421
+ const ttlMs = expiresIn * 1e3;
6422
+ return Math.min(MAX_REFRESH_SKEW_MS, Math.floor(ttlMs / 2));
6423
+ }
6383
6424
  var FALLBACK_REDIRECT_URL = `http://${CALLBACK_HOST}${CALLBACK_PATH}`;
6384
6425
  function timedFetch(fetchImpl) {
6385
6426
  return (input, init) => {
@@ -6446,7 +6487,9 @@ function createMcpAuthProvider(options) {
6446
6487
  function createJerkAuthProvider(options) {
6447
6488
  const { name, serverUrl, source } = options;
6448
6489
  let currentToken;
6449
- const _fetched = false;
6490
+ function registerCredential(token) {
6491
+ if (token && options.onCredentialObtained) options.onCredentialObtained(token);
6492
+ }
6450
6493
  return {
6451
6494
  async token() {
6452
6495
  return currentToken;
@@ -6458,6 +6501,7 @@ function createJerkAuthProvider(options) {
6458
6501
  const result2 = await source.getToken(name, serverUrl, challenge.scope);
6459
6502
  if (result2) {
6460
6503
  currentToken = result2.accessToken;
6504
+ registerCredential(currentToken);
6461
6505
  return;
6462
6506
  }
6463
6507
  } catch (err) {
@@ -6471,6 +6515,7 @@ function createJerkAuthProvider(options) {
6471
6515
  const result = await source.getToken(name, serverUrl);
6472
6516
  if (result) {
6473
6517
  currentToken = result.accessToken;
6518
+ registerCredential(currentToken);
6474
6519
  return;
6475
6520
  }
6476
6521
  throw new McpOAuthAuthorizationRequiredError();
@@ -6481,6 +6526,9 @@ function createPiAuthProvider(options) {
6481
6526
  const { name, serverUrl, source, oauth, platform: platform2 } = options;
6482
6527
  const store = new SourceBackedStore(source, name, serverUrl, platform2);
6483
6528
  let refreshing;
6529
+ function registerCredential(token) {
6530
+ if (token && options.onCredentialObtained) options.onCredentialObtained(token);
6531
+ }
6484
6532
  const refresh = async (staleToken) => {
6485
6533
  refreshing ??= store.withRefreshLock(async () => {
6486
6534
  const state = await store.load();
@@ -6510,15 +6558,28 @@ function createPiAuthProvider(options) {
6510
6558
  });
6511
6559
  return refreshing;
6512
6560
  };
6561
+ let cachedToken;
6562
+ let tokenLoaded = false;
6513
6563
  return {
6514
6564
  async token() {
6515
6565
  await refreshing?.catch(() => void 0);
6566
+ if (tokenLoaded) return cachedToken;
6516
6567
  const state = await store.load();
6517
- const token = state?.tokens?.access_token;
6518
- const expired = state?.tokensExpireAt !== void 0 && state.tokensExpireAt - REFRESH_SKEW_MS <= Date.now();
6519
- if (!expired || !state?.tokens?.refresh_token) return token;
6520
- await refresh(token).catch(() => void 0);
6521
- return (await store.load())?.tokens?.access_token;
6568
+ cachedToken = state?.tokens?.access_token;
6569
+ registerCredential(cachedToken);
6570
+ if (state?.tokens?.refresh_token) registerCredential(state.tokens.refresh_token);
6571
+ const skew = computeSkew(state);
6572
+ const expired = state?.tokensExpireAt !== void 0 && state.tokensExpireAt - skew <= Date.now();
6573
+ if (expired && state?.tokens?.refresh_token) {
6574
+ await refresh(cachedToken).catch(() => void 0);
6575
+ const refreshedState = await store.load();
6576
+ cachedToken = refreshedState?.tokens?.access_token;
6577
+ registerCredential(cachedToken);
6578
+ if (refreshedState?.tokens?.refresh_token)
6579
+ registerCredential(refreshedState.tokens.refresh_token);
6580
+ }
6581
+ tokenLoaded = true;
6582
+ return cachedToken;
6522
6583
  },
6523
6584
  async onUnauthorized(context) {
6524
6585
  const challenge = parseWwwAuthenticate(context.response.headers.get("www-authenticate"));
@@ -6526,6 +6587,11 @@ function createPiAuthProvider(options) {
6526
6587
  throw new AuthStepUpError(challenge.scope, options.name);
6527
6588
  }
6528
6589
  await refresh(context.token);
6590
+ const state = await store.load();
6591
+ cachedToken = state?.tokens?.access_token;
6592
+ tokenLoaded = true;
6593
+ registerCredential(cachedToken);
6594
+ if (state?.tokens?.refresh_token) registerCredential(state.tokens.refresh_token);
6529
6595
  }
6530
6596
  };
6531
6597
  }
@@ -9593,6 +9659,9 @@ var MergedConfigSource = class _MergedConfigSource {
9593
9659
  }
9594
9660
  };
9595
9661
 
9662
+ // src/cli/main.ts
9663
+ init_lock();
9664
+
9596
9665
  // src/config/edit.ts
9597
9666
  init_lock();
9598
9667
  function isRecord2(value) {
@@ -14964,6 +15033,8 @@ async function dispatchMultiTarget(platform2, parsed, version) {
14964
15033
  await Promise.race([killAllStdio(), new Promise((r) => setTimeout(r, 3e3))]);
14965
15034
  } catch {
14966
15035
  }
15036
+ await releaseAllLocks().catch(() => {
15037
+ });
14967
15038
  platform2.exit(exitCode);
14968
15039
  }
14969
15040
  platform2.onSignal?.("SIGTERM", () => void killTreeAndExit(143));
@@ -15196,25 +15267,28 @@ function classifyError(err) {
15196
15267
  }
15197
15268
  return { code: EXIT_RPC_ERROR, kind: "rpc_error", msg };
15198
15269
  }
15199
- async function resolveAuthProvider(platform2, hasAuthHeader, url, target, config) {
15270
+ async function resolveAuthProvider(platform2, hasAuthHeader, url, target, config, onCredentialObtained) {
15200
15271
  if (hasAuthHeader || !url) return void 0;
15201
- const piSource = new PiFileTokenSource(platform2);
15272
+ const source = await createTokenSource(platform2);
15202
15273
  const entry = config.entry(target);
15203
15274
  const oauth = entry && "url" in entry.config ? entry.config.oauth : void 0;
15204
15275
  const name = entry ? target : `url:${new URL(url).origin}${new URL(url).pathname}`;
15205
15276
  const provider = createMcpAuthProvider({
15206
15277
  name,
15207
15278
  serverUrl: url,
15208
- source: piSource,
15279
+ source,
15209
15280
  oauth,
15210
- platform: platform2
15281
+ platform: platform2,
15282
+ onCredentialObtained
15211
15283
  });
15212
15284
  const credentialSecrets = [];
15213
- const state = await piSource.loadWithoutLock(name, url);
15214
- if (state?.tokens?.access_token) credentialSecrets.push(state.tokens.access_token);
15215
- if (state?.tokens?.refresh_token) credentialSecrets.push(state.tokens.refresh_token);
15216
- if (state?.clientInformation && "client_secret" in state.clientInformation && state.clientInformation.client_secret) {
15217
- credentialSecrets.push(state.clientInformation.client_secret);
15285
+ if (source instanceof PiFileTokenSource) {
15286
+ const state = await source.loadWithoutLock(name, url);
15287
+ if (state?.tokens?.access_token) credentialSecrets.push(state.tokens.access_token);
15288
+ if (state?.tokens?.refresh_token) credentialSecrets.push(state.tokens.refresh_token);
15289
+ if (state?.clientInformation && "client_secret" in state.clientInformation && state.clientInformation.client_secret) {
15290
+ credentialSecrets.push(state.clientInformation.client_secret);
15291
+ }
15218
15292
  }
15219
15293
  return { provider, credentialSecrets };
15220
15294
  }
@@ -15262,7 +15336,7 @@ async function handleInputRequired(platform2, conn, err, respondData, json) {
15262
15336
  `);
15263
15337
  return EXIT_INPUT_REQUIRED;
15264
15338
  }
15265
- const isTty = platform2.isatty(0) && platform2.isatty(2);
15339
+ const isTty = platform2.kind === "host" && platform2.isatty(0) && platform2.isatty(2);
15266
15340
  const elicitResult = await handleElicitation(platform2, inputReq, isTty, respondData);
15267
15341
  if ("exitCode" in elicitResult) {
15268
15342
  await platform2.write(2, `${err.requestJson}
@@ -15312,6 +15386,8 @@ async function runClientVerb(platform2, version, parsed) {
15312
15386
  await Promise.race([killAllStdio(), new Promise((r) => setTimeout(r, 3e3))]);
15313
15387
  } catch {
15314
15388
  }
15389
+ await releaseAllLocks().catch(() => {
15390
+ });
15315
15391
  platform2.exit(exitCode);
15316
15392
  }
15317
15393
  platform2.onSignal?.("SIGINT", () => {
@@ -15364,7 +15440,11 @@ async function runClientVerb(platform2, version, parsed) {
15364
15440
  hasAuthHeader,
15365
15441
  resolved.url,
15366
15442
  target,
15367
- config
15443
+ config,
15444
+ (secret) => {
15445
+ allSecrets.add(secret);
15446
+ verbose.secrets.add(secret);
15447
+ }
15368
15448
  );
15369
15449
  const authProvider = authResolved?.provider;
15370
15450
  if (authResolved?.credentialSecrets) {
@@ -15444,6 +15524,8 @@ async function closeAndKillStdio(conn) {
15444
15524
  await killAllStdio();
15445
15525
  } catch {
15446
15526
  }
15527
+ await releaseAllLocks().catch(() => {
15528
+ });
15447
15529
  }
15448
15530
  async function writeErr(p, json, kind, msg) {
15449
15531
  if (json) await renderErrorJson(p, kind, msg);
@@ -15759,7 +15841,7 @@ async function main(ctx) {
15759
15841
  packageDir: "/node_modules/@ai-ecoverse/mcpcat"
15760
15842
  });
15761
15843
  const args = ctx.argv.slice(1);
15762
- return run(platform2, "0.14.5", args);
15844
+ return run(platform2, "0.14.7", args);
15763
15845
  }
15764
15846
  export {
15765
15847
  main as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/mcpcat",
3
- "version": "0.14.5",
3
+ "version": "0.14.7",
4
4
  "description": "A curl for the Model Context Protocol",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -56,7 +56,7 @@
56
56
  "trust:dry": "npx fledgling sync --dry-run -y --skip-publish"
57
57
  },
58
58
  "devDependencies": {
59
- "@ai-ecoverse/slicc-kernel": "1.82.0",
59
+ "@ai-ecoverse/slicc-kernel": "1.83.0",
60
60
  "@ai-ecoverse/slicc-shared-web": "1.13.1",
61
61
  "@biomejs/biome": "2.5.15",
62
62
  "@earendil-works/pi-codemode": "1.2.0",