@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.
- package/dist/host/mcpcat.mjs +103 -21
- package/dist/kernel/mcpcat.mjs +103 -21
- package/package.json +2 -2
package/dist/host/mcpcat.mjs
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
6897
|
-
|
|
6898
|
-
if (
|
|
6899
|
-
|
|
6900
|
-
|
|
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
|
|
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
|
|
15658
|
+
source,
|
|
15588
15659
|
oauth,
|
|
15589
|
-
platform: platform2
|
|
15660
|
+
platform: platform2,
|
|
15661
|
+
onCredentialObtained
|
|
15590
15662
|
});
|
|
15591
15663
|
const credentialSecrets = [];
|
|
15592
|
-
|
|
15593
|
-
|
|
15594
|
-
|
|
15595
|
-
|
|
15596
|
-
|
|
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.
|
|
16180
|
+
var code = await run(platform, "0.14.7", args);
|
|
16099
16181
|
process.exit(code);
|
package/dist/kernel/mcpcat.mjs
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
6518
|
-
|
|
6519
|
-
if (
|
|
6520
|
-
|
|
6521
|
-
|
|
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
|
|
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
|
|
15279
|
+
source,
|
|
15209
15280
|
oauth,
|
|
15210
|
-
platform: platform2
|
|
15281
|
+
platform: platform2,
|
|
15282
|
+
onCredentialObtained
|
|
15211
15283
|
});
|
|
15212
15284
|
const credentialSecrets = [];
|
|
15213
|
-
|
|
15214
|
-
|
|
15215
|
-
|
|
15216
|
-
|
|
15217
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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",
|