@skydiveai/pi-extensions 0.1.0-beta.1003 → 0.1.0-beta.1014

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.mjs +72 -1
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -695,6 +695,19 @@ const STDERR_BUFFER_BYTES = 4096;
695
695
  * indistinguishable from any other transport problem. Walk the cause
696
696
  * chain so the agent sees the real underlying error.
697
697
  */
698
+ /**
699
+ * True when an error from an http MCP transport (connect, listTools, or a tool
700
+ * call) is an authentication failure. With no authProvider configured the SDK
701
+ * surfaces a 401 as `StreamableHTTPError(401)`; older paths translate it to
702
+ * `UnauthorizedError`. A dead/expired OAuth token (the proxy can no longer
703
+ * mint one) shows up here on the NEXT request against a previously-connected
704
+ * client — not just at connect — so reconcile must re-classify such a failure
705
+ * as `pending_auth` instead of a generic `failed`, keeping the "waiting on
706
+ * auth" report consistent with `platform auth`.
707
+ */
708
+ function isUnauthorizedError(err) {
709
+ return err instanceof UnauthorizedError || err instanceof StreamableHTTPError && err.code === 401;
710
+ }
698
711
  function formatError(err) {
699
712
  if (!(err instanceof Error)) return String(err);
700
713
  const parts = [err.message];
@@ -716,7 +729,7 @@ async function connectHttp(_id, config, client) {
716
729
  stderr: null
717
730
  };
718
731
  } catch (err) {
719
- if (err instanceof UnauthorizedError || err instanceof StreamableHTTPError && err.code === 401) return {
732
+ if (isUnauthorizedError(err)) return {
720
733
  status: "pending_auth",
721
734
  client,
722
735
  stderr: "",
@@ -1193,6 +1206,64 @@ var McpExtension = class {
1193
1206
  try {
1194
1207
  mcpTools = (await connected.client.listTools()).tools;
1195
1208
  } catch (err) {
1209
+ if (isUnauthorizedError(err) && serverConfig.transport === "http") {
1210
+ await closeConnected(connected);
1211
+ const retry = await connectClient(id, serverConfig, { connectTimeoutMs });
1212
+ if (retry.status === "pending_auth") return {
1213
+ id,
1214
+ store: {
1215
+ client: retry.client,
1216
+ configKey,
1217
+ status: "pending_auth",
1218
+ stderrBuffer: null,
1219
+ cliHint: retry.cliHint
1220
+ },
1221
+ serverStatus: {
1222
+ status: "pending_auth",
1223
+ stderr: "",
1224
+ cliHint: retry.cliHint
1225
+ },
1226
+ change: null,
1227
+ error: null,
1228
+ tools: null
1229
+ };
1230
+ if (retry.status === "failed") return {
1231
+ id,
1232
+ store: null,
1233
+ serverStatus: {
1234
+ status: "failed",
1235
+ error: retry.error,
1236
+ stderr: retry.stderr
1237
+ },
1238
+ change: null,
1239
+ error: {
1240
+ serverId: id,
1241
+ message: retry.error
1242
+ },
1243
+ tools: null
1244
+ };
1245
+ if (retry.status === "connected") {
1246
+ connected = {
1247
+ client: retry.client,
1248
+ configKey,
1249
+ status: "connected",
1250
+ stderrBuffer: retry.stderr,
1251
+ cliHint: null
1252
+ };
1253
+ mcpTools = (await connected.client.listTools()).tools;
1254
+ return {
1255
+ id,
1256
+ store: connected,
1257
+ serverStatus: { status: "connected" },
1258
+ change: action === "reused" ? "refreshed" : action,
1259
+ error: null,
1260
+ tools: {
1261
+ client: connected.client,
1262
+ list: mcpTools
1263
+ }
1264
+ };
1265
+ }
1266
+ }
1196
1267
  const message = err instanceof Error ? err.message : String(err);
1197
1268
  const stderr = connected.stderrBuffer?.read() ?? "";
1198
1269
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skydiveai/pi-extensions",
3
- "version": "0.1.0-beta.1003",
3
+ "version": "0.1.0-beta.1014",
4
4
  "homepage": "https://skydive.com",
5
5
  "license": "MIT",
6
6
  "author": "Create, Inc.",