@introspection-ai/recipes 0.18.0 → 0.19.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.
Files changed (146) hide show
  1. package/dist/inspect.d.ts +1 -0
  2. package/dist/inspect.d.ts.map +1 -1
  3. package/dist/inspect.js +3 -0
  4. package/dist/inspect.js.map +1 -1
  5. package/dist/mcp-chunks/{auth-command-ZLGYIEUY.js → auth-command-3K7V3VCW.js} +31 -35
  6. package/dist/mcp-chunks/call-arguments-TX3F2TEE.js +15 -0
  7. package/dist/mcp-chunks/{call-command-LKTKSYTH.js → call-command-OFPHPFM5.js} +36 -34
  8. package/dist/mcp-chunks/chunk-2FSDGCHW.js +3299 -0
  9. package/dist/mcp-chunks/{chunk-BV56DXPW.js → chunk-2JHHONW4.js} +1 -1
  10. package/dist/mcp-chunks/chunk-2MEHGB7D.js +63 -0
  11. package/dist/mcp-chunks/chunk-3IZQW4H4.js +929 -0
  12. package/dist/mcp-chunks/{chunk-MZ2NARG7.js → chunk-54EWGONA.js} +5 -5
  13. package/dist/mcp-chunks/{chunk-LQQEYD76.js → chunk-55JIHDU3.js} +1 -1
  14. package/dist/mcp-chunks/chunk-64EP2BVO.js +39 -0
  15. package/dist/mcp-chunks/{chunk-LS7PMWSR.js → chunk-6D6KPSXN.js} +1 -1
  16. package/dist/mcp-chunks/{chunk-2XL7MG7R.js → chunk-7A63PAGP.js} +15 -9
  17. package/dist/mcp-chunks/chunk-7DH57OKF.js +28 -0
  18. package/dist/mcp-chunks/{chunk-BTLAWHTA.js → chunk-7RDLPFIO.js} +2 -2
  19. package/dist/mcp-chunks/chunk-C2PQFLWS.js +422 -0
  20. package/dist/mcp-chunks/chunk-CA5WFJZA.js +197 -0
  21. package/dist/mcp-chunks/{chunk-LNH5LAJD.js → chunk-CNDY7WB4.js} +2 -2
  22. package/dist/mcp-chunks/{chunk-UKYNQGNE.js → chunk-DEUU7WSN.js} +34 -8
  23. package/dist/mcp-chunks/{chunk-LKIBAYKU.js → chunk-DXPHJFSA.js} +25 -35
  24. package/dist/mcp-chunks/{chunk-J6LYIZXN.js → chunk-E6RVTWJY.js} +1 -1
  25. package/dist/mcp-chunks/{chunk-7FHEBT5G.js → chunk-E6T37ED6.js} +18 -13
  26. package/dist/mcp-chunks/chunk-ETWN4IIA.js +57 -0
  27. package/dist/mcp-chunks/{chunk-YVZKMV5H.js → chunk-F3LL4EBL.js} +1 -1
  28. package/dist/mcp-chunks/chunk-FWP4RACK.js +42 -0
  29. package/dist/mcp-chunks/{chunk-6W5QFASN.js → chunk-GFYTST6N.js} +1 -1
  30. package/dist/mcp-chunks/{chunk-TEUKFFQL.js → chunk-GIF7LOYU.js} +2 -2
  31. package/dist/mcp-chunks/{chunk-QXJUA3ND.js → chunk-GSZOK5TS.js} +828 -7
  32. package/dist/mcp-chunks/chunk-H7F5RZXS.js +26 -0
  33. package/dist/mcp-chunks/{chunk-ECIVB7P4.js → chunk-HAO6PL7Z.js} +2 -37
  34. package/dist/mcp-chunks/{chunk-WQJZMCJN.js → chunk-HTZ2URXW.js} +5 -3
  35. package/dist/mcp-chunks/{chunk-BWHIA4PC.js → chunk-JAKI24KR.js} +1 -1
  36. package/dist/mcp-chunks/{chunk-PWYFKGKG.js → chunk-KSGYBW3F.js} +180 -89
  37. package/dist/mcp-chunks/{chunk-SJCCBNZ4.js → chunk-KSMY7PXI.js} +1 -1
  38. package/dist/mcp-chunks/{chunk-2U4BSDC4.js → chunk-L4VKBFYI.js} +48 -29
  39. package/dist/mcp-chunks/{chunk-LEZSACDE.js → chunk-LICH4Q7A.js} +4 -4
  40. package/dist/mcp-chunks/{chunk-PIIYJR44.js → chunk-LNSUME65.js} +29 -33
  41. package/dist/mcp-chunks/{chunk-D3MRAZ6H.js → chunk-LWVFSQYX.js} +13974 -15562
  42. package/dist/mcp-chunks/{chunk-7KA2VJVZ.js → chunk-NCXEJ35U.js} +10 -5
  43. package/dist/mcp-chunks/{chunk-5QOSCSQB.js → chunk-NZOIX6XW.js} +2 -2
  44. package/dist/mcp-chunks/{chunk-XANPGTLI.js → chunk-P3RN22HQ.js} +11 -4
  45. package/dist/mcp-chunks/{chunk-IABRYROW.js → chunk-PKOJCYNA.js} +3 -3
  46. package/dist/mcp-chunks/{chunk-BNV3TPE4.js → chunk-QJACOI2W.js} +5 -13
  47. package/dist/mcp-chunks/{chunk-UNKB4SBV.js → chunk-RBVYCKCD.js} +2 -2
  48. package/dist/mcp-chunks/{chunk-DHBE7UBH.js → chunk-SB2UUURE.js} +12 -42
  49. package/dist/mcp-chunks/{chunk-4SQKWYFF.js → chunk-SFREPU3D.js} +1 -1
  50. package/dist/mcp-chunks/{chunk-BZIQOWE6.js → chunk-SRZZQ6TL.js} +35 -36
  51. package/dist/mcp-chunks/{chunk-M3TPODXI.js → chunk-UENXT3NE.js} +1 -1
  52. package/dist/mcp-chunks/chunk-UHOKCTZT.js +37 -0
  53. package/dist/mcp-chunks/{chunk-E22DYOW5.js → chunk-WWO5WGH5.js} +5 -5
  54. package/dist/mcp-chunks/{chunk-6XCZGU3G.js → chunk-WXBPMFSN.js} +149 -192
  55. package/dist/mcp-chunks/{chunk-XQK2JSW4.js → chunk-XRGLP3Z2.js} +14 -2
  56. package/dist/mcp-chunks/{chunk-L7NTQVYN.js → chunk-XTL4MHFH.js} +28 -10
  57. package/dist/mcp-chunks/{chunk-N46NEFAF.js → chunk-XUF6KARU.js} +1 -1
  58. package/dist/mcp-chunks/{chunk-WD6BOD24.js → chunk-YCYSQA5V.js} +23 -4
  59. package/dist/mcp-chunks/chunk-YPJ5EHXR.js +17394 -0
  60. package/dist/mcp-chunks/{chunk-NRAJX5E4.js → chunk-YSPT6F7K.js} +3 -3
  61. package/dist/mcp-chunks/{chunk-7UDVSOOF.js → chunk-YTKRAHO6.js} +54 -46
  62. package/dist/mcp-chunks/chunk-ZBFZ5UFE.js +67 -0
  63. package/dist/mcp-chunks/{cli-UV4QJZZM.js → cli-E4P6SZLQ.js} +89 -76
  64. package/dist/mcp-chunks/client-2EJC4PLL.js +18 -0
  65. package/dist/mcp-chunks/{config-command-NLAGKID5.js → config-command-MWF3RHPQ.js} +38 -59
  66. package/dist/mcp-chunks/daemon-command-6CJ26MKI.js +33 -0
  67. package/dist/mcp-chunks/{dist-LK3SHAMX.js → dist-ZIPUENTM.js} +527 -469
  68. package/dist/mcp-chunks/{emit-ts-command-VBXVXO6V.js → emit-ts-command-GOVJJ64A.js} +16 -13
  69. package/dist/mcp-chunks/{generate-cli-runner-6CAZZA3P.js → generate-cli-runner-L5OQIMEY.js} +242 -247
  70. package/dist/mcp-chunks/{inspect-cli-command-3ZORTOR7.js → inspect-cli-command-7OMMREPE.js} +10 -9
  71. package/dist/mcp-chunks/{launch-YKRXHXJI.js → launch-BWXPLPB7.js} +1 -1
  72. package/dist/mcp-chunks/{lifecycle-XVKRHPH3.js → lifecycle-B5UC65PT.js} +1 -1
  73. package/dist/mcp-chunks/{list-command-2MEGGNFQ.js → list-command-ZO4HVFQK.js} +74 -43
  74. package/dist/mcp-chunks/{output-utils-NKESLAJ6.js → output-utils-M3TJ2N4M.js} +3 -3
  75. package/dist/mcp-chunks/{prompt-B1Yc1NPt-VGOTWJMN.js → prompt-CH6TK0bC-C7OTKGRD.js} +1 -3
  76. package/dist/mcp-chunks/{record-command-YXHTTTT5.js → record-command-VD3HUQIC.js} +5 -4
  77. package/dist/mcp-chunks/replay-command-AX6IN7YD.js +42 -0
  78. package/dist/mcp-chunks/{resource-command-OO4NYF5C.js → resource-command-JEZ2DW2G.js} +10 -10
  79. package/dist/mcp-chunks/{result-utils-MOHHLNM7.js → result-utils-3YHYGS45.js} +4 -4
  80. package/dist/mcp-chunks/runtime-HSYVOME7.js +37 -0
  81. package/dist/mcp-chunks/{runtime-wrapper-RPWDIDBF.js → runtime-wrapper-UREU7GC3.js} +7 -3
  82. package/dist/mcp-chunks/serve-command-M47YZ6JN.js +16018 -0
  83. package/dist/mcp-chunks/{timeouts-W2XWCCXR.js → timeouts-THZRYP4B.js} +3 -1
  84. package/dist/mcp-chunks/{vault-command-PIYIUEZL.js → vault-command-53P7MLCB.js} +7 -6
  85. package/dist/mcp-chunks/webapi-PHEQZQKH.js +3316 -0
  86. package/dist/mcp-client.js +11 -1
  87. package/dist/mcp-client.js.map +1 -1
  88. package/dist/mcp-daemon-client.d.ts.map +1 -1
  89. package/dist/mcp-daemon-client.js +3 -0
  90. package/dist/mcp-daemon-client.js.map +1 -1
  91. package/dist/mcp-daemon-protocol.d.ts +6 -0
  92. package/dist/mcp-daemon-protocol.d.ts.map +1 -1
  93. package/dist/mcp-daemon-protocol.js.map +1 -1
  94. package/dist/mcp-daemon.js +43 -22
  95. package/dist/mcp-daemon.js.map +1 -1
  96. package/dist/mcp-run-worker.js +29 -22
  97. package/dist/mcp-trace-context.d.ts +6 -0
  98. package/dist/mcp-trace-context.d.ts.map +1 -0
  99. package/dist/mcp-trace-context.js +31 -0
  100. package/dist/mcp-trace-context.js.map +1 -0
  101. package/dist/model-binding.d.ts.map +1 -1
  102. package/dist/model-binding.js +8 -4
  103. package/dist/model-binding.js.map +1 -1
  104. package/dist/pi-extension.d.ts.map +1 -1
  105. package/dist/pi-extension.js +12 -0
  106. package/dist/pi-extension.js.map +1 -1
  107. package/dist/recipe/resolve.d.ts +2 -0
  108. package/dist/recipe/resolve.d.ts.map +1 -1
  109. package/dist/recipe/resolve.js +2 -1
  110. package/dist/recipe/resolve.js.map +1 -1
  111. package/dist/recipe-agent.d.ts +5 -2
  112. package/dist/recipe-agent.d.ts.map +1 -1
  113. package/dist/recipe-agent.js +20 -4
  114. package/dist/recipe-agent.js.map +1 -1
  115. package/dist/recipe-model.d.ts +7 -1
  116. package/dist/recipe-model.d.ts.map +1 -1
  117. package/dist/recipe-model.js +89 -20
  118. package/dist/recipe-model.js.map +1 -1
  119. package/dist/recipe-session.d.ts +14 -0
  120. package/dist/recipe-session.d.ts.map +1 -0
  121. package/dist/recipe-session.js +181 -0
  122. package/dist/recipe-session.js.map +1 -0
  123. package/dist/session.d.ts.map +1 -1
  124. package/dist/session.js +23 -1
  125. package/dist/session.js.map +1 -1
  126. package/docs/agent-composition.md +46 -22
  127. package/docs/pi-extension.md +9 -3
  128. package/docs/recipe-format.md +41 -5
  129. package/package.json +7 -7
  130. package/vendor/introspection-recipe-check/darwin-arm64/introspection-recipe-check +0 -0
  131. package/vendor/introspection-recipe-check/darwin-x64/introspection-recipe-check +0 -0
  132. package/vendor/introspection-recipe-check/linux-arm64/introspection-recipe-check +0 -0
  133. package/vendor/introspection-recipe-check/linux-x64/introspection-recipe-check +0 -0
  134. package/vendor/introspection-recipe-check/linux-x64-musl/introspection-recipe-check +0 -0
  135. package/vendor/introspection-recipe-check/win32-x64/introspection-recipe-check.exe +0 -0
  136. package/dist/mcp-chunks/call-arguments-LU3W6D3K.js +0 -13
  137. package/dist/mcp-chunks/chunk-HKRJ6O36.js +0 -1076
  138. package/dist/mcp-chunks/chunk-NNOEGEUZ.js +0 -17273
  139. package/dist/mcp-chunks/chunk-P3PSC54P.js +0 -869
  140. package/dist/mcp-chunks/chunk-TATVT5IT.js +0 -194
  141. package/dist/mcp-chunks/chunk-YHQUTU6L.js +0 -571
  142. package/dist/mcp-chunks/client-S7RQUG5U.js +0 -13
  143. package/dist/mcp-chunks/daemon-command-U242Z6VY.js +0 -26
  144. package/dist/mcp-chunks/replay-command-25HJ6AQU.js +0 -85
  145. package/dist/mcp-chunks/runtime-5WJ3G25Y.js +0 -33
  146. package/dist/mcp-chunks/serve-command-DHXJZMMN.js +0 -3302
@@ -1,571 +0,0 @@
1
- import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
- import {
3
- clearVaultEntry,
4
- getOAuthVaultPath,
5
- loadVaultEntry,
6
- saveVaultEntry
7
- } from "./chunk-TATVT5IT.js";
8
- import {
9
- checkResourceAllowed,
10
- discoverOAuthServerInfo,
11
- refreshAuthorization,
12
- resourceUrlFromServerUrl
13
- } from "./chunk-P3PSC54P.js";
14
- import {
15
- readJsonFile,
16
- writeJsonFile,
17
- writeTextFileAtomic
18
- } from "./chunk-2XL7MG7R.js";
19
- import {
20
- legacyMcporterDir
21
- } from "./chunk-ECIVB7P4.js";
22
-
23
- // node_modules/.pnpm/mcporter@0.12.3/node_modules/mcporter/dist/oauth-persistence.js
24
- import fs from "node:fs/promises";
25
- import { Buffer } from "node:buffer";
26
- import os from "node:os";
27
- import path from "node:path";
28
-
29
- // node_modules/.pnpm/mcporter@0.12.3/node_modules/mcporter/dist/oauth-client-info.js
30
- function buildStaticClientInformation(definition, options = {}) {
31
- if (!definition.oauthClientId) {
32
- return void 0;
33
- }
34
- const clientSecret = resolveOAuthClientSecret(definition);
35
- return {
36
- client_id: definition.oauthClientId,
37
- ...clientSecret ? { client_secret: clientSecret } : {},
38
- ...options.redirectUrl ? { redirect_uris: [options.redirectUrl.toString()] } : {},
39
- grant_types: ["authorization_code", "refresh_token"],
40
- response_types: ["code"],
41
- ...definition.oauthTokenEndpointAuthMethod ? { token_endpoint_auth_method: definition.oauthTokenEndpointAuthMethod } : {}
42
- };
43
- }
44
- function resolveOAuthClientSecret(definition) {
45
- if (definition.oauthClientSecretEnv) {
46
- const value = process.env[definition.oauthClientSecretEnv];
47
- if (!value) {
48
- throw new Error(`Environment variable '${definition.oauthClientSecretEnv}' is required for OAuth client secret.`);
49
- }
50
- return value;
51
- }
52
- return definition.oauthClientSecret;
53
- }
54
-
55
- // node_modules/.pnpm/mcporter@0.12.3/node_modules/mcporter/dist/oauth-persistence.js
56
- var TOKEN_EXPIRY_SKEW_SECONDS = 60;
57
- function withStoredExpiry(tokens) {
58
- const stored = tokens;
59
- if (typeof stored.expires_at === "number" || typeof stored.expiresAt === "number") {
60
- return tokens;
61
- }
62
- if (typeof tokens.expires_in === "number" && Number.isFinite(tokens.expires_in)) {
63
- return {
64
- ...tokens,
65
- expires_at: Math.floor(Date.now() / 1e3) + tokens.expires_in
66
- };
67
- }
68
- return tokens;
69
- }
70
- function tokenExpirySeconds(tokens) {
71
- const stored = tokens;
72
- for (const candidate of [stored.expires_at, stored.expiresAt]) {
73
- if (typeof candidate === "number" && Number.isFinite(candidate)) {
74
- return candidate;
75
- }
76
- }
77
- return void 0;
78
- }
79
- function cachedTokensChanged(original, current) {
80
- if (!current || typeof current.access_token !== "string" || current.access_token.trim().length === 0) {
81
- return false;
82
- }
83
- if (typeof original.refresh_token === "string" && typeof current.refresh_token === "string") {
84
- return current.refresh_token !== original.refresh_token || current.access_token !== original.access_token;
85
- }
86
- return current.access_token !== original.access_token;
87
- }
88
- function shouldRefreshCachedToken(tokens, skewSeconds = TOKEN_EXPIRY_SKEW_SECONDS) {
89
- const expiresAt = tokenExpirySeconds(tokens);
90
- if (expiresAt !== void 0) {
91
- return expiresAt <= Math.floor(Date.now() / 1e3) + skewSeconds;
92
- }
93
- return typeof tokens.expires_in === "number" && typeof tokens.refresh_token === "string";
94
- }
95
- function resourceForRefresh(serverUrl, resourceMetadata) {
96
- if (!resourceMetadata) {
97
- return void 0;
98
- }
99
- const defaultResource = resourceUrlFromServerUrl(serverUrl);
100
- if (!checkResourceAllowed({ requestedResource: defaultResource, configuredResource: resourceMetadata.resource })) {
101
- throw new Error(`Protected resource ${resourceMetadata.resource} does not match expected ${defaultResource} (or origin)`);
102
- }
103
- return new URL(resourceMetadata.resource);
104
- }
105
- function unrecoverableOAuthRefreshCode(error) {
106
- const errorCode = oauthErrorCode(error);
107
- if (errorCode && ["invalid_client", "invalid_grant", "unauthorized_client"].includes(errorCode)) {
108
- return errorCode;
109
- }
110
- return void 0;
111
- }
112
- function oauthErrorCode(error) {
113
- if (!error || typeof error !== "object") {
114
- return void 0;
115
- }
116
- const { errorCode, name } = error;
117
- if (typeof errorCode === "string" && errorCode.length > 0) {
118
- return errorCode.toLowerCase();
119
- }
120
- if (typeof name === "string") {
121
- const normalized = name.toLowerCase();
122
- if (normalized === "invalidclienterror") {
123
- return "invalid_client";
124
- }
125
- if (normalized === "invalidgranterror") {
126
- return "invalid_grant";
127
- }
128
- if (normalized === "unauthorizedclienterror") {
129
- return "unauthorized_client";
130
- }
131
- }
132
- return void 0;
133
- }
134
- var DirectoryPersistence = class {
135
- root;
136
- logger;
137
- tokenPath;
138
- clientInfoPath;
139
- codeVerifierPath;
140
- statePath;
141
- constructor(root, logger) {
142
- this.root = root;
143
- this.logger = logger;
144
- this.tokenPath = path.join(root, "tokens.json");
145
- this.clientInfoPath = path.join(root, "client.json");
146
- this.codeVerifierPath = path.join(root, "code_verifier.txt");
147
- this.statePath = path.join(root, "state.txt");
148
- }
149
- describe() {
150
- return this.root;
151
- }
152
- async ensureDir() {
153
- await fs.mkdir(this.root, { recursive: true });
154
- }
155
- async readTokens() {
156
- return this.readJsonOrUndefined(this.tokenPath);
157
- }
158
- async saveTokens(tokens) {
159
- await this.ensureDir();
160
- await writeJsonFile(this.tokenPath, withStoredExpiry(tokens));
161
- this.logger?.debug?.(`Saved tokens to ${this.tokenPath}`);
162
- }
163
- async readClientInfo() {
164
- return this.readJsonOrUndefined(this.clientInfoPath);
165
- }
166
- async saveClientInfo(info) {
167
- await this.ensureDir();
168
- await writeJsonFile(this.clientInfoPath, info);
169
- }
170
- async readCodeVerifier() {
171
- try {
172
- return (await fs.readFile(this.codeVerifierPath, "utf8")).trim();
173
- } catch (error) {
174
- if (error.code === "ENOENT") {
175
- return void 0;
176
- }
177
- throw error;
178
- }
179
- }
180
- async saveCodeVerifier(value) {
181
- await this.ensureDir();
182
- await writeTextFileAtomic(this.codeVerifierPath, value);
183
- }
184
- async readState() {
185
- return readJsonFile(this.statePath);
186
- }
187
- // A present-but-corrupt credential cache (tokens/client) means "no usable
188
- // credentials": degrade to re-auth instead of crashing the connection,
189
- // mirroring VaultPersistence and the daemon/server-proxy readers. Genuine I/O
190
- // faults still propagate (readJsonFile re-throws everything except ENOENT).
191
- // OAuth state is intentionally excluded (see readState) so its CSRF check
192
- // still fails closed on a corrupt state file.
193
- async readJsonOrUndefined(filePath) {
194
- try {
195
- return await readJsonFile(filePath);
196
- } catch (error) {
197
- if (!(error instanceof SyntaxError)) {
198
- throw error;
199
- }
200
- this.logger?.debug?.(`Ignoring corrupt OAuth cache file ${filePath}: ${error.message}`);
201
- return void 0;
202
- }
203
- }
204
- async saveState(value) {
205
- await this.ensureDir();
206
- await writeJsonFile(this.statePath, value);
207
- }
208
- async clear(scope) {
209
- const files = [];
210
- if (scope === "all" || scope === "tokens") {
211
- files.push(this.tokenPath);
212
- }
213
- if (scope === "all" || scope === "client") {
214
- files.push(this.clientInfoPath);
215
- }
216
- if (scope === "all" || scope === "verifier") {
217
- files.push(this.codeVerifierPath);
218
- }
219
- if (scope === "all" || scope === "state") {
220
- files.push(this.statePath);
221
- }
222
- await Promise.all(files.map(async (file) => {
223
- try {
224
- await fs.unlink(file);
225
- } catch (error) {
226
- if (error.code !== "ENOENT") {
227
- throw error;
228
- }
229
- }
230
- }));
231
- }
232
- };
233
- var VaultPersistence = class {
234
- definition;
235
- constructor(definition) {
236
- this.definition = definition;
237
- }
238
- describe() {
239
- return `${getOAuthVaultPath()} (vault)`;
240
- }
241
- async readTokens() {
242
- return (await loadVaultEntry(this.definition))?.tokens;
243
- }
244
- async saveTokens(tokens) {
245
- await saveVaultEntry(this.definition, { tokens: withStoredExpiry(tokens) });
246
- }
247
- async readClientInfo() {
248
- return (await loadVaultEntry(this.definition))?.clientInfo;
249
- }
250
- async saveClientInfo(info) {
251
- await saveVaultEntry(this.definition, { clientInfo: info });
252
- }
253
- async readCodeVerifier() {
254
- return (await loadVaultEntry(this.definition))?.codeVerifier;
255
- }
256
- async saveCodeVerifier(value) {
257
- await saveVaultEntry(this.definition, { codeVerifier: value });
258
- }
259
- async readState() {
260
- return (await loadVaultEntry(this.definition))?.state;
261
- }
262
- async saveState(value) {
263
- await saveVaultEntry(this.definition, { state: value });
264
- }
265
- async clear(scope) {
266
- await clearVaultEntry(this.definition, scope);
267
- }
268
- };
269
- var CompositePersistence = class {
270
- stores;
271
- constructor(stores) {
272
- this.stores = stores;
273
- }
274
- describe() {
275
- return this.stores.map((store) => store.describe()).join(" + ");
276
- }
277
- async readTokens() {
278
- for (const store of this.stores) {
279
- const result = await store.readTokens();
280
- if (result) {
281
- return result;
282
- }
283
- }
284
- return void 0;
285
- }
286
- async saveTokens(tokens) {
287
- await Promise.all(this.stores.map((store) => store.saveTokens(tokens)));
288
- }
289
- async readClientInfo() {
290
- for (const store of this.stores) {
291
- const result = await store.readClientInfo();
292
- if (result) {
293
- return result;
294
- }
295
- }
296
- return void 0;
297
- }
298
- async saveClientInfo(info) {
299
- await Promise.all(this.stores.map((store) => store.saveClientInfo(info)));
300
- }
301
- async readCodeVerifier() {
302
- for (const store of this.stores) {
303
- const result = await store.readCodeVerifier();
304
- if (result) {
305
- return result;
306
- }
307
- }
308
- return void 0;
309
- }
310
- async saveCodeVerifier(value) {
311
- await Promise.all(this.stores.map((store) => store.saveCodeVerifier(value)));
312
- }
313
- async readState() {
314
- for (const store of this.stores) {
315
- const result = await store.readState();
316
- if (result) {
317
- return result;
318
- }
319
- }
320
- return void 0;
321
- }
322
- async saveState(value) {
323
- await Promise.all(this.stores.map((store) => store.saveState(value)));
324
- }
325
- async clear(scope) {
326
- await Promise.all(this.stores.map((store) => store.clear(scope)));
327
- }
328
- };
329
- async function buildOAuthPersistence(definition, logger) {
330
- const vault = new VaultPersistence(definition);
331
- const stores = [vault];
332
- if (definition.tokenCacheDir) {
333
- stores.unshift(new DirectoryPersistence(definition.tokenCacheDir, logger));
334
- }
335
- const legacyDir = path.join(legacyMcporterDir(), definition.name);
336
- if (!definition.tokenCacheDir && legacyDir) {
337
- const legacy = new DirectoryPersistence(legacyDir, logger);
338
- const legacyTokens = await legacy.readTokens();
339
- const legacyClient = await legacy.readClientInfo();
340
- const legacyVerifier = await legacy.readCodeVerifier();
341
- const legacyState = await legacy.readState();
342
- if (legacyTokens || legacyClient || legacyVerifier || legacyState) {
343
- if (legacyTokens) {
344
- await vault.saveTokens(legacyTokens);
345
- }
346
- if (legacyClient) {
347
- await vault.saveClientInfo(legacyClient);
348
- }
349
- if (legacyVerifier) {
350
- await vault.saveCodeVerifier(legacyVerifier);
351
- }
352
- if (legacyState) {
353
- await vault.saveState(legacyState);
354
- }
355
- logger?.info?.(`Migrated legacy OAuth cache for '${definition.name}' into vault.`);
356
- }
357
- }
358
- return stores.length === 1 ? vault : new CompositePersistence(stores);
359
- }
360
- async function clearOAuthCaches(definition, logger, scope = "all") {
361
- const persistence = await buildOAuthPersistence(definition, logger);
362
- await persistence.clear(scope);
363
- const legacyDir = path.join(legacyMcporterDir(), definition.name);
364
- if (legacyDir && (!definition.tokenCacheDir || legacyDir !== definition.tokenCacheDir)) {
365
- const legacy = new DirectoryPersistence(legacyDir, logger);
366
- await legacy.clear(scope);
367
- }
368
- if (definition.tokenCacheDir && scope === "all") {
369
- await fs.rm(definition.tokenCacheDir, { recursive: true, force: true });
370
- }
371
- const legacyFiles = [];
372
- if (definition.name.toLowerCase() === "gmail") {
373
- legacyFiles.push(path.join(os.homedir(), ".gmail-mcp", "credentials.json"));
374
- }
375
- await Promise.all(legacyFiles.map(async (file) => {
376
- try {
377
- await fs.unlink(file);
378
- logger?.info?.(`Cleared legacy OAuth cache file ${file}`);
379
- } catch (error) {
380
- if (error.code !== "ENOENT") {
381
- throw error;
382
- }
383
- }
384
- }));
385
- }
386
- async function readCachedAccessToken(definition, logger) {
387
- const persistence = await buildOAuthPersistence(definition, logger);
388
- const tokens = await persistence.readTokens();
389
- if (!tokens || typeof tokens.access_token !== "string" || tokens.access_token.trim().length === 0) {
390
- return void 0;
391
- }
392
- if (definition.auth === "refreshable_bearer") {
393
- return await readExplicitRefreshableBearerToken(definition, persistence, tokens, logger);
394
- }
395
- if (!shouldRefreshCachedToken(tokens)) {
396
- return tokens.access_token;
397
- }
398
- if (typeof tokens.refresh_token !== "string" || tokens.refresh_token.trim().length === 0) {
399
- return tokens.access_token;
400
- }
401
- try {
402
- const clientInformation = buildStaticClientInformation(definition) ?? await persistence.readClientInfo();
403
- if (!clientInformation) {
404
- logger?.debug?.(`Cached OAuth token for '${definition.name}' is expired, but no client information is available.`);
405
- return tokens.access_token;
406
- }
407
- if (definition.command.kind !== "http") {
408
- return tokens.access_token;
409
- }
410
- const serverInfo = await discoverOAuthServerInfo(definition.command.url);
411
- const resource = resourceForRefresh(definition.command.url, serverInfo.resourceMetadata);
412
- const refreshed = await refreshAuthorization(serverInfo.authorizationServerUrl, {
413
- metadata: serverInfo.authorizationServerMetadata,
414
- clientInformation,
415
- refreshToken: tokens.refresh_token,
416
- ...resource ? { resource } : {}
417
- });
418
- await persistence.saveTokens(refreshed);
419
- logger?.debug?.(`Refreshed cached OAuth access token for '${definition.name}' (non-interactive).`);
420
- return refreshed.access_token;
421
- } catch (error) {
422
- logger?.debug?.(`Failed to refresh cached OAuth token for '${definition.name}' non-interactively: ${error instanceof Error ? error.message : String(error)}`);
423
- const unrecoverableCode = unrecoverableOAuthRefreshCode(error);
424
- if (unrecoverableCode) {
425
- const latestTokens = await persistence.readTokens();
426
- if (cachedTokensChanged(tokens, latestTokens)) {
427
- logger?.debug?.(`Kept cached OAuth token for '${definition.name}' because another refresh updated it first.`);
428
- return latestTokens?.access_token;
429
- }
430
- const scope = unrecoverableCode === "invalid_grant" ? "tokens" : "all";
431
- await clearOAuthCaches(definition, logger, scope);
432
- logger?.debug?.(`Cleared cached OAuth ${scope === "all" ? "credentials" : "token"} for '${definition.name}' after unrecoverable refresh failure.`);
433
- return void 0;
434
- }
435
- return tokens.access_token;
436
- }
437
- }
438
- async function readExplicitRefreshableBearerToken(definition, persistence, tokens, logger) {
439
- const refresh = definition.refresh;
440
- const skewSeconds = refresh?.refreshSkewSeconds ?? TOKEN_EXPIRY_SKEW_SECONDS;
441
- if (!shouldRefreshCachedToken(tokens, skewSeconds)) {
442
- return tokens.access_token;
443
- }
444
- if (!refresh) {
445
- throw new Error(`Cached bearer token for '${definition.name}' is expired, but refresh is not configured.`);
446
- }
447
- if (typeof tokens.refresh_token !== "string" || tokens.refresh_token.trim().length === 0) {
448
- throw new Error(`Cached bearer token for '${definition.name}' is expired, but no refresh_token is available.`);
449
- }
450
- try {
451
- const refreshed = await refreshBearerToken(definition, tokens.refresh_token);
452
- await persistence.saveTokens(refreshed);
453
- logger?.debug?.(`Refreshed bearer access token for '${definition.name}' (non-interactive).`);
454
- return refreshed.access_token;
455
- } catch (error) {
456
- logger?.debug?.(`Failed to refresh bearer token for '${definition.name}' non-interactively: ${error instanceof Error ? error.message : String(error)}`);
457
- throw new Error(`Failed to refresh cached bearer token for '${definition.name}': ${error instanceof Error ? error.message : String(error)}`, { cause: error });
458
- }
459
- }
460
- async function refreshBearerToken(definition, refreshToken) {
461
- const refresh = definition.refresh;
462
- if (!refresh) {
463
- throw new Error("Missing refresh configuration.");
464
- }
465
- const clientId = readEnvOrConfig(refresh.clientIdEnv, definition.oauthClientId);
466
- const method = refresh.clientAuthMethod ?? definition.oauthTokenEndpointAuthMethod ?? "client_secret_basic";
467
- const clientSecret = method === "none" ? void 0 : readClientSecret(definition, refresh.clientSecretEnv);
468
- const body = new URLSearchParams({
469
- grant_type: "refresh_token",
470
- refresh_token: refreshToken
471
- });
472
- const headers = {
473
- accept: "application/json",
474
- "content-type": "application/x-www-form-urlencoded"
475
- };
476
- if (method === "client_secret_post") {
477
- if (clientId) {
478
- body.set("client_id", clientId);
479
- }
480
- if (clientSecret) {
481
- body.set("client_secret", clientSecret);
482
- }
483
- } else if (method === "none") {
484
- if (clientId) {
485
- body.set("client_id", clientId);
486
- }
487
- } else {
488
- if (!clientId || !clientSecret) {
489
- throw new Error(`Refresh client credentials are required for '${method}'.`);
490
- }
491
- headers.authorization = `Basic ${Buffer.from(`${formEncodeCredential(clientId)}:${formEncodeCredential(clientSecret)}`).toString("base64")}`;
492
- }
493
- const response = await fetch(refresh.tokenEndpoint, {
494
- method: "POST",
495
- headers,
496
- body
497
- });
498
- if (!response.ok) {
499
- throw new Error(`Token endpoint returned HTTP ${response.status}.`);
500
- }
501
- const payload = normalizeBearerTokenResponse(await response.json());
502
- return {
503
- ...payload,
504
- ...payload.refresh_token ? {} : { refresh_token: refreshToken }
505
- };
506
- }
507
- function normalizeBearerTokenResponse(value) {
508
- if (!value || typeof value !== "object") {
509
- throw new Error("Token endpoint did not return a JSON object.");
510
- }
511
- const payload = value;
512
- if (typeof payload.access_token !== "string" || payload.access_token.trim().length === 0) {
513
- throw new Error("Token endpoint did not return an access_token.");
514
- }
515
- return {
516
- access_token: payload.access_token,
517
- token_type: typeof payload.token_type === "string" && payload.token_type ? payload.token_type : "Bearer",
518
- ...typeof payload.id_token === "string" ? { id_token: payload.id_token } : {},
519
- ...typeof payload.scope === "string" ? { scope: payload.scope } : {},
520
- ...typeof payload.refresh_token === "string" && payload.refresh_token ? { refresh_token: payload.refresh_token } : {},
521
- ...coerceExpiresIn(payload.expires_in)
522
- };
523
- }
524
- function coerceExpiresIn(value) {
525
- if (typeof value === "number" && Number.isFinite(value)) {
526
- return { expires_in: value };
527
- }
528
- if (typeof value === "string" && value.trim().length > 0) {
529
- const parsed = Number(value);
530
- if (Number.isFinite(parsed)) {
531
- return { expires_in: parsed };
532
- }
533
- }
534
- return {};
535
- }
536
- function readEnvOrConfig(envName, fallback) {
537
- if (!envName) {
538
- return fallback;
539
- }
540
- const value = process.env[envName];
541
- if (value === void 0 || value.trim().length === 0) {
542
- throw new Error(`Environment variable '${envName}' is required for bearer token refresh.`);
543
- }
544
- return value;
545
- }
546
- function formEncodeCredential(value) {
547
- return new URLSearchParams([["", value]]).toString().slice(1);
548
- }
549
- function readClientSecret(definition, refreshClientSecretEnv) {
550
- if (refreshClientSecretEnv) {
551
- return readEnvOrConfig(refreshClientSecretEnv, void 0);
552
- }
553
- return resolveOAuthClientSecret2(definition);
554
- }
555
- function resolveOAuthClientSecret2(definition) {
556
- if (definition.oauthClientSecretEnv) {
557
- const value = process.env[definition.oauthClientSecretEnv];
558
- if (value === void 0 || value.trim().length === 0) {
559
- throw new Error(`Environment variable '${definition.oauthClientSecretEnv}' is required for OAuth client secret.`);
560
- }
561
- return value;
562
- }
563
- return definition.oauthClientSecret;
564
- }
565
-
566
- export {
567
- buildStaticClientInformation,
568
- buildOAuthPersistence,
569
- clearOAuthCaches,
570
- readCachedAccessToken
571
- };
@@ -1,13 +0,0 @@
1
- import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
- import {
3
- DaemonClient,
4
- resolveDaemonPaths
5
- } from "./chunk-PWYFKGKG.js";
6
- import "./chunk-2XL7MG7R.js";
7
- import "./chunk-WQJZMCJN.js";
8
- import "./chunk-ECIVB7P4.js";
9
- import "./chunk-LRKZP7DJ.js";
10
- export {
11
- DaemonClient,
12
- resolveDaemonPaths
13
- };
@@ -1,26 +0,0 @@
1
- import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
- import {
3
- handleDaemonCli
4
- } from "./chunk-6XCZGU3G.js";
5
- import "./chunk-NNOEGEUZ.js";
6
- import "./chunk-7FHEBT5G.js";
7
- import "./chunk-BZIQOWE6.js";
8
- import "./chunk-YHQUTU6L.js";
9
- import "./chunk-TATVT5IT.js";
10
- import "./chunk-HKRJ6O36.js";
11
- import "./chunk-4SQKWYFF.js";
12
- import "./chunk-6W5QFASN.js";
13
- import "./chunk-2U4BSDC4.js";
14
- import "./chunk-UKYNQGNE.js";
15
- import "./chunk-P3PSC54P.js";
16
- import "./chunk-NRAJX5E4.js";
17
- import "./chunk-PWYFKGKG.js";
18
- import "./chunk-2XL7MG7R.js";
19
- import "./chunk-WQJZMCJN.js";
20
- import "./chunk-ECIVB7P4.js";
21
- import "./chunk-LS7PMWSR.js";
22
- import "./chunk-D3MRAZ6H.js";
23
- import "./chunk-LRKZP7DJ.js";
24
- export {
25
- handleDaemonCli
26
- };
@@ -1,85 +0,0 @@
1
- import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
- import {
3
- parseReplayArgs
4
- } from "./chunk-7UDVSOOF.js";
5
- import {
6
- buildReplayCommandEnv
7
- } from "./chunk-J6LYIZXN.js";
8
- import {
9
- PRIVATE_RECORDING_FILE_MODE,
10
- ensurePrivateRecordingDir,
11
- resolveRecordingConfigPath,
12
- resolveRecordingPath
13
- } from "./chunk-7FHEBT5G.js";
14
- import "./chunk-ECIVB7P4.js";
15
- import "./chunk-LRKZP7DJ.js";
16
-
17
- // node_modules/.pnpm/mcporter@0.12.3/node_modules/mcporter/dist/cli/replay-command.js
18
- import { spawn } from "node:child_process";
19
- import fs from "node:fs/promises";
20
- async function handleReplayCli(args) {
21
- const parsed = parseReplayArgs(args);
22
- const replayPath = resolveRecordingPath(parsed.sessionName);
23
- if (parsed.command.length > 0) {
24
- await runWithReplayEnv(parsed.command, buildReplayCommandEnv(parsed.sessionName, parsed.server));
25
- return;
26
- }
27
- const configPath = resolveRecordingConfigPath(parsed.sessionName);
28
- await ensurePrivateRecordingDir(configPath);
29
- await fs.writeFile(configPath, `${JSON.stringify({
30
- session: parsed.sessionName,
31
- server: parsed.server,
32
- mode: "replay",
33
- replayPath,
34
- env: {
35
- MCPORTER_REPLAY: parsed.sessionName,
36
- ...parsed.server ? { MCPORTER_REPLAY_SERVER: parsed.server } : {},
37
- MCPORTER_DISABLE_KEEPALIVE: "*"
38
- }
39
- }, null, 2)}
40
- `, {
41
- encoding: "utf8",
42
- mode: PRIVATE_RECORDING_FILE_MODE
43
- });
44
- await fs.chmod(configPath, PRIVATE_RECORDING_FILE_MODE);
45
- console.log(`Replay configuration written to ${configPath}`);
46
- const envInstructions = [
47
- `MCPORTER_REPLAY=${parsed.sessionName}`,
48
- ...parsed.server ? [`MCPORTER_REPLAY_SERVER=${parsed.server}`] : [],
49
- "MCPORTER_DISABLE_KEEPALIVE=*"
50
- ];
51
- console.log(`Set ${envInstructions.join(" and ")} before the next mcporter call to replay ${replayPath}.`);
52
- }
53
- function printReplayHelp() {
54
- console.log(`Usage: mcporter replay <session-name> [--server <name>] [-- <command-to-run>]
55
-
56
- Replay MCP JSON-RPC traffic from ~/.mcporter/recordings/<session-name>.ndjson.
57
-
58
- Flags:
59
- --server <name> Restrict replay to one configured server.`);
60
- }
61
- async function runWithReplayEnv(commandAndArgs, env) {
62
- const [command, ...args] = commandAndArgs;
63
- if (!command) {
64
- return;
65
- }
66
- await new Promise((resolve, reject) => {
67
- const child = spawn(command, args, {
68
- stdio: "inherit",
69
- env
70
- });
71
- child.once("error", reject);
72
- child.once("exit", (code, signal) => {
73
- if (signal) {
74
- reject(new Error(`Command '${command}' exited from signal ${signal}.`));
75
- return;
76
- }
77
- process.exitCode = code ?? 0;
78
- resolve();
79
- });
80
- });
81
- }
82
- export {
83
- handleReplayCli,
84
- printReplayHelp
85
- };